From owner-svn-src-all@FreeBSD.ORG Fri Dec 7 22:27:14 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id C8E56ECB; Fri, 7 Dec 2012 22:27:14 +0000 (UTC) (envelope-from pjd@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id ADA7C8FC15; Fri, 7 Dec 2012 22:27:14 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qB7MREfw098265; Fri, 7 Dec 2012 22:27:14 GMT (envelope-from pjd@svn.freebsd.org) Received: (from pjd@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qB7MRDZl098259; Fri, 7 Dec 2012 22:27:13 GMT (envelope-from pjd@svn.freebsd.org) Message-Id: <201212072227.qB7MRDZl098259@svn.freebsd.org> From: Pawel Jakub Dawidek Date: Fri, 7 Dec 2012 22:27:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r243998 - in head: share/man/man9 sys/vm X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 07 Dec 2012 22:27:14 -0000 Author: pjd Date: Fri Dec 7 22:27:13 2012 New Revision: 243998 URL: http://svnweb.freebsd.org/changeset/base/243998 Log: Implemented uma_zone_set_warning(9) function that sets a warning, which will be printed once the given zone becomes full and cannot allocate an item. The warning will not be printed more often than every five minutes. All UMA warnings can be globally turned off by setting sysctl/tunable vm.zone_warnings to 0. Discussed on: arch Obtained from: WHEEL Systems MFC after: 2 weeks Modified: head/share/man/man9/zone.9 head/sys/vm/uma.h head/sys/vm/uma_core.c head/sys/vm/uma_int.h Modified: head/share/man/man9/zone.9 ============================================================================== --- head/share/man/man9/zone.9 Fri Dec 7 22:23:53 2012 (r243997) +++ head/share/man/man9/zone.9 Fri Dec 7 22:27:13 2012 (r243998) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 28, 2012 +.Dd December 7, 2012 .Dt ZONE 9 .Os .Sh NAME @@ -37,7 +37,8 @@ .Nm uma_zdestroy , .Nm uma_zone_set_max, .Nm uma_zone_get_max, -.Nm uma_zone_get_cur +.Nm uma_zone_get_cur, +.Nm uma_zone_set_warning .Nd zone allocator .Sh SYNOPSIS .In sys/param.h @@ -65,6 +66,8 @@ .Fn uma_zone_get_max "uma_zone_t zone" .Ft int .Fn uma_zone_get_cur "uma_zone_t zone" +.Ft void +.Fn uma_zone_set_warning "uma_zone_t zone" "const char *warning" .Sh DESCRIPTION The zone allocator provides an efficient interface for managing dynamically-sized collections of items of similar size. @@ -213,6 +216,16 @@ The returned value is approximate becaus determine an exact value is not performed by the implementation. This ensures low overhead at the expense of potentially stale data being used in the calculation. +.Pp +The +.Fn uma_zone_set_warning +function sets a warning that will be printed on the system console when the +given zone becomes full and fails to allocate an item. +The warning will be printed not often than every five minutes. +Warnings can be turned off globally by setting the +.Va vm.zone_warnings +sysctl tunable to +.Va 0 . .Sh RETURN VALUES The .Fn uma_zalloc Modified: head/sys/vm/uma.h ============================================================================== --- head/sys/vm/uma.h Fri Dec 7 22:23:53 2012 (r243997) +++ head/sys/vm/uma.h Fri Dec 7 22:27:13 2012 (r243998) @@ -476,6 +476,18 @@ int uma_zone_set_max(uma_zone_t zone, in int uma_zone_get_max(uma_zone_t zone); /* + * Sets a warning to be printed when limit is reached + * + * Arguments: + * zone The zone we will warn about + * warning Warning content + * + * Returns: + * Nothing + */ +void uma_zone_set_warning(uma_zone_t zone, const char *warning); + +/* * Obtains the approximate current number of items allocated from a zone * * Arguments: Modified: head/sys/vm/uma_core.c ============================================================================== --- head/sys/vm/uma_core.c Fri Dec 7 22:23:53 2012 (r243997) +++ head/sys/vm/uma_core.c Fri Dec 7 22:27:13 2012 (r243998) @@ -265,6 +265,11 @@ SYSCTL_PROC(_vm, OID_AUTO, zone_count, C SYSCTL_PROC(_vm, OID_AUTO, zone_stats, CTLFLAG_RD|CTLTYPE_STRUCT, 0, 0, sysctl_vm_zone_stats, "s,struct uma_type_header", "Zone Stats"); +static int zone_warnings = 1; +TUNABLE_INT("vm.zone_warnings", &zone_warnings); +SYSCTL_INT(_vm, OID_AUTO, zone_warnings, CTLFLAG_RW, &zone_warnings, 0, + "Warn when UMA zones becomes full"); + /* * This routine checks to see whether or not it's safe to enable buckets. */ @@ -363,6 +368,18 @@ bucket_zone_drain(void) zone_drain(ubz->ubz_zone); } +static void +zone_log_warning(uma_zone_t zone) +{ + static const struct timeval warninterval = { 300, 0 }; + + if (!zone_warnings || zone->uz_warning == NULL) + return; + + if (ratecheck(&zone->uz_ratecheck, &warninterval)) + printf("[zone: %s] %s\n", zone->uz_name, zone->uz_warning); +} + static inline uma_keg_t zone_first_keg(uma_zone_t zone) { @@ -1432,6 +1449,8 @@ zone_ctor(void *mem, int size, void *uda zone->uz_sleeps = 0; zone->uz_fills = zone->uz_count = 0; zone->uz_flags = 0; + zone->uz_warning = NULL; + timevalclear(&zone->uz_ratecheck); keg = arg->keg; if (arg->flags & UMA_ZONE_SECONDARY) { @@ -2191,8 +2210,10 @@ keg_fetch_slab(uma_keg_t keg, uma_zone_t * If this is not a multi-zone, set the FULL bit. * Otherwise slab_multi() takes care of it. */ - if ((zone->uz_flags & UMA_ZFLAG_MULTI) == 0) + if ((zone->uz_flags & UMA_ZFLAG_MULTI) == 0) { zone->uz_flags |= UMA_ZFLAG_FULL; + zone_log_warning(zone); + } if (flags & M_NOWAIT) break; zone->uz_sleeps++; @@ -2339,6 +2360,7 @@ zone_fetch_slab_multi(uma_zone_t zone, u if (full && !empty) { zone->uz_flags |= UMA_ZFLAG_FULL; zone->uz_sleeps++; + zone_log_warning(zone); msleep(zone, zone->uz_lock, PVM, "zonelimit", hz/100); zone->uz_flags &= ~UMA_ZFLAG_FULL; continue; @@ -2881,6 +2903,16 @@ uma_zone_get_max(uma_zone_t zone) } /* See uma.h */ +void +uma_zone_set_warning(uma_zone_t zone, const char *warning) +{ + + ZONE_LOCK(zone); + zone->uz_warning = warning; + ZONE_UNLOCK(zone); +} + +/* See uma.h */ int uma_zone_get_cur(uma_zone_t zone) { Modified: head/sys/vm/uma_int.h ============================================================================== --- head/sys/vm/uma_int.h Fri Dec 7 22:23:53 2012 (r243997) +++ head/sys/vm/uma_int.h Fri Dec 7 22:27:13 2012 (r243998) @@ -331,6 +331,10 @@ struct uma_zone { uint16_t uz_fills; /* Outstanding bucket fills */ uint16_t uz_count; /* Highest value ub_ptr can have */ + /* The next three fields are used to print a rate-limited warnings. */ + const char *uz_warning; /* Warning to print on failure */ + struct timeval uz_ratecheck; /* Warnings rate-limiting */ + /* * This HAS to be the last item because we adjust the zone size * based on NCPU and then allocate the space for the zones.