PERFORCE change 166541 for review
Andre Oppermann
andre at FreeBSD.org
Sat Jul 25 10:27:34 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=166541
Change 166541 by andre at andre_t61 on 2009/07/25 10:27:15
In uma_zone_set_max():
Lock the keg when changing uk_maxpages even though normally the zone lock is the keg lock.
Handle the value 0 for unlimited. Before it would result in a minimum sized zone.
Wakeup anyone blocked on the keg/zone when the limit is raised or removed.
Affected files ...
.. //depot/projects/tcp_reass/vm/uma_core.c#7 edit
Differences ...
==== //depot/projects/tcp_reass/vm/uma_core.c#7 (text+ko) ====
@@ -2761,7 +2761,7 @@
clearfull = 0;
if (keg->uk_flags & UMA_ZFLAG_FULL) {
- if (keg->uk_pages < keg->uk_maxpages) {
+ if (keg->uk_pages < keg->uk_maxpages || keg->uk_maxpages == 0) {
keg->uk_flags &= ~UMA_ZFLAG_FULL;
clearfull = 1;
}
@@ -2787,13 +2787,45 @@
void
uma_zone_set_max(uma_zone_t zone, int nitems)
{
+ u_int32_t mp;
uma_keg_t keg;
+ int clearfull = 0;
+ /*
+ * Normally the zone lock *is* the keg lock.
+ */
ZONE_LOCK(zone);
keg = zone_first_keg(zone);
- keg->uk_maxpages = (nitems / keg->uk_ipers) * keg->uk_ppera;
- if (keg->uk_maxpages * keg->uk_ipers < nitems)
- keg->uk_maxpages += keg->uk_ppera;
+ keg_relock(keg, zone);
+
+ mp = keg->uk_maxpages;
+ /*
+ * Increase the limit or remove it.
+ */
+ if (nitems > 0) {
+ keg->uk_maxpages = (nitems / keg->uk_ipers) * keg->uk_ppera;
+ if (keg->uk_maxpages * keg->uk_ipers < nitems)
+ keg->uk_maxpages += keg->uk_ppera;
+ } else
+ keg->uk_maxpages = 0;
+
+ /*
+ * If the keg was full and the limit was increased,
+ * or removed, then wake up anyone stuck on waiting
+ * for memory.
+ */
+ if ((keg->uk_flags & UMA_ZFLAG_FULL) &&
+ (keg->uk_maxpages == 0 || mp < keg->uk_maxpages)) {
+ keg->uk_flags &= ~UMA_ZFLAG_FULL;
+ clearfull = 1;
+ wakeup(keg);
+ }
+ zone_relock(zone, keg);
+
+ if (clearfull) {
+ zone->uz_flags &= ~UMA_ZFLAG_FULL;
+ wakeup(zone);
+ }
ZONE_UNLOCK(zone);
}
More information about the p4-projects
mailing list