Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 May 2010 20:49:47 -0400
From:      jhell <jhell@dataix.net>
To:        Sean Bruno <seanbru@yahoo-inc.com>
Cc:        Garrett Cooper <yanefbsd@gmail.com>, "sbruno@freebsd.org" <sbruno@freebsd.org>, freebsd-hackers <freebsd-hackers@freebsd.org>
Subject:   Re: Exposing Zone Sleeps
Message-ID:  <4BFDC1AB.4090604@dataix.net>
In-Reply-To: <1274900290.2481.135.camel@localhost.localdomain>
References:  <1274739973.31299.23.camel@localhost.localdomain> <4BFBD838.40208@dataix.net> <4BFC1660.1000405@dataix.net> <AANLkTimkvxtzMWuvfOLWy5SKQH9kTUow0F2I5nJtGL48@mail.gmail.com> <AANLkTikfzFFNSg0ZqYmsmobpkCxcRsS0rx9HYJ_bCvWK@mail.gmail.com> <1274900290.2481.135.camel@localhost.localdomain>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------030108020004090702040307
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 05/26/2010 14:58, Sean Bruno wrote:
> On Wed, 2010-05-26 at 11:52 -0700, Garrett Cooper wrote:
> 
> 
>>>>
>>>> This patch instead pardon the early.post but there was a problem with
>>>> the last patch that I attached for stable/8 r208530 with arguments 10 &
>>>> 11 to function sysctl_vm_zone where it wanted a long unsigned integer
>>>> rather than u_int64_t.
>>>>
>>>> This patch satisfies that. Whether its correct is left to the reader but
>>>> compiles cleanly & runs smoothly.
>>>
>>> I know this seems trivial, but could you change:
>>>
>>> +       printf("%-20s %6s %6s %8s %8s %8s %4s %4s\n\n", "ITEM", "SIZE",
>>> +           "LIMIT", "USED", "FREE", "REQ", "FAIL", "SLEEP");
>>>
>>> to
>>>
>>> +       printf("%-20s %6s %6s %8s %8s %8s %4s %4s\n\n", "ITEM", "SIZE",
>>> +           "LIMIT", "USED", "FREE", "REQS", "FAIL", "SLEEP");
>>>
>>> that way the plural nature of requests is more straightforward and understood.
>>>
>>> Also, do all of the fields _really_ need to have a field width? Seems
>>> like overkill to me...
>>
>> Oh, and the field width for the last item is wrong; SLEEP will be
>> truncated to SLEE.
>> Thanks,
>> -Garrett
> 
> I hate this type of column implementation.  Any ideas on a more useful
> implementation?
> 
> also, I'm missing an email in this thread somehow.  I didn't see the
> second version of the REL-8 patch.
> 
> Sean

Attached is the diff against vmstat.c only *just* to view the
differences. This is also in the sleep_stat_stable8-r208580.diff so no
need to patch twice.

Also attached is the patch for sleep stat on stable/8 "revised". against
r208580:

Changes:
*	Added back the #ifdef DDB
*	vmstat(1) displays all columns in a 80 column display cleanly.

Comments & suggestions ?

I am a little bit shaky about putting the last column so close to the
end of the terminal but that may just be my own personal worries but for
now every field should have enough room to grow as far as I can verify
on my own equipment. Test this out and let me know what you think, if it
wraps or not and whether you think there is enough space for the numbers
to grow in the current layout of the columns.

Thanks again & regards,

- -- 

 jhell
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (FreeBSD)

iQEcBAEBAgAGBQJL/cGqAAoJEJBXh4mJ2FR+oo4IAJWt9sOEhnlmZOG+8Ehf7SKt
QX5ZxBDHz196FR5zOW1p4xjfkGX5ZVD0WytHS7JyTxTiMxkvzELfFpbzfGFtp1U8
Hgtv76gCZnZOEdOTCdtjknJmJNw6FC9FMAXLv5f4tzBj8HNo5sfg0x9wBmEiUfI0
8WO9f83n62lKV5SRyx+jRM/FeAZsNz9zAT0+Z8UmYUDSy+u6jFLYbWD71TzwLMKd
8+Ba/5qsnTTFVfqZOG3lRPcOCdj1QBicRzL+hyKfmNFT1IN8Xek+BhE9sDiOmqK2
0dt87kaDBV5reAeQ1P0Cqvgl7m1JGWg0bJL+c5Z7O2MpcosOxqbfTji1lHQiVZo=
=uA4o
-----END PGP SIGNATURE-----

