2.6.26-rc: x86: pci-dma.c: use __GFP_NO_OOM instead of __GFP_NORETRY
Subsystems (4)
PATCH 1/1 2.6.26-rc: x86: pci-dma.c: use __GFP_NO_OOM instead of __GFP_NORETRY
Please consider the below patch for 2.6.26 (can somebody from the x86 team pick this up please? Thank you)
[PATCH] 2.6.26-rc: x86: pci-dma.c: use __GFP_NO_OOM instead of __GFP_NORETRY
arch/x86/kernel/pci-dma.c::dma_alloc_coherent() adds __GFP_NORETRY to the gfp flags before calling alloc_pages() to prevent the oom killer from running.
This has the expected side effect that that alloc_pages() doesn't retry anymore. Not really a problem for dma_alloc_coherent(.. GFP_ATOMIC) which is the way most drivers use it (through pci_alloc_consistent()) but drivers that call dma_alloc_coherent(.. GFP_KERNEL) directly can get unexpected failures.
Until we have the mask allocator, use a new flag __GFP_NO_OOM instead of __GFP_NORETRY.
arch/x86/kernel/pci-dma.c +1 -1
@@ -398,7 +398,7 @@return NULL ;/* Don't invoke OOM killer */ - gfp |= __GFP_NORETRY; + gfp |= __GFP_NO_OOM;#ifdef CONFIG_X86_64 /* Why <=? Even when the mask is smaller than 4GB it is often
include/linux/gfp.h +1 -0
@@ -43,6 +43,7 @@#define __GFP_REPEAT ((__force gfp_t)0x400u)/* See above */ #define __GFP_NOFAIL ((__force gfp_t)0x800u)/* See above */ #define __GFP_NORETRY ((__force gfp_t)0x1000u)/* See above */ +#define __GFP_NO_OOM ((__force gfp_t)0x2000u)/* Don't invoke oomkiller */ #define __GFP_COMP ((__force gfp_t)0x4000u)/* Add compound page metadata */ #define __GFP_ZERO ((__force gfp_t)0x8000u)/* Return zeroed page on success */ #define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u)/* Don't use emergency reserves */
mm/page_alloc.c +2 -1
@@ -1583,7 +1583,8 @@ zonelist, high_zoneidx, alloc_flags);if (page) goto got_pg; - }else if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY)) { + }else if ((gfp_mask & __GFP_FS) && + !(gfp_mask & (__GFP_NORETRY|__GFP_NO_OOM))) {if (!try_set_zone_oom (zonelist, gfp_mask)) {schedule_timeout_uninterruptible (1 ); goto restart;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 2 lines · Miquel van Smoorenburg
Please consider the below patch for 2.6.26 (can somebody from the x86 team pick this up please? Thank you)
looks good to me in principle - but it should go via -mm as it touches mm/page_alloc.c. Andrew: this fix is for v2.6.26.
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andrew Morton
maintainerQuoted 10 lines · On Tue, 27 May 2008 01:49:47 +0200 Miquel van Smoorenburg <[email protected]>…
Please consider the below patch for 2.6.26 (can somebody from the x86 team pick this up please? Thank you)
[PATCH] 2.6.26-rc: x86:
pci-dma.c: use__GFP_NO_OOMinstead of__GFP_NORETRYarch/x86/kernel/pci-dma.c::dma_alloc_coherent() adds
__GFP_NORETRYto the gfp flags before callingalloc_pages()to prevent the oom killer from running.
Now, why does dma_alloc_coherent() do that?
If __GFP_FS is cleared (most cases) then we won't be calling out_of_memory() anyway.
If __GFP_FS _is_ set then setting __GFP_NORETRY will do much more than avoiding oom-killings. It will prevent the page allocator from retrying and will cause the problems which one assumes (without evidence :() you have observed.
So... why not just remove the setting of __GFP_NORETRY? Why is it wrong to oom-kill things in this case?
Quoted 9 lines
This has the expected side effect that that
alloc_pages()doesn't retry anymore. Not really a problem for dma_alloc_coherent(..GFP_ATOMIC) which is the way most drivers use it (throughpci_alloc_consistent()) but drivers that call dma_alloc_coherent(..GFP_KERNEL) directly can get unexpected failures.Until we have the mask allocator, use a new flag
__GFP_NO_OOMinstead of__GFP_NORETRY.
But this change increases the chances of a caller getting stuck in the page allocator for ever, unable to make progress?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 15 lines · Andrew Morton
Quoted 10 lines · On Tue, 27 May 2008 01:49:47 +0200 Miquel van Smoorenburg <[email protected]>…
Please consider the below patch for 2.6.26 (can somebody from the x86 team pick this up please? Thank you)
[PATCH] 2.6.26-rc: x86:
pci-dma.c: use__GFP_NO_OOMinstead of__GFP_NORETRYarch/x86/kernel/pci-dma.c::dma_alloc_coherent() adds
__GFP_NORETRYto the gfp flags before callingalloc_pages()to prevent the oom killer from running.Now, why does
dma_alloc_coherent()do that?
Quoted 7 lines
If
__GFP_FSis cleared (most cases) then we won't be callingout_of_memory()anyway.If
__GFP_FS_is_ set then setting__GFP_NORETRYwill do much more than avoiding oom-killings. It will prevent the page allocator from retrying and will cause the problems which one assumes (without evidence :() you have observed.
Ah right, this was discussed in a different thread on linux-kernel / linux-mm. Message id <[email protected]> or see
http://lkml.org/lkml/2008/5/21/131
Quoted 2 lines
So... why not just remove the setting of
__GFP_NORETRY? Why is it wrong to oom-kill things in this case?
This was the first thing I proposed, since it was already that way in pci-dma_32.c, the __GFP_NORETRY was only added in pci-dma_64.c . Hence I found out about this when moving boxes to a 64 bit kernel. But in 2.6.26, those two were merged.
Quoted 7 lines
Quoted 7 lines
This has the expected side effect that that
alloc_pages()doesn't retry anymore. Not really a problem for dma_alloc_coherent(..GFP_ATOMIC) which is the way most drivers use it (throughpci_alloc_consistent()) but drivers that call dma_alloc_coherent(..GFP_KERNEL) directly can get unexpected failures.
Quoted 6 lines
Quoted 3 lines
Until we have the mask allocator, use a new flag
__GFP_NO_OOMinstead of__GFP_NORETRY.But this change increases the chances of a caller getting stuck in the page allocator for ever, unable to make progress?
Another bandaid fix I proposed was this:
arch/x86/kernel/pci-dma.c +2 -1
@@ -398,7 +398,8 @@return NULL ;/* Don't invoke OOM killer */ - gfp |= __GFP_NORETRY; +if (!(gfp & __GFP_WAIT)) + gfp |= __GFP_NORETRY;#ifdef CONFIG_X86_64 /* Why <=? Even when the mask is smaller than 4GB it is often
This will at least make sure that when called with GFP_KERNEL, __GFP_NORETRY is not set, while it will be set with GFP_ATOMIC.
But I concluded from the earlier discussion that there was consensus about __GFP_NO_OOM , so I sent this patch. Now I'm most definitely not an expert, in fact pretty ignorant really, so if there are serious objections or a better solution, please drop this patch.
I do think the issue should still be fixed.
The minimum would be to surround the gfp |= __GFP_NORETRY with #ifdef CONFIG_X86_64 so that at least 32 bit doesn't regress in 2.6.26
However as dpt_i2o in 2.6.26 works on 64 bit systems now and it calls dma_alloc_coherent(.. GFP_KERNEL) I'm afraid it might cause instability with that driver on x86_64 (that's my main worry. tw_cli crashing is merely inconvenient).
Mike.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 2 lines
So... why not just remove the setting of
__GFP_NORETRY? Why is it wrong to oom-kill things in this case?
When the 16MB zone overflows (which can be common in some workloads) calling the OOM killer is pretty useless because it has barely any real user data [only exception would be the "only 16MB" case Alan mentioned]. Killing random processes in this case is bad.
I think for 16MB __GFP_NORETRY is ok because there should be nothing freeable in there so looping is useless. Only exception would be the "only 16MB total" case again but I'm not sure 2.6 supports that at all on x86.
On the other hand d_a_c() does more allocations than just 16MB, especially on 64bit and the other zones need different strategies.
Quoted 2 lines
But this change increases the chances of a caller getting stuck in the page allocator for ever, unable to make progress?
At least for much longer, yes I am somewhat worried about this too.
Sometimes a OOM regression test suite would be really nice.
-Andi
Quoted 8 lines · Andi Kleen
Quoted 2 lines
So... why not just remove the setting of
__GFP_NORETRY? Why is it wrong to oom-kill things in this case?When the 16MB zone overflows (which can be common in some workloads) calling the OOM killer is pretty useless because it has barely any real user data [only exception would be the "only 16MB" case Alan mentioned]. Killing random processes in this case is bad.
Quoted 7 lines
I think for 16MB
__GFP_NORETRYis ok because there should be nothing freeable in there so looping is useless. Only exception would be the "only 16MB total" case again but I'm not sure 2.6 supports that at all on x86.On the other hand
d_a_c()does more allocations than just 16MB, especially on 64bit and the other zones need different strategies.
Okay, so how about this then ?
arch/x86/kernel/pci-dma.c +3 -4
@@ -397,9 +397,6 @@if (dev->dma_mask ==NULL )return NULL ; -/* Don't invoke OOM killer */ - gfp |= __GFP_NORETRY; -#ifdef CONFIG_X86_64 /* Why <=? Even when the mask is smaller than 4GB it is often larger than 16MB and in this case we have a chance of
@@ -410,7 +407,9 @@#endif again: - page =dma_alloc_pages (dev, gfp,get_order (size)); +/* Don't invoke OOM killer or retry in lower 16MB DMA zone */ + page =dma_alloc_pages (dev, + (gfp &GFP_DMA ) ? gfp | __GFP_NORETRY : gfp,get_order (size));if (page ==NULL )return NULL ;
Mike.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andrew Morton
maintainerQuoted 28 lines · On Wed, 28 May 2008 10:31:25 +0200 Miquel van Smoorenburg <[email protected]>…
Quoted 5 lines
When the 16MB zone overflows (which can be common in some workloads) calling the OOM killer is pretty useless because it has barely any real user data [only exception would be the "only 16MB" case Alan mentioned]. Killing random processes in this case is bad.
Quoted 7 lines
I think for 16MB
__GFP_NORETRYis ok because there should be nothing freeable in there so looping is useless. Only exception would be the "only 16MB total" case again but I'm not sure 2.6 supports that at all on x86.On the other hand
d_a_c()does more allocations than just 16MB, especially on 64bit and the other zones need different strategies.Okay, so how about this then ?
arch/x86/kernel/pci-dma.c +0
-3@@ -397,9 +397,6 @@if (dev->dma_mask ==NULL )return NULL ; -/* Don't invoke OOM killer */ - gfp |= __GFP_NORETRY; -#ifdef CONFIG_X86_64 /* Why <=? Even when the mask is smaller than 4GB it is often larger than 16MB and in this case we have a chance of
arch/x86/kernel/pci-dma.c line 414
Quoted 9 lines
arch/x86/kernel/pci-dma.c +3
-1@@ -410,7 +407,9 @@#endif again: - page =dma_alloc_pages (dev, gfp,get_order (size)); +/* Don't invoke OOM killer or retry in lower 16MB DMA zone */ + page =dma_alloc_pages (dev, + (gfp &GFP_DMA ) ? gfp | __GFP_NORETRY : gfp,get_order (size));if (page ==NULL )return NULL ;
I guess that's more specifally solving that-which-we-wish-to-solve.
Formally we should be testing __GFP_DMA here, not GFP_DMA - just the zone selector field. They're presently equal, but someone could legitimately come along and do
#define GFP_DMA (__GFP_DMA|__GFP_HIGH)
or similar.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 8 lines
arch/x86/kernel/pci-dma.c line 414
Quoted 6 lines
arch/x86/kernel/pci-dma.c +3
-1- page =dma_alloc_pages (dev, gfp,get_order (size)); +/* Don't invoke OOM killer or retry in lower 16MB DMA zone */ + page =dma_alloc_pages (dev, + (gfp &GFP_DMA ) ? gfp | __GFP_NORETRY : gfp,get_order (size));if (page ==NULL )return NULL ;I guess that's more specifally solving that-which-we-wish-to-solve.
Then the allocator could still be stuck in ZONE_DMA32 on 64bit.
Also d_a_c() does one "speculative" allocation, as in an allocation where it knows the zone is too large for the mask but it tries anyways because it often works. In that case too much trying is also not good.
-Andi
Quoted 15 lines · Miquel van Smoorenburg
Okay, so how about this then ?
arch/x86/kernel/pci-dma.c +0
-3@@ -397,9 +397,6 @@if (dev->dma_mask ==NULL )return NULL ; -/* Don't invoke OOM killer */ - gfp |= __GFP_NORETRY; -#ifdef CONFIG_X86_64 /* Why <=? Even when the mask is smaller than 4GB it is often larger than 16MB and in this case we have a chance of
arch/x86/kernel/pci-dma.c line 414
Quoted 9 lines
arch/x86/kernel/pci-dma.c +3
-1@@ -410,7 +407,9 @@#endif again: - page =dma_alloc_pages (dev, gfp,get_order (size)); +/* Don't invoke OOM killer or retry in lower 16MB DMA zone */ + page =dma_alloc_pages (dev, + (gfp &GFP_DMA ) ? gfp | __GFP_NORETRY : gfp,get_order (size));if (page ==NULL )return NULL ;
applied to tip/pci-for-jesse for more testing. Thanks,
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 10 lines · Miquel van Smoorenburg
Quoted 6 lines · Ingo Molnar
Quoted 1 line · Miquel van Smoorenburg
Okay, so how about this then ?
applied to tip/pci-for-jesse for more testing. Thanks,
I've thought about it a bit more, and I think the actual patch that really does what everybody wants is this one instead:
applied a delta patch version of the one below to tip/pci-for-jesse. Thanks,
Ingo
Quoted 62 lines
[PATCH] x86:
pci-dma.c: don't always add__GFP_NORETRYto gfpCurrently
arch/x86/kernel/pci-dma.calways adds__GFP_NORETRYto the allocation flags, because it wants to be reasonably sure not to deadlock when callingalloc_pages().But really that should only be done in two cases:
- when allocating memory in the lower 16 MB DMA zone.
If there's no free memory there, waiting or OOM killing is of no use
- when optimistically trying an allocation in the DMA32 zone whendma_mask<DMA_32BIT_MASKhoping that the allocation happens to fall within the limits of thedma_maskAlso blindly adding
__GFP_NORETRYto the the gfp variable might not be a good idea since we then also use it when callingdma_ops->alloc_coherent(). Clearing it might also not be a good idea, dma_alloc_coherent()'s caller might have set it on purpose. The gfp variable should not be clobbered.Signed-off-by Miquel van Smoorenburg <[email protected]>arch/x86/kernel/pci-dma.c +10
-4@@ -378,6 +378,7 @@ dma_alloc_coherent(struct device *dev, sstruct page *page;unsigned long dma_mask =0 ;dma_addr_t bus; +int noretry =0 ;/* ignore region specifiers */ gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);@@ -397,20 +398,25 @@ dma_alloc_coherent(struct device *dev, sif (dev->dma_mask ==NULL )return NULL ; -/* Don't invoke OOM killer */ - gfp |= __GFP_NORETRY; +/* Don't invoke OOM killer or retry in lower 16MB DMA zone */ +if (gfp & __GFP_DMA) + noretry =1 ;#ifdef CONFIG_X86_64 /* Why <=? Even when the mask is smaller than 4GB it is often larger than 16MB and in this case we have a chance of finding fitting memory in the next higher zone first. If not retry with true GFP_DMA. -AK */ -if (dma_mask <=DMA_32BIT_MASK && !(gfp &GFP_DMA )) +if (dma_mask <=DMA_32BIT_MASK && !(gfp &GFP_DMA )) { gfp |=GFP_DMA32 ; +if (dma_mask <DMA_32BIT_MASK ) + noretry =1 ; + }#endif again: - page =dma_alloc_pages (dev, gfp,get_order (size)); + page =dma_alloc_pages (dev, + noretry ? gfp | __GFP_NORETRY : gfp,get_order (size));if (page ==NULL )return NULL ;
Quoted 11 lines · Ingo Molnar
Quoted 8 lines · Miquel van Smoorenburg
Quoted 4 lines · Ingo Molnar
Quoted 1 line · Miquel van Smoorenburg
Okay, so how about this then ?
applied to tip/pci-for-jesse for more testing. Thanks,
I've thought about it a bit more, and I think the actual patch that really does what everybody wants is this one instead:
applied a delta patch version of the one below to tip/pci-for-jesse.
Speaking of that branch, how do you want to handle it? Is it intended for my linux-next branch or are some of the fixes important to get upstream now? Which branch should I diff/log against to see the changes (last time I looked it appeared neither master nor tip were the correct ones...)
Thanks,
Jesse
Quoted 11 lines · Jesse Barnes
Quoted 10 lines · Ingo Molnar
Quoted 8 lines · Miquel van Smoorenburg
Quoted 4 lines · Ingo Molnar
Quoted 1 line · Miquel van Smoorenburg
Okay, so how about this then ?
applied to tip/pci-for-jesse for more testing. Thanks,
I've thought about it a bit more, and I think the actual patch that really does what everybody wants is this one instead:
Quoted 6 lines
Quoted 1 line
applied a delta patch version of the one below to tip/pci-for-jesse.
Speaking of that branch, how do you want to handle it? Is it intended for my linux-next branch or are some of the fixes important to get upstream now? Which branch should I diff/log against to see the changes (last time I looked it appeared neither master nor tip were the correct ones...)
My opinion is that this particular patch should go into 2.6.26.
Mike.
Quoted 11 lines · Jesse Barnes
Quoted 10 lines · Ingo Molnar
Quoted 8 lines · Miquel van Smoorenburg
Quoted 4 lines · Ingo Molnar
Quoted 1 line · Miquel van Smoorenburg
Okay, so how about this then ?
applied to tip/pci-for-jesse for more testing. Thanks,
I've thought about it a bit more, and I think the actual patch that really does what everybody wants is this one instead:
Quoted 7 lines
Quoted 1 line
applied a delta patch version of the one below to tip/pci-for-jesse.
Speaking of that branch, how do you want to handle it? Is it intended for my linux-next branch or are some of the fixes important to get upstream now? Which branch should I diff/log against to see the changes (last time I looked it appeared neither master nor tip were the correct ones...)
that branch is always based in -git so if stuff goes upstream patches disappear from it. git-log linus/master..tip/pci-for-jesse should tell the currently pending items. Right now it's just two lowprio items:
Yinghai Lu (2):
pci: debug extra pci resources range
pci: debug extra pci bus resources
Ingo
Quoted 7 lines · Ingo Molnar
that branch is always based in -git so if stuff goes upstream patches disappear from it. git-log linus/master..tip/pci-for-jesse should tell the currently pending items. Right now it's just two lowprio items:
Yinghai Lu (2):
pci: debug extra pci resources range
pci: debug extra pci bus resources
It looks like these add some new, unconditional debug output? I guess I shouldn't worry about printks so much at this point, given how much obsolete/uninteresting info gets dumped these days, but it would be nice if this were only dumped if some debug option were set. Given the variety of PCI stuff we might like to dump at various times, maybe it's time we added a few new pci=debug=foo options? Yinghai?
Thanks,
Jesse
Quoted 9 lines · Jesse Barnes
Quoted 7 lines · Ingo Molnar
that branch is always based in -git so if stuff goes upstream patches disappear from it. git-log linus/master..tip/pci-for-jesse should tell the currently pending items. Right now it's just two lowprio items:
Yinghai Lu (2):
pci: debug extra pci resources range
pci: debug extra pci bus resources
Quoted 7 lines
It looks like these add some new, unconditional debug output? I guess I shouldn't worry about printks so much at this point, given how much obsolete/uninteresting info gets dumped these days, but it would be nice if this were only dumped if some debug option were set. Given the variety of PCI stuff we might like to dump at various times, maybe it's time we added a few new pci=debug=foo options? Yinghai?
that is just limited printout. and it is informative.. that is BAR before kernel try to assign new value to it.
YH
Quoted 1 line · Yinghai Lu
On Tue, Jul 1, 2008 at 7:39 PM, Jesse Barnes <[email protected]>
Quoted 16 lines · wrote:
Quoted 9 lines · Ingo Molnar
Quoted 7 lines
that branch is always based in -git so if stuff goes upstream patches disappear from it. git-log linus/master..tip/pci-for-jesse should tell the currently pending items. Right now it's just two lowprio items:
Yinghai Lu (2):
pci: debug extra pci resources range
pci: debug extra pci bus resourcesQuoted 6 lines
It looks like these add some new, unconditional debug output? I guess I shouldn't worry about printks so much at this point, given how much obsolete/uninteresting info gets dumped these days, but it would be nice if this were only dumped if some debug option were set. Given the variety of PCI stuff we might like to dump at various times, maybe it's time we added a few new pci=debug=foo options? Yinghai?
Quoted 2 lines
that is just limited printout. and it is informative.. that is BAR before kernel try to assign new value to it.
Yeah, and it's in keeping with the early (pre-assignment) BAR dumping code you added elsewhere. I'm fine with it as-is, I'll revisit finer grained debug options in a future release and fix things up then as needed.
Thanks,
Jesse