Skip to content

Commit 781802d

Browse files
committed
uma_core: Rely on domainset iterator to wait on M_WAITOK
Commit 8b987a7 ("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
1 parent d5d1e05 commit 781802d

File tree

1 file changed

+6
-16
lines changed

1 file changed

+6
-16
lines changed

sys/vm/uma_core.c

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4009,21 +4009,15 @@ keg_fetch_slab(uma_keg_t keg, uma_zone_t zone, int rdomain, const int flags)
40094009
/*
40104010
* Use the keg's policy if upper layers haven't already specified a
40114011
* domain (as happens with first-touch zones).
4012-
*
4013-
* To avoid races we run the iterator with the keg lock held, but that
4014-
* means that we cannot allow the vm_domainset layer to sleep. Thus,
4015-
* clear M_WAITOK and handle low memory conditions locally.
40164012
*/
40174013
rr = rdomain == UMA_ANYDOMAIN;
4014+
aflags = flags;
40184015
if (rr) {
4019-
aflags = (flags & ~M_WAITOK) | M_NOWAIT;
40204016
if (vm_domainset_iter_policy_ref_init(&di, &keg->uk_dr, &domain,
40214017
&aflags) != 0)
40224018
return (NULL);
4023-
} else {
4024-
aflags = flags;
4019+
} else
40254020
domain = rdomain;
4026-
}
40274021

40284022
for (;;) {
40294023
slab = keg_fetch_free_slab(keg, domain, rr, flags);
@@ -4053,13 +4047,8 @@ keg_fetch_slab(uma_keg_t keg, uma_zone_t zone, int rdomain, const int flags)
40534047
if ((flags & M_WAITOK) == 0)
40544048
break;
40554049
vm_wait_domain(domain);
4056-
} else if (vm_domainset_iter_policy(&di, &domain) != 0) {
4057-
if ((flags & M_WAITOK) != 0) {
4058-
vm_wait_doms(&keg->uk_dr.dr_policy->ds_mask, 0);
4059-
goto restart;
4060-
}
4050+
} else if (vm_domainset_iter_policy(&di, &domain) != 0)
40614051
break;
4062-
}
40634052
}
40644053

40654054
/*
@@ -5245,7 +5234,7 @@ uma_prealloc(uma_zone_t zone, int items)
52455234
KEG_GET(zone, keg);
52465235
slabs = howmany(items, keg->uk_ipers);
52475236
while (slabs-- > 0) {
5248-
aflags = M_NOWAIT;
5237+
aflags = M_WAITOK;
52495238
if (vm_domainset_iter_policy_ref_init(&di, &keg->uk_dr, &domain,
52505239
&aflags) != 0)
52515240
panic("%s: Domainset is empty", __func__);
@@ -5266,7 +5255,8 @@ uma_prealloc(uma_zone_t zone, int items)
52665255
break;
52675256
}
52685257
if (vm_domainset_iter_policy(&di, &domain) != 0)
5269-
vm_wait_doms(&keg->uk_dr.dr_policy->ds_mask, 0);
5258+
panic("%s: Cannot allocate from any domain",
5259+
__func__);
52705260
}
52715261
}
52725262
}

0 commit comments

Comments
 (0)