__alloc_pages_slowpath: Give up timeslice if under memory pressure.
If we aren't able to get any memory despite going through the slowpath once,
suspend the current process until later. Previously, the kernel would just
call cond_resched() in a few places, but that doesn't work well if the
current task has realtime priority: it will prevent other critical tasks
like kswapd, nfsiod, or mtdblock## from running. Those tasks, in turn,
might need to run in order to actually free up memory, which is what the
alloc_pages_slowpath() loop is waiting for in the first place.
This fix is probably not really ideal (it would slow down recovery in the
"lucky" cases where we manage to clear things up after a single time through
the loop). But it seems to be relatively harmless because it's such a
rarely-used code path. And it definitely beats hanging the whole kernel.
This condition triggered very frequently when the OOM killed kicked in, but
note that the OOM killer is not actually necessary to cause the problem. It
could occur if the kernel ever freed up pages from a realtime process and
needed to swap them back in.
I added printk's to each case, and confirmed that neither of them shows up
(at least on a TV box) under normal conditions.
2 files changed