Only update the domain cursor once in keg_fetch_slab().

We drop the keg lock when we go to actually allocate the slab, allowing
other threads to advance the cursor.  This can cause us to exit the
round-robin loop before having attempted allocations from all domains,
resulting in a hang during a subsequent blocking allocation attempt from
a depleted domain.

Reported and tested by:	Jan Bramkamp <crest@bultmann.eu>
Reviewed by:	alc, cem
Approved by:	re (gjb)
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D17209
This commit is contained in:
markj 2018-09-18 17:51:45 +00:00
parent 5b1e55571c
commit 351e1e4099

View File

@ -2698,10 +2698,8 @@ again:
LIST_INSERT_HEAD(&dom->ud_part_slab, slab, us_link);
return (slab);
}
if (rr) {
keg->uk_cursor = (keg->uk_cursor + 1) % vm_ndomains;
domain = keg->uk_cursor;
}
if (rr)
domain = (domain + 1) % vm_ndomains;
} while (domain != start);
/* Retry domain scan with blocking. */