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>