kmalloc() will return null even when there is spare virtual memory
about if it is called with GFP_ATOMIC (from an interrupt or bottom
half handler) if physical memory has run out. This is because (for
obvious reasons) it can't swap out under such a circumstance.
The normal cause is extensive use of fragmented packets which reassemble
to be larger than 4K (may be you are NFS serving to clients using 4k or
more as their default size? in which case mount -orsize=1024,wsize=1024
if possible).
Failing this (or if the above isn't the cause), one possibility is
to up the (now misnamed, or maybe someone has renamed it) MAX_SECONDARY_PAGES
value. In fact I think someone changed this not to be a constant but to vary
according to physical RAM (look at how __get_free_pages() balks requests
for pages when called with other than GFP_ATOMIC - there used to be a line
like
if (( Priority == GFP_ATOMIC) || (FreePages >= MAX_SECONDARY_PAGES))
{
... go and get them the page
}
... and your call is probably failing not enough secondary pages are being
left in reserve (i.e. the system isn't swapping soon enough). Trouble is
you don't *only* need free pages for atomic allocs, you need contiguous
free pages. But making it reserve contiguous pages tends to give less
good memory usage.
Anyway, if you want it, here's an off the top of my head pseudo patch
which probably won't make it into the distribution as it's too memory hungry.
(no it won't run through patch, no I haven't tried this though it worked while
I was developing it :-) )
- if (( Priority == GFP_ATOMIC) || (FreePages >= MAX_SECONDARY_PAGES))
+ if (( Priority == GFP_ATOMIC) || (
+ /* only give them a page if at least one of the top two highest order
+ free lists is non empty which will mean there is a reasonable amount
+ of contiguous free RAM for atomic allocs */
+ (free_area_list[NR_MEM_LISTS-1]!=&free_area_list[NR_MEM_LISTS-1])
+ || (free_area_list[NR_MEM_LISTS-2]!=&free_area_list[NR_MEM_LISTS-2])
+ ))
If you think this is too memory hungry you can add a few more || bits
with NR_MEM_LISTS-n where n are consecutive or better turn it into w while
loop to avoid accessing negative indices of the free_area_list array.
Hope it helps.
Alex
----------------------------+-------------+-----------------------------
Alex Bligh : ,-----. :
Computer Concepts Ltd. : : : alex@cconcepts.co.uk
Gaddesden Place : : ,-----. :
Hemel Hempstead : `-+---` ` : Tel. +44 1442-351000
Herts. UK HP2 6EX : | , : Fax. +44 1442-351010
: `-----` :
----------------------------+-------------+-----------------------------