]> xenbits.xensource.com Git - people/liuw/freebsd.git/commitdiff
Add a sched_yield() to work around low memory conditions in the current code.
authoradrian <adrian@FreeBSD.org>
Sat, 7 Nov 2015 04:04:00 +0000 (04:04 +0000)
committeradrian <adrian@FreeBSD.org>
Sat, 7 Nov 2015 04:04:00 +0000 (04:04 +0000)
Things seem to get stuck in low memory conditions where no bufs are available,
the reclamation path is called to wakeup the daemon, but no sleeping is done.
Because of this, we are stuck in a tight loop in the current process and
never run said reclamation path.

This was introduced in r289279 . This is only a temporary workaround
to restore system usefulness until the more permanent solutions can be
found.

Tested:

* Carambola2, 64MB (and 32MB by manual config.)

sys/kern/vfs_bio.c

index 1e51db3954339ba3c966be7ee5e8bbb379f25da9..6376cdf2e55a0fe14f2ea35946df60fd8a8f2ef7 100644 (file)
@@ -3622,6 +3622,23 @@ loop:
                if (bp == NULL) {
                        if (slpflag || slptimeo)
                                return NULL;
+                       /*
+                        * XXX This is here until the sleep path is diagnosed
+                        * enough to work under very low memory conditions.
+                        *
+                        * There's an issue on low memory, 4BSD+non-preempt
+                        * systems (eg MIPS routers with 32MB RAM) where buffer
+                        * exhaustion occurs without sleeping for buffer
+                        * reclaimation.  This just sticks in a loop and
+                        * constantly attempts to allocate a buffer, which
+                        * hits exhaustion and tries to wakeup bufdaemon.
+                        * This never happens because we never yield.
+                        *
+                        * The real solution is to identify and fix these cases
+                        * so we aren't effectively busy-waiting in a loop
+                        * until the reclaimation path has cycles to run.
+                        */
+                       kern_yield(PRI_USER);
                        goto loop;
                }