--------------030108020004090702040307
Content-Type: text/x-patch;
 name="vmstat-z.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="vmstat-z.diff"

Index: vmstat.c
===================================================================
--- vmstat.c	(revision 208580)
+++ vmstat.c	(working copy)
@@ -1286,16 +1286,17 @@
 				    memstat_strerror(error));
 		}
 	}
-	printf("%-20s %8s  %8s  %8s  %8s  %8s  %8s\n\n", "ITEM", "SIZE",
-	    "LIMIT", "USED", "FREE", "REQUESTS", "FAILURES");
+	printf("%-20s %+6s %+8s %+8s %+6s %+10s %+8s %+6s\n\n", "ITEM", "SIZE",
+		"LIMIT", "USED", "FREE", "REQS", "FAIL", "SLEEP");
 	for (mtp = memstat_mtl_first(mtlp); mtp != NULL;
 	    mtp = memstat_mtl_next(mtp)) {
 		strlcpy(name, memstat_get_name(mtp), MEMTYPE_MAXNAME);
 		strcat(name, ":");
-		printf("%-20s %8llu, %8llu, %8llu, %8llu, %8llu, %8llu\n", name,
+		printf("%-20s %+6llu,%+8llu,%+8llu,%+6llu,%+10llu,%+8llu,%+6llu\n",name,
 		    memstat_get_size(mtp), memstat_get_countlimit(mtp),
 		    memstat_get_count(mtp), memstat_get_free(mtp),
-		    memstat_get_numallocs(mtp), memstat_get_failures(mtp));
+		    memstat_get_numallocs(mtp), memstat_get_failures(mtp),
+		    memstat_get_sleeps(mtp));
 	}
 	memstat_mtl_free(mtlp);
 	printf("\n");

--------------030108020004090702040307
Content-Type: text/x-patch;
 name="sleep_stat_stable8_r208580.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="sleep_stat_stable8_r208580.diff"

Index: usr.bin/vmstat/vmstat.c
===================================================================
--- usr.bin/vmstat/vmstat.c	(revision 208580)
+++ usr.bin/vmstat/vmstat.c	(working copy)
@@ -1286,16 +1286,17 @@
 				    memstat_strerror(error));
 		}
 	}
-	printf("%-20s %8s  %8s  %8s  %8s  %8s  %8s\n\n", "ITEM", "SIZE",
-	    "LIMIT", "USED", "FREE", "REQUESTS", "FAILURES");
+	printf("%-20s %+6s %+8s %+8s %+6s %+10s %+8s %+6s\n\n", "ITEM", "SIZE",
+		"LIMIT", "USED", "FREE", "REQS", "FAIL", "SLEEP");
 	for (mtp = memstat_mtl_first(mtlp); mtp != NULL;
 	    mtp = memstat_mtl_next(mtp)) {
 		strlcpy(name, memstat_get_name(mtp), MEMTYPE_MAXNAME);
 		strcat(name, ":");
-		printf("%-20s %8llu, %8llu, %8llu, %8llu, %8llu, %8llu\n", name,
+		printf("%-20s %+6llu,%+8llu,%+8llu,%+6llu,%+10llu,%+8llu,%+6llu\n",name,
 		    memstat_get_size(mtp), memstat_get_countlimit(mtp),
 		    memstat_get_count(mtp), memstat_get_free(mtp),
-		    memstat_get_numallocs(mtp), memstat_get_failures(mtp));
+		    memstat_get_numallocs(mtp), memstat_get_failures(mtp),
+		    memstat_get_sleeps(mtp));
 	}
 	memstat_mtl_free(mtlp);
 	printf("\n");
Index: lib/libmemstat/memstat.h
===================================================================
--- lib/libmemstat/memstat.h	(revision 208580)
+++ lib/libmemstat/memstat.h	(working copy)
@@ -139,6 +139,7 @@
 uint64_t	 memstat_get_count(const struct memory_type *mtp);
 uint64_t	 memstat_get_free(const struct memory_type *mtp);
 uint64_t	 memstat_get_failures(const struct memory_type *mtp);
