- Simplify implementation of uma_zone_get_max.

- Add uma_zone_get_cur which returns the current approximate occupancy of
  a zone. This is useful for providing stats via sysctl amongst other things.

Sponsored by:	FreeBSD Foundation
Reviewed by:	gnn, jhb
MFC after:	2 weeks
This commit is contained in:
Lawrence Stewart 2010-10-16 04:14:45 +00:00
parent 1636dde957
commit c4ae7908a7
3 changed files with 65 additions and 13 deletions

View File

@ -25,7 +25,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd June 19, 2008 .Dd October 9, 2010
.Dt ZONE 9 .Dt ZONE 9
.Os .Os
.Sh NAME .Sh NAME
@ -35,7 +35,9 @@
.Nm uma_zfree , .Nm uma_zfree ,
.Nm uma_zfree_arg , .Nm uma_zfree_arg ,
.Nm uma_zdestroy , .Nm uma_zdestroy ,
.Nm uma_zone_set_max .Nm uma_zone_set_max,
.Nm uma_zone_get_max,
.Nm uma_zone_get_cur
.Nd zone allocator .Nd zone allocator
.Sh SYNOPSIS .Sh SYNOPSIS
.In sys/param.h .In sys/param.h
@ -59,6 +61,10 @@
.Fn uma_zdestroy "uma_zone_t zone" .Fn uma_zdestroy "uma_zone_t zone"
.Ft void .Ft void
.Fn uma_zone_set_max "uma_zone_t zone" "int nitems" .Fn uma_zone_set_max "uma_zone_t zone" "int nitems"
.Ft int
.Fn uma_zone_get_max "uma_zone_t zone"
.Ft int
.Fn uma_zone_get_cur "uma_zone_t zone"
.Sh DESCRIPTION .Sh DESCRIPTION
The zone allocator provides an efficient interface for managing The zone allocator provides an efficient interface for managing
dynamically-sized collections of items of similar size. dynamically-sized collections of items of similar size.
@ -170,21 +176,36 @@ must have been freed with
.Fn uma_zfree .Fn uma_zfree
before. before.
.Pp .Pp
The purpose of The
.Fn uma_zone_set_max .Fn uma_zone_set_max
is to limit the maximum amount of memory that the system can dedicated function limits the number of items
toward the zone specified by the .Pq and therefore memory
.Fa zone that can be allocated to
argument. .Fa zone .
The The
.Fa nitems .Fa nitems
argument gives the upper limit of items in the zone. argument specifies the requested upper limit number of items.
This limits the total number of items in the zone which includes: The effective limit may end up being higher than requested, as the
implementation will round up to ensure all memory pages allocated to the zone
are utilised to capacity.
The limit applies to the total number of items in the zone, which includes
allocated items, free items and free items in the per-cpu caches. allocated items, free items and free items in the per-cpu caches.
On systems with more than one CPU it may not be possible to allocate On systems with more than one CPU it may not be possible to allocate
the specified number of items even when there is no shortage of memory, the specified number of items even when there is no shortage of memory,
because all of the remaining free items may be in the caches of the because all of the remaining free items may be in the caches of the
other CPUs when the limit is hit. other CPUs when the limit is hit.
.Pp
The
.Fn uma_zone_get_max
function returns the effective upper limit number of items for a zone.
.Pp
The
.Fn uma_zone_get_cur
function returns the approximate current occupancy of the zone.
The returned value is approximate because appropriate synchronisation to
determine an exact value is not performend by the implementation.
This ensures low overhead at the expense of potentially stale data being used
in the calculation.
.Sh RETURN VALUES .Sh RETURN VALUES
The The
.Fn uma_zalloc .Fn uma_zalloc

View File

@ -470,6 +470,17 @@ void uma_zone_set_max(uma_zone_t zone, int nitems);
*/ */
int uma_zone_get_max(uma_zone_t zone); int uma_zone_get_max(uma_zone_t zone);
/*
* Obtains the approximate current number of items allocated from a zone
*
* Arguments:
* zone The zone to obtain the current allocation count from
*
* Return:
* int The approximate current number of items allocated from the zone
*/
int uma_zone_get_cur(uma_zone_t zone);
/* /*
* The following two routines (uma_zone_set_init/fini) * The following two routines (uma_zone_set_init/fini)
* are used to set the backend init/fini pair which acts on an * are used to set the backend init/fini pair which acts on an

View File

@ -2805,15 +2805,35 @@ uma_zone_get_max(uma_zone_t zone)
ZONE_LOCK(zone); ZONE_LOCK(zone);
keg = zone_first_keg(zone); keg = zone_first_keg(zone);
if (keg->uk_maxpages) nitems = keg->uk_maxpages * keg->uk_ipers;
nitems = keg->uk_maxpages * keg->uk_ipers;
else
nitems = 0;
ZONE_UNLOCK(zone); ZONE_UNLOCK(zone);
return (nitems); return (nitems);
} }
/* See uma.h */
int
uma_zone_get_cur(uma_zone_t zone)
{
int64_t nitems;
u_int i;
ZONE_LOCK(zone);
nitems = zone->uz_allocs - zone->uz_frees;
CPU_FOREACH(i) {
/*
* See the comment in sysctl_vm_zone_stats() regarding the
* safety of accessing the per-cpu caches. With the zone lock
* held, it is safe, but can potentially result in stale data.
*/
nitems += zone->uz_cpu[i].uc_allocs -
zone->uz_cpu[i].uc_frees;
}
ZONE_UNLOCK(zone);
return (nitems < 0 ? 0 : nitems);
}
/* See uma.h */ /* See uma.h */
void void
uma_zone_set_init(uma_zone_t zone, uma_init uminit) uma_zone_set_init(uma_zone_t zone, uma_init uminit)