1/*-
2 * Copyright (c) 2004-2005 Robert N. M. Watson
3 * Copyright (c) 2004, 2005,
4 * Bosko Milekic <bmilekic@FreeBSD.org>. All rights reserved.
5 * Copyright (c) 2002, 2003, 2004, 2005,
6 * Jeffrey Roberson <jeff@FreeBSD.org>. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
--- 35 unchanged lines hidden (view full) ---
44
45/*
46 * TODO:
47 * - Improve memory usage for large allocations
48 * - Investigate cache size adjustments
49 */
50
51#include <sys/cdefs.h>
52__FBSDID("$FreeBSD: head/sys/vm/uma_core.c 147995 2005-07-14 16:17:21Z rwatson $");
53
54/* I should really use ktr.. */
55/*
56#define UMA_DEBUG 1
57#define UMA_DEBUG_ALLOC 1
58#define UMA_DEBUG_ALLOC_1 1
59*/
60
--- 4 unchanged lines hidden (view full) ---
65#include <sys/types.h>
66#include <sys/queue.h>
67#include <sys/malloc.h>
68#include <sys/ktr.h>
69#include <sys/lock.h>
70#include <sys/sysctl.h>
71#include <sys/mutex.h>
72#include <sys/proc.h>
73#include <sys/smp.h>
74#include <sys/vmmeter.h>
75
76#include <vm/vm.h>
77#include <vm/vm_object.h>
78#include <vm/vm_page.h>
79#include <vm/vm_param.h>
80#include <vm/vm_map.h>
--- 148 unchanged lines hidden (view full) ---
229static void *uma_slab_alloc(uma_zone_t zone, uma_slab_t slab);
230static void zone_drain(uma_zone_t);
231static uma_zone_t uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit,
232 uma_fini fini, int align, u_int16_t flags);
233
234void uma_print_zone(uma_zone_t);
235void uma_print_stats(void);
236static int sysctl_vm_zone(SYSCTL_HANDLER_ARGS);
237
238#ifdef WITNESS
239static int nosleepwithlocks = 1;
240SYSCTL_INT(_debug, OID_AUTO, nosleepwithlocks, CTLFLAG_RW, &nosleepwithlocks,
241 0, "Convert M_WAITOK to M_NOWAIT to avoid lock-held-across-sleep paths");
242#else
243static int nosleepwithlocks = 0;
244SYSCTL_INT(_debug, OID_AUTO, nosleepwithlocks, CTLFLAG_RW, &nosleepwithlocks,
245 0, "Convert M_WAITOK to M_NOWAIT to avoid lock-held-across-sleep paths");
246#endif
247SYSCTL_OID(_vm, OID_AUTO, zone, CTLTYPE_STRING|CTLFLAG_RD,
248 NULL, 0, sysctl_vm_zone, "A", "Zone Info");
249SYSINIT(uma_startup3, SI_SUB_VM_CONF, SI_ORDER_SECOND, uma_startup3, NULL);
250
251/*
252 * This routine checks to see whether or not it's safe to enable buckets.
253 */
254
255static void
256bucket_enable(void)
257{
258 if (cnt.v_free_count < cnt.v_free_min)
--- 2487 unchanged lines hidden (view full) ---
2746 continue;
2747 cache = &zone->uz_cpu[i];
2748 printf("CPU %d Cache:\n", i);
2749 cache_print(cache);
2750 }
2751}
2752
2753/*
2754 * Sysctl handler for vm.zone
2755 *
2756 * stolen from vm_zone.c
2757 */
2758static int
2759sysctl_vm_zone(SYSCTL_HANDLER_ARGS)
2760{
2761 int error, len, cnt;
2762 const int linesize = 128; /* conservative */
2763 int totalfree;
2764 char *tmpbuf, *offset;
2765 uma_zone_t z;
2766 uma_keg_t zk;
2767 char *p;
2768 int cpu;
2769 int cachefree;
2770 uma_bucket_t bucket;
2771 uma_cache_t cache;
2772 u_int64_t alloc;
2773
2774 cnt = 0;
2775 mtx_lock(&uma_mtx);
2776 LIST_FOREACH(zk, &uma_kegs, uk_link) {
2777 LIST_FOREACH(z, &zk->uk_zones, uz_link)
2778 cnt++;
2779 }
2780 mtx_unlock(&uma_mtx);
--- 9 unchanged lines hidden (view full) ---
2790 offset = tmpbuf;
2791 mtx_lock(&uma_mtx);
2792 LIST_FOREACH(zk, &uma_kegs, uk_link) {
2793 LIST_FOREACH(z, &zk->uk_zones, uz_link) {
2794 if (cnt == 0) /* list may have changed size */
2795 break;
2796 ZONE_LOCK(z);
2797 cachefree = 0;
2798 alloc = 0;
2799 if (!(zk->uk_flags & UMA_ZFLAG_INTERNAL)) {
2800 for (cpu = 0; cpu <= mp_maxid; cpu++) {
2801 if (CPU_ABSENT(cpu))
2802 continue;
2803 cache = &z->uz_cpu[cpu];
2804 if (cache->uc_allocbucket != NULL)
2805 cachefree += cache->uc_allocbucket->ub_cnt;
2806 if (cache->uc_freebucket != NULL)
2807 cachefree += cache->uc_freebucket->ub_cnt;
2808 alloc += cache->uc_allocs;
2809 }
2810 }
2811 alloc += z->uz_allocs;
2812
2813 LIST_FOREACH(bucket, &z->uz_full_bucket, ub_link) {
2814 cachefree += bucket->ub_cnt;
2815 }
2816 totalfree = zk->uk_free + cachefree;
2817 len = snprintf(offset, linesize,
2818 "%-12.12s %6.6u, %8.8u, %6.6u, %6.6u, %8.8llu\n",
2819 z->uz_name, zk->uk_size,
2820 zk->uk_maxpages * zk->uk_ipers,
2821 (zk->uk_ipers * (zk->uk_pages / zk->uk_ppera)) - totalfree,
2822 totalfree,
2823 (unsigned long long)alloc);
2824 ZONE_UNLOCK(z);
2825 for (p = offset + 12; p > offset && *p == ' '; --p)
2826 /* nothing */ ;
2827 p[1] = ':';
2828 cnt--;
2829 offset += len;
2830 }
2831 }
2832 mtx_unlock(&uma_mtx);
2833 *offset++ = '\0';
2834 error = SYSCTL_OUT(req, tmpbuf, offset - tmpbuf);
2835out:
2836 FREE(tmpbuf, M_TEMP);
2837 return (error);
2838}
2 * Copyright (c) 2004-2005 Robert N. M. Watson
3 * Copyright (c) 2004, 2005,
4 * Bosko Milekic <bmilekic@FreeBSD.org>. All rights reserved.
5 * Copyright (c) 2002, 2003, 2004, 2005,
6 * Jeffrey Roberson <jeff@FreeBSD.org>. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
--- 35 unchanged lines hidden (view full) ---
44
45/*
46 * TODO:
47 * - Improve memory usage for large allocations
48 * - Investigate cache size adjustments
49 */
50
51#include <sys/cdefs.h>
52__FBSDID("$FreeBSD: head/sys/vm/uma_core.c 147995 2005-07-14 16:17:21Z rwatson $");
53
54/* I should really use ktr.. */
55/*
56#define UMA_DEBUG 1
57#define UMA_DEBUG_ALLOC 1
58#define UMA_DEBUG_ALLOC_1 1
59*/
60
--- 4 unchanged lines hidden (view full) ---
65#include <sys/types.h>
66#include <sys/queue.h>
67#include <sys/malloc.h>
68#include <sys/ktr.h>
69#include <sys/lock.h>
70#include <sys/sysctl.h>
71#include <sys/mutex.h>
72#include <sys/proc.h>
73#include <sys/smp.h>
74#include <sys/vmmeter.h>
75
76#include <vm/vm.h>
77#include <vm/vm_object.h>
78#include <vm/vm_page.h>
79#include <vm/vm_param.h>
80#include <vm/vm_map.h>
--- 148 unchanged lines hidden (view full) ---
229static void *uma_slab_alloc(uma_zone_t zone, uma_slab_t slab);
230static void zone_drain(uma_zone_t);
231static uma_zone_t uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit,
232 uma_fini fini, int align, u_int16_t flags);
233
234void uma_print_zone(uma_zone_t);
235void uma_print_stats(void);
236static int sysctl_vm_zone(SYSCTL_HANDLER_ARGS);
237
238#ifdef WITNESS
239static int nosleepwithlocks = 1;
240SYSCTL_INT(_debug, OID_AUTO, nosleepwithlocks, CTLFLAG_RW, &nosleepwithlocks,
241 0, "Convert M_WAITOK to M_NOWAIT to avoid lock-held-across-sleep paths");
242#else
243static int nosleepwithlocks = 0;
244SYSCTL_INT(_debug, OID_AUTO, nosleepwithlocks, CTLFLAG_RW, &nosleepwithlocks,
245 0, "Convert M_WAITOK to M_NOWAIT to avoid lock-held-across-sleep paths");
246#endif
247SYSCTL_OID(_vm, OID_AUTO, zone, CTLTYPE_STRING|CTLFLAG_RD,
248 NULL, 0, sysctl_vm_zone, "A", "Zone Info");
249SYSINIT(uma_startup3, SI_SUB_VM_CONF, SI_ORDER_SECOND, uma_startup3, NULL);
250
251/*
252 * This routine checks to see whether or not it's safe to enable buckets.
253 */
254
255static void
256bucket_enable(void)
257{
258 if (cnt.v_free_count < cnt.v_free_min)
--- 2487 unchanged lines hidden (view full) ---
2746 continue;
2747 cache = &zone->uz_cpu[i];
2748 printf("CPU %d Cache:\n", i);
2749 cache_print(cache);
2750 }
2751}
2752
2753/*
2754 * Sysctl handler for vm.zone
2755 *
2756 * stolen from vm_zone.c
2757 */
2758static int
2759sysctl_vm_zone(SYSCTL_HANDLER_ARGS)
2760{
2761 int error, len, cnt;
2762 const int linesize = 128; /* conservative */
2763 int totalfree;
2764 char *tmpbuf, *offset;
2765 uma_zone_t z;
2766 uma_keg_t zk;
2767 char *p;
2768 int cpu;
2769 int cachefree;
2770 uma_bucket_t bucket;
2771 uma_cache_t cache;
2772 u_int64_t alloc;
2773
2774 cnt = 0;
2775 mtx_lock(&uma_mtx);
2776 LIST_FOREACH(zk, &uma_kegs, uk_link) {
2777 LIST_FOREACH(z, &zk->uk_zones, uz_link)
2778 cnt++;
2779 }
2780 mtx_unlock(&uma_mtx);
--- 9 unchanged lines hidden (view full) ---
2790 offset = tmpbuf;
2791 mtx_lock(&uma_mtx);
2792 LIST_FOREACH(zk, &uma_kegs, uk_link) {
2793 LIST_FOREACH(z, &zk->uk_zones, uz_link) {
2794 if (cnt == 0) /* list may have changed size */
2795 break;
2796 ZONE_LOCK(z);
2797 cachefree = 0;
2798 alloc = 0;
2799 if (!(zk->uk_flags & UMA_ZFLAG_INTERNAL)) {
2800 for (cpu = 0; cpu <= mp_maxid; cpu++) {
2801 if (CPU_ABSENT(cpu))
2802 continue;
2803 cache = &z->uz_cpu[cpu];
2804 if (cache->uc_allocbucket != NULL)
2805 cachefree += cache->uc_allocbucket->ub_cnt;
2806 if (cache->uc_freebucket != NULL)
2807 cachefree += cache->uc_freebucket->ub_cnt;
2808 alloc += cache->uc_allocs;
2809 }
2810 }
2811 alloc += z->uz_allocs;
2812
2813 LIST_FOREACH(bucket, &z->uz_full_bucket, ub_link) {
2814 cachefree += bucket->ub_cnt;
2815 }
2816 totalfree = zk->uk_free + cachefree;
2817 len = snprintf(offset, linesize,
2818 "%-12.12s %6.6u, %8.8u, %6.6u, %6.6u, %8.8llu\n",
2819 z->uz_name, zk->uk_size,
2820 zk->uk_maxpages * zk->uk_ipers,
2821 (zk->uk_ipers * (zk->uk_pages / zk->uk_ppera)) - totalfree,
2822 totalfree,
2823 (unsigned long long)alloc);
2824 ZONE_UNLOCK(z);
2825 for (p = offset + 12; p > offset && *p == ' '; --p)
2826 /* nothing */ ;
2827 p[1] = ':';
2828 cnt--;
2829 offset += len;
2830 }
2831 }
2832 mtx_unlock(&uma_mtx);
2833 *offset++ = '\0';
2834 error = SYSCTL_OUT(req, tmpbuf, offset - tmpbuf);
2835out:
2836 FREE(tmpbuf, M_TEMP);
2837 return (error);
2838}