+uint64_t	 memstat_get_sleeps(const struct memory_type *mtp);
 void		*memstat_get_caller_pointer(const struct memory_type *mtp,
 		    int index);
 void		 memstat_set_caller_pointer(struct memory_type *mtp,
Index: lib/libmemstat/memstat.c
===================================================================
--- lib/libmemstat/memstat.c	(revision 208580)
+++ lib/libmemstat/memstat.c	(working copy)
@@ -188,6 +188,7 @@
 	mtp->mt_count = 0;
 	mtp->mt_free = 0;
 	mtp->mt_failures = 0;
+	mtp->mt_sleeps = 0;
 
 	mtp->mt_zonefree = 0;
 	mtp->mt_kegfree = 0;
@@ -304,6 +305,13 @@
 	return (mtp->mt_failures);
 }
 
+uint64_t
+memstat_get_sleeps(const struct memory_type *mtp)
+{
+
+	return (mtp->mt_sleeps);
+}
+
 void *
 memstat_get_caller_pointer(const struct memory_type *mtp, int index)
 {
Index: lib/libmemstat/memstat_internal.h
===================================================================
--- lib/libmemstat/memstat_internal.h	(revision 208580)
+++ lib/libmemstat/memstat_internal.h	(working copy)
@@ -65,6 +65,7 @@
 	uint64_t	 mt_count;	/* Number of current allocations. */
 	uint64_t	 mt_free;	/* Number of cached free items. */
 	uint64_t	 mt_failures;	/* Number of allocation failures. */
+	uint64_t	 mt_sleeps;	/* Number of allocation sleeps. */
 
 	/*
 	 * Caller-owned memory.
Index: lib/libmemstat/memstat_uma.c
===================================================================
--- lib/libmemstat/memstat_uma.c	(revision 208580)
+++ lib/libmemstat/memstat_uma.c	(working copy)
@@ -208,6 +208,7 @@
 		mtp->mt_numallocs = uthp->uth_allocs;
 		mtp->mt_numfrees = uthp->uth_frees;
 		mtp->mt_failures = uthp->uth_fails;
+		mtp->mt_sleeps = uthp->uth_sleeps;
 
 		for (j = 0; j < maxcpus; j++) {
 			upsp = (struct uma_percpu_stat *)p;
@@ -402,6 +403,7 @@
 			mtp->mt_numallocs = uz.uz_allocs;
 			mtp->mt_numfrees = uz.uz_frees;
 			mtp->mt_failures = uz.uz_fails;
+			mtp->mt_sleeps = uz.uz_sleeps;
 			if (kz.uk_flags & UMA_ZFLAG_INTERNAL)
 				goto skip_percpu;
 			for (i = 0; i < mp_maxid + 1; i++) {
Index: sys/vm/uma_int.h
===================================================================
--- sys/vm/uma_int.h	(revision 208580)
+++ sys/vm/uma_int.h	(working copy)
@@ -314,7 +314,8 @@
 
 	u_int64_t	uz_allocs;	/* Total number of allocations */
 	u_int64_t	uz_frees;	/* Total number of frees */
-	u_int64_t	uz_fails;	/* Total number of alloc failures */
+	long unsigned int uz_fails;	/* Total number of alloc failures */
+	long unsigned int uz_sleeps;	/* Total number of alloc sleeps */
 	u_int32_t	uz_flags;	/* Flags inherited from kegs */
 	u_int32_t	uz_size;	/* Size inherited from kegs */
 	uint16_t	uz_fills;	/* Outstanding bucket fills */
Index: sys/vm/uma.h
===================================================================
--- sys/vm/uma.h	(revision 208580)
+++ sys/vm/uma.h	(working copy)
@@ -600,7 +600,8 @@
 	u_int64_t	uth_allocs;	/* Zone: number of allocations. */
 	u_int64_t	uth_frees;	/* Zone: number of frees. */
 	u_int64_t	uth_fails;	/* Zone: number of alloc failures. */
-	u_int64_t	_uth_reserved1[3];	/* Reserved. */
+	u_int64_t	_uth_reserved1[2];	/* Reserved. */
+	u_int64_t	uth_sleeps;	/* Zone: number of alloc sleeps. */
 };
 
 struct uma_percpu_stat {
Index: sys/vm/uma_core.c
===================================================================
--- sys/vm/uma_core.c	(revision 208580)
+++ sys/vm/uma_core.c	(working copy)
@@ -249,11 +249,15 @@
 
 void uma_print_zone(uma_zone_t);
 void uma_print_stats(void);
+static int sysctl_vm_zone(SYSCTL_HANDLER_ARGS);
 static int sysctl_vm_zone_count(SYSCTL_HANDLER_ARGS);
 static int sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS);
 
 SYSINIT(uma_startup3, SI_SUB_VM_CONF, SI_ORDER_SECOND, uma_startup3, NULL);
 
