UMA supports "secondary" zones, in which a second zone can be layered

on top of a primary zone, sharing the same allocation "keg".  When
reporting statistics for zones, do not report the free items in the
keg as part of the free items in the zone, or those free items will
be reported more than once: for the primary zone, and then any
secondary zones off the primary zone.  Separately record and maintain
a kegfree statistic, and export via memstat_get_kegfree(), which is
available for use if needed.  Since items free'd back to the keg are
not fully initialized, and hence may not actually be available (since
secondary zone ctor-time initialization can fail), this makes some
amount of sense.

This change corrects a bug made visible in the libmemstat(3)
modifications to netstat: mbufs freed back to the keg from the
packet zone would be counted twice, resulting in negative values
being printed in the mbuf free count.

Some further refinement of reporting relating to secondary zones may
still be required.

Reported by:	ssouhlal
MFC after:	3 days
This commit is contained in:
Robert Watson 2005-07-20 09:17:40 +00:00
parent 18b35df8fe
commit ca108fe268
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=148170
5 changed files with 14 additions and 1 deletions

View File

@ -93,6 +93,8 @@
.Ft uint64_t
.Fn memstat_get_zonefree "const struct memory_type *mtp"
.Ft uint64_t
.Fn memstat_get_kegfree "const struct memory_type *mtp"
.Ft uint64_t
.Fn memstat_get_percpu_memalloced "const struct memory_type *mtp" "int cpu"
.Ft uint64_t
.Fn memstat_get_percpu_memfreed "const struct memory_type *mtp" "int cpu"

View File

@ -143,6 +143,7 @@ memstat_mt_reset_stats(struct memory_type *mtp)
mtp->mt_failures = 0;
mtp->mt_zonefree = 0;
mtp->mt_kegfree = 0;
for (i = 0; i < MEMSTAT_MAXCPU; i++) {
mtp->mt_percpu_alloc[i].mtp_memalloced = 0;
@ -291,6 +292,13 @@ memstat_get_zonefree(const struct memory_type *mtp)
return (mtp->mt_zonefree);
}
uint64_t
memstat_get_kegfree(const struct memory_type *mtp)
{
return (mtp->mt_kegfree);
}
uint64_t
memstat_get_percpu_memalloced(const struct memory_type *mtp, int cpu)
{

View File

@ -119,6 +119,7 @@ uint64_t memstat_get_caller_uint64(const struct memory_type *mtp,
void memstat_set_caller_uint64(struct memory_type *mtp, int index,
uint64_t value);
uint64_t memstat_get_zonefree(const struct memory_type *mtp);
uint64_t memstat_get_kegfree(const struct memory_type *mtp);
uint64_t memstat_get_percpu_memalloced(const struct memory_type *mtp,
int cpu);
uint64_t memstat_get_percpu_memfreed(const struct memory_type *mtp,

View File

@ -85,6 +85,7 @@ struct memory_type {
* global stats above.
*/
uint64_t mt_zonefree; /* Free items in zone. */
uint64_t mt_kegfree; /* Free items in keg. */
/*
* Per-CPU measurements fall into two categories: per-CPU allocation,

View File

@ -222,7 +222,8 @@ memstat_sysctl_uma(struct memory_type_list *list, int flags)
mtp->mt_byteslimit = uthp->uth_limit * uthp->uth_size;
mtp->mt_count = mtp->mt_numallocs - mtp->mt_numfrees;
mtp->mt_zonefree = uthp->uth_zone_free + uthp->uth_keg_free;
mtp->mt_zonefree = uthp->uth_zone_free;
mtp->mt_kegfree = uthp->uth_keg_free;
mtp->mt_free += mtp->mt_zonefree;
}