svn commit: r331841 - stable/11/sys/vm
Konstantin Belousov
kib at FreeBSD.org
Sat Mar 31 12:45:40 UTC 2018
Author: kib
Date: Sat Mar 31 12:45:39 2018
New Revision: 331841
URL: https://svnweb.freebsd.org/changeset/base/331841
Log:
MFC r331489:
For vm_zone_stats() sysctl handler, do not drain sbuf calling copyout(9)
while owning zone lock.
Modified:
stable/11/sys/vm/uma_core.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/vm/uma_core.c
==============================================================================
--- stable/11/sys/vm/uma_core.c Sat Mar 31 12:44:11 2018 (r331840)
+++ stable/11/sys/vm/uma_core.c Sat Mar 31 12:45:39 2018 (r331841)
@@ -3414,7 +3414,7 @@ sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS)
{
struct uma_stream_header ush;
struct uma_type_header uth;
- struct uma_percpu_stat ups;
+ struct uma_percpu_stat *ups;
uma_bucket_t bucket;
struct sbuf sbuf;
uma_cache_t cache;
@@ -3429,6 +3429,7 @@ sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS)
return (error);
sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
sbuf_clear_flags(&sbuf, SBUF_INCLUDENUL);
+ ups = malloc((mp_maxid + 1) * sizeof(*ups), M_TEMP, M_WAITOK);
count = 0;
rw_rlock(&uma_rwlock);
@@ -3477,7 +3478,6 @@ sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS)
uth.uth_frees = z->uz_frees;
uth.uth_fails = z->uz_fails;
uth.uth_sleeps = z->uz_sleeps;
- (void)sbuf_bcat(&sbuf, &uth, sizeof(uth));
/*
* While it is not normally safe to access the cache
* bucket pointers while not on the CPU that owns the
@@ -3486,30 +3486,31 @@ sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS)
* accept the possible race associated with bucket
* exchange during monitoring.
*/
- for (i = 0; i < (mp_maxid + 1); i++) {
- bzero(&ups, sizeof(ups));
- if (kz->uk_flags & UMA_ZFLAG_INTERNAL)
- goto skip;
- if (CPU_ABSENT(i))
- goto skip;
+ for (i = 0; i < mp_maxid + 1; i++) {
+ bzero(&ups[i], sizeof(*ups));
+ if (kz->uk_flags & UMA_ZFLAG_INTERNAL ||
+ CPU_ABSENT(i))
+ continue;
cache = &z->uz_cpu[i];
if (cache->uc_allocbucket != NULL)
- ups.ups_cache_free +=
+ ups[i].ups_cache_free +=
cache->uc_allocbucket->ub_cnt;
if (cache->uc_freebucket != NULL)
- ups.ups_cache_free +=
+ ups[i].ups_cache_free +=
cache->uc_freebucket->ub_cnt;
- ups.ups_allocs = cache->uc_allocs;
- ups.ups_frees = cache->uc_frees;
-skip:
- (void)sbuf_bcat(&sbuf, &ups, sizeof(ups));
+ ups[i].ups_allocs = cache->uc_allocs;
+ ups[i].ups_frees = cache->uc_frees;
}
ZONE_UNLOCK(z);
+ (void)sbuf_bcat(&sbuf, &uth, sizeof(uth));
+ for (i = 0; i < mp_maxid + 1; i++)
+ (void)sbuf_bcat(&sbuf, &ups[i], sizeof(ups[i]));
}
}
rw_runlock(&uma_rwlock);
error = sbuf_finish(&sbuf);
sbuf_delete(&sbuf);
+ free(ups, M_TEMP);
return (error);
}
More information about the svn-src-stable-11
mailing list