Date: Wed, 08 Mar 2017 14:27:15 -0800 From: John Baldwin <jhb@freebsd.org> To: freebsd-hackers@freebsd.org Cc: Karl Denninger <karl@denninger.net> Subject: Re: Kernel UMA current occupancy statistics Message-ID: <2800890.fCNZHq2Y8P@ralph.baldwin.cx> In-Reply-To: <18fdca3b-9002-db60-504b-388c628fab0e@denninger.net> References: <18fdca3b-9002-db60-504b-388c628fab0e@denninger.net>
next in thread | previous in thread | raw e-mail | index | archive | help
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. -- John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?2800890.fCNZHq2Y8P>