Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 Jul 2009 10:27:31 GMT
From:      Andre Oppermann <andre@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 166541 for review
Message-ID:  <200907251027.n6PARV5D079703@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=166541

Change 166541 by andre@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);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907251027.n6PARV5D079703>