mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
uma_core: Rely on domainset iterator to wait on M_WAITOK
Commit 8b987a7769 ("Use per-domain keg locks.") removed the need to
lock the keg entirely, replacing it with per-domain keg locks. In
particular, it removed the need to hold a lock over waiting for a domain
to grow free memory.
Simplify the code of keg_fetch_slab() and uma_prealloc() by removing the
M_WAITOK -> M_NOWAIT downgrade and the local call to vm_wait_doms()
(which used to necessitate temporary dropping the keg lock) which the
iterator machinery already handles on M_WAITOK (and compatibly with
vm_domainset_iter_ignore() at that, although that does not matter now).
Reviewed by: bnovkov, markj
Tested by: bnovkov
MFC after: 3 days
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D52441
This commit is contained in:
1 file changed
+6
-16
+6
-16
@@ -4009,21 +4009,15 @@ restart:
|
||||
/*
|
||||
* Use the keg's policy if upper layers haven't already specified a
|
||||
* domain (as happens with first-touch zones).
|
||||
*
|
||||
* To avoid races we run the iterator with the keg lock held, but that
|
||||
* means that we cannot allow the vm_domainset layer to sleep. Thus,
|
||||
* clear M_WAITOK and handle low memory conditions locally.
|
||||
*/
|
||||
rr = rdomain == UMA_ANYDOMAIN;
|
||||
aflags = flags;
|
||||
if (rr) {
|
||||
aflags = (flags & ~M_WAITOK) | M_NOWAIT;
|
||||
if (vm_domainset_iter_policy_ref_init(&di, &keg->uk_dr, &domain,
|
||||
&aflags) != 0)
|
||||
return (NULL);
|
||||
} else {
|
||||
aflags = flags;
|
||||
} else
|
||||
domain = rdomain;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
slab = keg_fetch_free_slab(keg, domain, rr, flags);
|
||||
@@ -4053,13 +4047,8 @@ restart:
|
||||
if ((flags & M_WAITOK) == 0)
|
||||
break;
|
||||
vm_wait_domain(domain);
|
||||
} else if (vm_domainset_iter_policy(&di, &domain) != 0) {
|
||||
if ((flags & M_WAITOK) != 0) {
|
||||
vm_wait_doms(&keg->uk_dr.dr_policy->ds_mask, 0);
|
||||
goto restart;
|
||||
}
|
||||
} else if (vm_domainset_iter_policy(&di, &domain) != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5245,7 +5234,7 @@ uma_prealloc(uma_zone_t zone, int items)
|
||||
KEG_GET(zone, keg);
|
||||
slabs = howmany(items, keg->uk_ipers);
|
||||
while (slabs-- > 0) {
|
||||
aflags = M_NOWAIT;
|
||||
aflags = M_WAITOK;
|
||||
if (vm_domainset_iter_policy_ref_init(&di, &keg->uk_dr, &domain,
|
||||
&aflags) != 0)
|
||||
panic("%s: Domainset is empty", __func__);
|
||||
@@ -5266,7 +5255,8 @@ uma_prealloc(uma_zone_t zone, int items)
|
||||
break;
|
||||
}
|
||||
if (vm_domainset_iter_policy(&di, &domain) != 0)
|
||||
vm_wait_doms(&keg->uk_dr.dr_policy->ds_mask, 0);
|
||||
panic("%s: Cannot allocate from any domain",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user