+SYSCTL_OID(_vm, OID_AUTO, zone, CTLTYPE_STRING|CTLFLAG_RD,
+    NULL, 0, sysctl_vm_zone, "A", "Zone Info");
+
 SYSCTL_PROC(_vm, OID_AUTO, zone_count, CTLFLAG_RD|CTLTYPE_INT,
     0, 0, sysctl_vm_zone_count, "I", "Number of UMA zones");
 
@@ -1400,6 +1404,7 @@
 	zone->uz_allocs = 0;
 	zone->uz_frees = 0;
 	zone->uz_fails = 0;
+	zone->uz_sleeps = 0;
 	zone->uz_fills = zone->uz_count = 0;
 	zone->uz_flags = 0;
 	keg = arg->keg;
@@ -2287,6 +2292,7 @@
 		 */
 		if (full && !empty) {
 			zone->uz_flags |= UMA_ZFLAG_FULL;
+			zone->uz_sleeps++;
 			msleep(zone, zone->uz_lock, PVM, "zonelimit", hz/100);
 			zone->uz_flags &= ~UMA_ZFLAG_FULL;
 			continue;
@@ -3132,6 +3138,85 @@
 }
 #endif /* DDB */
 
+/*
+ * Sysctl handler for vm.zone
+ *
+ * stolen from vm_zone.c
+ */
+static int
+sysctl_vm_zone(SYSCTL_HANDLER_ARGS)
+{
+	int error, len, cnt;
+	const int linesize = 128;	/* conservative */
+	int totalfree;
+	char *tmpbuf, *offset;
+	uma_zone_t z;
+	uma_keg_t zk;
+	char *p;
+	int cachefree;
+	uma_bucket_t bucket;
+	u_int64_t allocs, frees;
+
+	cnt = 0;
+	mtx_lock(&uma_mtx);
+	LIST_FOREACH(zk, &uma_kegs, uk_link) {
+		LIST_FOREACH(z, &zk->uk_zones, uz_link)
+			cnt++;
+	}
+	mtx_unlock(&uma_mtx);
+	MALLOC(tmpbuf, char *, (cnt == 0 ? 1 : cnt) * linesize,
+			M_TEMP, M_WAITOK);
+	len = snprintf(tmpbuf, linesize,
+	    "\nITEM            SIZE   LIMIT     USED    FREE      REQ   FAIL SLEEP\n\n");
+	if (cnt == 0)
+		tmpbuf[len - 1] = '\0';
+	error = SYSCTL_OUT(req, tmpbuf, cnt == 0 ? len-1 : len);
+	if (error || cnt == 0)
+		goto out;
+	offset = tmpbuf;
+	mtx_lock(&uma_mtx);
+	LIST_FOREACH(zk, &uma_kegs, uk_link) {
+	  LIST_FOREACH(z, &zk->uk_zones, uz_link) {
+		if (cnt == 0)	/* list may have changed size */
+			break;
+		ZONE_LOCK(z);
+		cachefree = 0;
+		if (!(zk->uk_flags & UMA_ZFLAG_INTERNAL)) {
+			uma_zone_sumstat(z, &cachefree, &allocs, &frees);
+		} else {
+			allocs = z->uz_allocs;
+			frees = z->uz_frees;
+		}
+
+		LIST_FOREACH(bucket, &z->uz_full_bucket, ub_link) {
+			cachefree += bucket->ub_cnt;
+		}
+		totalfree = zk->uk_free + cachefree;
+		len = snprintf(offset, linesize,
+		    "%-12.12s  %6.6u, %6.6u, %6.6u, %6.6u, %8.8llu, %4.4lu, %4.4lu\n",
+		    /*ITEM*/z->uz_name, /*SIZE*/zk->uk_size,
+		    /*LIMIT*/zk->uk_maxpages * zk->uk_ipers,
+		    /*USED*/(zk->uk_ipers * (zk->uk_pages / zk->uk_ppera)) - totalfree,
+		    /*FREE*/totalfree,
+		    /*REQ*/(unsigned long long)allocs,
+		    /*FAIL*/z->uz_fails,
+		    /*SLEEP*/z->uz_sleeps);
+		ZONE_UNLOCK(z);
+		for (p = offset + 12; p > offset && *p == ' '; --p)
+			/* nothing */ ;
+		p[1] = ':';
+		cnt--;
+		offset += len;
+	  }
+	}
+	mtx_unlock(&uma_mtx);
+	*offset++ = '\0';
+	error = SYSCTL_OUT(req, tmpbuf, offset - tmpbuf);
+out:
+	FREE(tmpbuf, M_TEMP);
+	return (error);
+}
+
 static int
 sysctl_vm_zone_count(SYSCTL_HANDLER_ARGS)
 {
@@ -3236,6 +3321,7 @@
 			uth.uth_allocs = z->uz_allocs;
 			uth.uth_frees = z->uz_frees;
 			uth.uth_fails = z->uz_fails;
+			uth.uth_sleeps = z->uz_sleeps;
 			if (sbuf_bcat(&sbuf, &uth, sizeof(uth)) < 0) {
 				ZONE_UNLOCK(z);
 				mtx_unlock(&uma_mtx);

--------------030108020004090702040307
Content-Type: application/octet-stream;
 name="vmstat-z.diff.sig"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename="vmstat-z.diff.sig"

iQEcBAABAgAGBQJL/cGrAAoJEJBXh4mJ2FR+OKEIAJonhKdbXekseQv6caOe7uLdJlv+nd8w
ypyc/O85lTtN+6ZsUOa+hE+lCiLAdtX4gNCN33PlxJP+mV2x0VY1P6zqRsbVYn2LicfFpis9
4bbrX77JEO6DKXhwyjotTTBZ/B8wQ9SDEqifM1oNGEnROY69zyhmDKH+GEdnz7i/CUvIha8Y
sATAF+aEhJv5DHa60r0JMu8tbVrzyB5tyBNWMcZZvXPQMl1elrFCqkDlAiec+QgVixRupT8X
nD0OurUOL0Fnk0AiiG1tGilk5radR7yA7drfjZuUV20Cobi4jTqGxAQUDtAW5T39ayiJP5Fg
wYK/PY2ize9jKFAEdZeeyCA=
--------------030108020004090702040307
Content-Type: application/octet-stream;
	name="sleep_stat_stable8_r208580.diff.sig"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="sleep_stat_stable8_r208580.diff.sig"

iQEcBAABAgAGBQJL/cGrAAoJEJBXh4mJ2FR+A+QH/iv53Ra7coIY2sNHxbKyRm26lTe3HaU9
blb6x7Jw9Kku688Gti/F9sYhUhz/UIlJk4XF3hcGNxU4E4FgIGHZtCBLESISzRzQV28cbLq1
q0uUZsOL4Z/TcLBUAxmrDtyHmPDuYDGkSNX+A/vP0aw+YoBn0qWOPED2dEOsA9gHhJ7B+4eu
lmBxrUR3X6cAzMxfbX4ZEV/6XwhXfLwK20MTz7cBVnzlhLki9ZIPCgVVX+u6l3whW2hloY+W
DFiiokn/9ITMAlhHWuALqsqyvB3NOs46s7POaf4qorZUo4Mc6VN4QXrgWLvjxvsRpKoYycMF
8qZO10Mt/Z14060u8i1TwCU=
--------------030108020004090702040307--



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