* (Found?) Re: Hard Hang with __alloc_pages: 0-order allocation failed (gfp=0x20/1) - Not out of memory
@ 2004-05-26 1:22 Roger Larsson
2004-05-26 19:58 ` Roger Larsson
0 siblings, 1 reply; 4+ messages in thread
From: Roger Larsson @ 2004-05-26 1:22 UTC (permalink / raw)
To: linux-kernel
Hi,
Since I read linux-kernel via achieves, this might be found already - but
anyway... (CONFIG_SMP problem? Oh, noticed that this is 2.4.21...)
decode "(gfp=0x20/1)" and you find that
current->flags is PF_MEMALLOC
gfp is __GFP_HIGH (== GFP_ATOMIC)
and the backtrace says we are in_interrupt()
So I guess this is the key line...
if (current->flags & PF_MEMALLOC && !in_interrupt()) {
* Less than (.min >> 2) of memory left.
* In interrupt
=> Not allowed to allocate anything more
Does the caller understand that repeating requests will not help?
In e1000_main.c
skb = dev_alloc_skb(adapter->rx_buffer_len + reserve_len);
___skbuff.h___
static inline struct sk_buff *dev_alloc_skb(unsigned int length)
{
return __dev_alloc_skb(length, GFP_ATOMIC);
}
static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
int gfp_mask)
{
struct sk_buff *skb;
skb = alloc_skb(length+16, gfp_mask);
if (skb)
skb_reserve(skb,16);
return skb;
}
And the rather big alloc_skb calls kmalloc
void * kmalloc (size_t size, int flags)
{
cache_sizes_t *csizep = cache_sizes;
for (; csizep->cs_size; csizep++) {
if (size > csizep->cs_size)
continue;
return __kmem_cache_alloc(flags & GFP_DMA ?
csizep->cs_dmacachep : csizep->cs_cachep, flags);
}
return NULL;
}
- - - now take a close look at the try_again path - - -
static inline void * __kmem_cache_alloc (kmem_cache_t *cachep, int flags)
{
unsigned long save_flags;
void* objp;
kmem_cache_alloc_head(cachep, flags);
try_again:
local_irq_save(save_flags);
#ifdef CONFIG_SMP
{
cpucache_t *cc = cc_data(cachep);
if (cc) {
if (cc->avail) {
STATS_INC_ALLOCHIT(cachep);
objp = cc_entry(cc)[--cc->avail];
} else {
STATS_INC_ALLOCMISS(cachep);
objp = kmem_cache_alloc_batch(cachep,cc,flags);
if (!objp)
goto alloc_new_slab_nolock;
- - -
alloc_new_slab_nolock:
#endif
local_irq_restore(save_flags);
if (kmem_cache_grow(cachep, flags))
/* Someone may have stolen our objs. Doesn't matter, we'll
* just come back here again.
*/
goto try_again;
But kmem_cache_grow will return failed...
-> kmem_getpages -> _get_free_pages -> alloc_pages
Or have I missed something?
/RogerL
--
Roger Larsson
Skellefteå
Sweden
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: Hard Hang with __alloc_pages: 0-order allocation failed (gfp=0x20/1) - Not out of memory
2004-05-26 1:22 (Found?) Re: Hard Hang with __alloc_pages: 0-order allocation failed (gfp=0x20/1) - Not out of memory Roger Larsson
@ 2004-05-26 19:58 ` Roger Larsson
2004-05-26 20:27 ` PROBLEM: e100 or e1000 on SMP kernel freeze system (ipx+ncp) Roger Larsson
0 siblings, 1 reply; 4+ messages in thread
From: Roger Larsson @ 2004-05-26 19:58 UTC (permalink / raw)
To: linux-kernel
Modifying the header so you find it. And write a better summary...
* When you have little memory left __alloc_pages wont allow
allocations from interrupt context (even if PF_MEMALLOC)
if (current->flags & PF_MEMALLOC && !in_interrupt()) {
* But in the callchain there is a loop in __kmem_cache_alloc when running SMP
> static inline void * __kmem_cache_alloc (kmem_cache_t *cachep, int flags)
> {
> unsigned long save_flags;
> void* objp;
>
> kmem_cache_alloc_head(cachep, flags);
> try_again:
> local_irq_save(save_flags);
>
> #ifdef CONFIG_SMP
> {
> cpucache_t *cc = cc_data(cachep);
>
> if (cc) {
> if (cc->avail) {
> STATS_INC_ALLOCHIT(cachep);
> objp = cc_entry(cc)[--cc->avail];
> } else {
> STATS_INC_ALLOCMISS(cachep);
> objp = kmem_cache_alloc_batch(cachep,cc,flags);
> if (!objp)
> goto alloc_new_slab_nolock;
>
> - - - snip - - -
> alloc_new_slab_nolock:
> #endif
> local_irq_restore(save_flags);
> if (kmem_cache_grow(cachep, flags))
> /* Someone may have stolen our objs. Doesn't matter, we'll
> * just come back here again.
> */
> goto try_again;
>
> But kmem_cache_grow will return failed...
> -> kmem_getpages -> _get_free_pages -> alloc_pages
But alloc_pages WILL fail every time... => infinite loop in interrupt
context... It probably should not try again in this case...
if (!in_interrupt())
goto try_again;
Or it should check if GFP_WAIT is set... A _busy_ wait is also a wait...
/RogerL
--
Roger Larsson
Skellefteå
Sweden
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2004-05-26 22:47 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-05-26 1:22 (Found?) Re: Hard Hang with __alloc_pages: 0-order allocation failed (gfp=0x20/1) - Not out of memory Roger Larsson
2004-05-26 19:58 ` Roger Larsson
2004-05-26 20:27 ` PROBLEM: e100 or e1000 on SMP kernel freeze system (ipx+ncp) Roger Larsson
2004-05-26 22:47 ` Andrew Shirrayev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®