Re: Kernel 2.6.9 Multiple Page Allocation Failures

Nathan Scott
2004-12-03T06:21:37Z

Hi there,

On Thu, Dec 02, 2004 at 02:56:10PM -0800, Andrew Morton wrote:
> Stefan Schmidt <zaphodb@zaphods.net> wrote:
> >
> > and ~80kpps in each direction at ~44k interrupts/s, so the problematic
> > combination seems to be many open files, high i/o transaction rate or
> > troughput and heavy networking load. (tso currently on)
> > Caching on ext2-fs in general seemed to generate less page allocation errors
> > than on xfs and none of the traces i looked over so far showed involvement
> > of the filesystem i.e. were all triggered by alloc_skb.
>
> hm, OK, interesting.
>
> It's quite possible that XFS is performing rather too many GFP_ATOMIC
> allocations and is depleting the page reserves. Although increasing
> /proc/sys/vm/min_free_kbytes should help there.
>
> Nathan, it would be a worthwhile exercise to consider replacing GFP_ATOMIC
> with (GFP_ATOMIC & ~ __GFP_HIGH) where appropriate.
> ...

(i.e. zero? so future-proofing for if GFP_ATOMIC != __GFP_HIGH?)

> If there are places in XFS where it only needs one of these two behaviours,
> it would be good to select just that one.

OK, I took a quick look through - there's two places where we use
GFP_ATOMIC at the moment. One is a log debug/tracing chunk of code,
wont be coming into play here, I'll go back and rework that later.
The second is in the metadata buffering code, and is in a spot where
we can cope with a failure (don't need to dip into emergency pools
at all) but looks like we're avoiding sleeping there.

Does this patch improve things for your workload, Stefan?

cheers.

--
Nathan

Index: xfs-linux-2.6/fs/xfs/linux-2.6/xfs_buf.c
===================================================================
--- xfs-linux-2.6.orig/fs/xfs/linux-2.6/xfs_buf.c
+++ xfs-linux-2.6/fs/xfs/linux-2.6/xfs_buf.c
@@ -183,7 +183,7 @@
{
a_list_t *aentry;

- aentry = kmalloc(sizeof(a_list_t), GFP_ATOMIC);
+ aentry = kmalloc(sizeof(a_list_t), (GFP_ATOMIC & ~__GFP_HIGH));
if (aentry) {
spin_lock(&as_lock);
aentry->next = as_free_head;