xfs
[Top] [All Lists]

Re: [REPOST] [PATCH] fs/xfs/linux-2.6/kmem.c

To: Miquel van Smoorenburg <miquels@xxxxxxxxxxx>
Subject: Re: [REPOST] [PATCH] fs/xfs/linux-2.6/kmem.c
From: Nathan Scott <nathans@xxxxxxx>
Date: Fri, 26 Nov 2004 15:11:32 +1100
Cc: linux-xfs@xxxxxxxxxxx
In-reply-to: <1101386106l.15668l.0l@traveler>
References: <20041115103130.GA7971@xxxxxxxxxx> <20041117232247.GA9834@frodo> <1101386106l.15668l.0l@traveler>
Sender: linux-xfs-bounce@xxxxxxxxxxx
User-agent: Mutt/1.5.3i
Hi Mike,

On Thu, Nov 25, 2004 at 12:35:06PM +0000, Miquel van Smoorenburg wrote:
> 
> OK, did that. This time I kept as much of the code intact as possible.

Thanks.

> Things I changed:
> 
> - in linux-2.6/kmem.c:
>  o add __GFP_NOWARN to gfp flags so that kmalloc/vmalloc don't
>    spew warnings when we're in a loop
>  o added call to blk_congestion_wait() at the end of the loop
>  o made error printk a bit clearer

Looks good.

> - in linux-2.6/xfs_buf.c
>  o add __GFP_NOWARN to gfp flags so that alloc_pages() doesn't
>    spew warnings when we're in a loop
>  o added call to blk_congestion_wait() at the end of the loop
>  o made error printk a bit clearer
>  o since there was already a 10 ms delay in there, if
>    blk_congestion_wait() waited for less than 10 ms make sure
>    we wait for the remaining amount of time (which is 20 ms now).

Looks good.

>  I'm not sure if we actually need the sleep-at-least-10-ms code,
>  but I'm not sure what it does and at least this way, actual
>  behaviour isn't changed much.

That was there to give the daemon a bit of time to wakeup and
start writeout on delwrite buffers (which will clean pages,
and help with subsequent page allocation attempts) -- it looks
safe to now drop that timeout piece altogether; we'll quickly
initiate I/O and then be held off inside blk_congestion_wait,
either right away or after the next failed find_or_create_page.

> Patch has been tested on a busy usenet newsserver.

I tweaked a couple of things, esp. keeping the uses of GFP flags
together in kmem.h and xfs_buf.c and dropped the timeout.  How
does the following patch fare for you?  (could you also send me
a Signed-off-by: line for when the final patch is merged in?)

thanks!

-- 
Nathan


Index: xfs-linux/linux-2.6/xfs_buf.c
===================================================================
--- xfs-linux.orig/linux-2.6/xfs_buf.c
+++ xfs-linux/linux-2.6/xfs_buf.c
@@ -53,13 +53,10 @@
 #include <linux/workqueue.h>
 #include <linux/suspend.h>
 #include <linux/percpu.h>
+#include <linux/blkdev.h>
 
 #include "xfs_linux.h"
 
-#ifndef GFP_READAHEAD
-#define GFP_READAHEAD  (__GFP_NOWARN|__GFP_NORETRY)
-#endif
-
 /*
  * File wide globals
  */
@@ -118,8 +115,8 @@
  */
 
 #define pb_to_gfp(flags) \
-       (((flags) & PBF_READ_AHEAD) ? GFP_READAHEAD : \
-        ((flags) & PBF_DONT_BLOCK) ? GFP_NOFS : GFP_KERNEL)
+       ((((flags) & PBF_READ_AHEAD) ? __GFP_NORETRY : \
+         ((flags) & PBF_DONT_BLOCK) ? GFP_NOFS : GFP_KERNEL) | __GFP_NOWARN)
 
 #define pb_to_km(flags) \
         (((flags) & PBF_DONT_BLOCK) ? KM_NOFS : KM_SLEEP)
@@ -388,13 +385,13 @@
                         */
                        if (!(++retries % 100))
                                printk(KERN_ERR
-                                       "possible deadlock in %s (mode:0x%x)\n",
+                                       "XFS: possible memory allocation "
+                                       "deadlock in %s (mode:0x%x)\n",
                                        __FUNCTION__, gfp_mask);
 
                        XFS_STATS_INC(pb_page_retries);
                        pagebuf_daemon_wakeup(0, gfp_mask);
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       schedule_timeout(10);
+                       blk_congestion_wait(WRITE, HZ/50);
                        goto retry;
                }
 
Index: xfs-linux/linux-2.6/kmem.c
===================================================================
--- xfs-linux.orig/linux-2.6/kmem.c
+++ xfs-linux/linux-2.6/kmem.c
@@ -35,6 +35,7 @@
 #include <linux/vmalloc.h>
 #include <linux/highmem.h>
 #include <linux/swap.h>
+#include <linux/blkdev.h>
 
 #include "time.h"
 #include "kmem.h"
@@ -46,7 +47,8 @@
 void *
 kmem_alloc(size_t size, int flags)
 {
-       int     retries = 0, lflags = kmem_flags_convert(flags);
+       int     retries = 0;
+       int     lflags = kmem_flags_convert(flags);
        void    *ptr;
 
        do {
@@ -57,8 +59,10 @@
                if (ptr || (flags & (KM_MAYFAIL|KM_NOSLEEP)))
                        return ptr;
                if (!(++retries % 100))
-                       printk(KERN_ERR "possible deadlock in %s (mode:0x%x)\n",
+                       printk(KERN_ERR "XFS: possible memory allocation "
+                                       "deadlock in %s (mode:0x%x)\n",
                                        __FUNCTION__, lflags);
+               blk_congestion_wait(WRITE, HZ/50);
        } while (1);
 }
 
@@ -102,7 +106,8 @@
 void *
 kmem_zone_alloc(kmem_zone_t *zone, int flags)
 {
-       int     retries = 0, lflags = kmem_flags_convert(flags);
+       int     retries = 0;
+       int     lflags = kmem_flags_convert(flags);
        void    *ptr;
 
        do {
@@ -110,8 +115,10 @@
                if (ptr || (flags & (KM_MAYFAIL|KM_NOSLEEP)))
                        return ptr;
                if (!(++retries % 100))
-                       printk(KERN_ERR "possible deadlock in %s (mode:0x%x)\n",
+                       printk(KERN_ERR "XFS: possible memory allocation "
+                                       "deadlock in %s (mode:0x%x)\n",
                                        __FUNCTION__, lflags);
+               blk_congestion_wait(WRITE, HZ/50);
        } while (1);
 }
 
Index: xfs-linux/linux-2.6/kmem.h
===================================================================
--- xfs-linux.orig/linux-2.6/kmem.h
+++ xfs-linux/linux-2.6/kmem.h
@@ -83,7 +83,7 @@
 
 static __inline unsigned int kmem_flags_convert(int flags)
 {
-       int lflags;
+       int     lflags = __GFP_NOWARN;  /* we'll report deadlocks, if needed */
 
 #ifdef DEBUG
        if (unlikely(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL))) {


<Prev in Thread] Current Thread [Next in Thread>