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);
 }
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to