From owner-freebsd-hackers@freebsd.org Wed Mar 8 23:13:45 2017 Return-Path: Delivered-To: freebsd-hackers@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 05CE0D039AD for ; Wed, 8 Mar 2017 23:13:45 +0000 (UTC) (envelope-from slw@zxy.spb.ru) Received: from zxy.spb.ru (zxy.spb.ru [195.70.199.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BC5ED18B2; Wed, 8 Mar 2017 23:13:44 +0000 (UTC) (envelope-from slw@zxy.spb.ru) Received: from slw by zxy.spb.ru with local (Exim 4.86 (FreeBSD)) (envelope-from ) id 1clkm4-000ArG-9y; Thu, 09 Mar 2017 02:13:40 +0300 Date: Thu, 9 Mar 2017 02:13:40 +0300 From: Slawa Olhovchenkov To: John Baldwin Cc: freebsd-hackers@freebsd.org, Karl Denninger Subject: Re: Kernel UMA current occupancy statistics Message-ID: <20170308231340.GT15630@zxy.spb.ru> References: <18fdca3b-9002-db60-504b-388c628fab0e@denninger.net> <2800890.fCNZHq2Y8P@ralph.baldwin.cx> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <2800890.fCNZHq2Y8P@ralph.baldwin.cx> User-Agent: Mutt/1.5.24 (2015-08-30) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: slw@zxy.spb.ru X-SA-Exim-Scanned: No (on zxy.spb.ru); SAEximRunCond expanded to false X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Mar 2017 23:13:45 -0000 On Wed, Mar 08, 2017 at 02:27:15PM -0800, John Baldwin wrote: > On Wednesday, August 31, 2016 08:02:06 AM Karl Denninger wrote: > > Working on the ZFS ARC code I'm trying to find documentation on the > > means by which I can determine the occupancy of a UMA slab. > > > > There is a userland set of calls but I assume those are not the correct > > way to approach this in the kernel context. include/sys/vm/uma.h > > declares that the returned structure is to be opaque to users of the > > facility, and the only occupancy-related function I can find is > > uma_zone_get_cur, which gives me the number of items allocated but > > uma_zone_get_max states that it will return "0" if no limit on > > allocations has been set. > > > > Any hints on how to determine, if for example there are 50,000 "units" > > of memory that are currently held out of kmem in a given slab how many > > are actually allocated and how many are free and reusable without a > > further kernel memory allocation? > > > > What I'm trying to determine is this (from vmstat -z): > > > > ITEM SIZE LIMIT USED FREE REQ FAIL SLEEP > > zio_buf_512: 512, 0, 79865, 199359, 6495950, 0, 0 > > > > In other words how do I programmatically, inside a kernel routine (in > > this case zfs/arc.c) retrieve the "used" and "free" values if I have a > > given slab's pointer (which I can use to call kmem_cache_reap_now)? > > > > Thanks in advance; > > vmstat -z retrieves these using memstat_sysctl_uma() from libmemstat > which in turn uses the vm.zone_stats sysctl. Looking in that function, > it seems that the used field (mt_count) is computed this way: > > mtp->mt_count = mtp->mt_numallocs - mtp->mt_numfrees; > > Where numallocs and numfrees are computed by summing a set of per-CPU > stats: > > for (j = 0; j < maxcpus; j++) { > mtp->mt_numallocs += upsp->ups_allocs; > mtp->mt_numfrees += upsp->ups_frees; > } > > The free field (mt_free) is calculated similarly. First with a global > count followed by per-CPU counts: > > mtp->mt_numfrees = uthp->uth_frees; > for (j = 0; j < maxcpus; j++) { > mtp->mt_free += upsp->ups_cache_free; > } > > The vm.zone_stats sysctl is implemented by sysctl_vm_zone_stats() in > sys/vm/uma_core.c. > > It seems like 'uma_zone_get_cur()' might give you USED. You would > need to add a new function to let you calculate FREE. You can probably > use 'uma_zone_get_cur()' as a template for implementing that other > function. uma_zone_sumstat() might also be useful as a reference. I am wrote such function as part of D7538: https://reviews.freebsd.org/D7538#f080cd65