Deleted Added
full compact
uma_core.c (295222) uma_core.c (296243)
1/*-
2 * Copyright (c) 2002-2005, 2009, 2013 Jeffrey Roberson <jeff@FreeBSD.org>
3 * Copyright (c) 2004, 2005 Bosko Milekic <bmilekic@FreeBSD.org>
4 * Copyright (c) 2004-2006 Robert N. M. Watson
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 34 unchanged lines hidden (view full) ---

43
44/*
45 * TODO:
46 * - Improve memory usage for large allocations
47 * - Investigate cache size adjustments
48 */
49
50#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2002-2005, 2009, 2013 Jeffrey Roberson <jeff@FreeBSD.org>
3 * Copyright (c) 2004, 2005 Bosko Milekic <bmilekic@FreeBSD.org>
4 * Copyright (c) 2004-2006 Robert N. M. Watson
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 34 unchanged lines hidden (view full) ---

43
44/*
45 * TODO:
46 * - Improve memory usage for large allocations
47 * - Investigate cache size adjustments
48 */
49
50#include <sys/cdefs.h>
51__FBSDID("$FreeBSD: head/sys/vm/uma_core.c 295222 2016-02-03 23:30:17Z glebius $");
51__FBSDID("$FreeBSD: head/sys/vm/uma_core.c 296243 2016-03-01 00:33:32Z glebius $");
52
53/* I should really use ktr.. */
54/*
55#define UMA_DEBUG 1
56#define UMA_DEBUG_ALLOC 1
57#define UMA_DEBUG_ALLOC_1 1
58*/
59

--- 47 unchanged lines hidden (view full) ---

107static struct uma_keg masterkeg;
108static struct uma_zone masterzone_k;
109static struct uma_zone masterzone_z;
110static uma_zone_t kegs = &masterzone_k;
111static uma_zone_t zones = &masterzone_z;
112
113/* This is the zone from which all of uma_slab_t's are allocated. */
114static uma_zone_t slabzone;
52
53/* I should really use ktr.. */
54/*
55#define UMA_DEBUG 1
56#define UMA_DEBUG_ALLOC 1
57#define UMA_DEBUG_ALLOC_1 1
58*/
59

--- 47 unchanged lines hidden (view full) ---

107static struct uma_keg masterkeg;
108static struct uma_zone masterzone_k;
109static struct uma_zone masterzone_z;
110static uma_zone_t kegs = &masterzone_k;
111static uma_zone_t zones = &masterzone_z;
112
113/* This is the zone from which all of uma_slab_t's are allocated. */
114static uma_zone_t slabzone;
115static uma_zone_t slabrefzone; /* With refcounters (for UMA_ZONE_REFCNT) */
116
117/*
118 * The initial hash tables come out of this zone so they can be allocated
119 * prior to malloc coming up.
120 */
121static uma_zone_t hashzone;
122
123/* The boot-time adjusted value for cache line alignment. */

--- 26 unchanged lines hidden (view full) ---

150static struct sx uma_drain_lock;
151
152/* Is the VM done starting up? */
153static int booted = 0;
154#define UMA_STARTUP 1
155#define UMA_STARTUP2 2
156
157/*
115
116/*
117 * The initial hash tables come out of this zone so they can be allocated
118 * prior to malloc coming up.
119 */
120static uma_zone_t hashzone;
121
122/* The boot-time adjusted value for cache line alignment. */

--- 26 unchanged lines hidden (view full) ---

149static struct sx uma_drain_lock;
150
151/* Is the VM done starting up? */
152static int booted = 0;
153#define UMA_STARTUP 1
154#define UMA_STARTUP2 2
155
156/*
158 * Only mbuf clusters use ref zones. Just provide enough references
159 * to support the one user. New code should not use the ref facility.
160 */
161static const u_int uma_max_ipers_ref = PAGE_SIZE / MCLBYTES;
162
163/*
164 * This is the handle used to schedule events that need to happen
165 * outside of the allocation fast path.
166 */
167static struct callout uma_callout;
168#define UMA_TIMEOUT 20 /* Seconds for callout interval. */
169
170/*
171 * This structure is passed as the zone ctor arg so that I don't have to create

--- 774 unchanged lines hidden (view full) ---

946 *
947 * Returns:
948 * The slab that was allocated or NULL if there is no memory and the
949 * caller specified M_NOWAIT.
950 */
951static uma_slab_t
952keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int wait)
953{
157 * This is the handle used to schedule events that need to happen
158 * outside of the allocation fast path.
159 */
160static struct callout uma_callout;
161#define UMA_TIMEOUT 20 /* Seconds for callout interval. */
162
163/*
164 * This structure is passed as the zone ctor arg so that I don't have to create

--- 774 unchanged lines hidden (view full) ---

939 *
940 * Returns:
941 * The slab that was allocated or NULL if there is no memory and the
942 * caller specified M_NOWAIT.
943 */
944static uma_slab_t
945keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int wait)
946{
954 uma_slabrefcnt_t slabref;
955 uma_alloc allocf;
956 uma_slab_t slab;
957 uint8_t *mem;
958 uint8_t flags;
959 int i;
960
961 mtx_assert(&keg->uk_lock, MA_OWNED);
962 slab = NULL;

--- 46 unchanged lines hidden (view full) ---

1009 slab->us_keg = keg;
1010 slab->us_data = mem;
1011 slab->us_freecount = keg->uk_ipers;
1012 slab->us_flags = flags;
1013 BIT_FILL(SLAB_SETSIZE, &slab->us_free);
1014#ifdef INVARIANTS
1015 BIT_ZERO(SLAB_SETSIZE, &slab->us_debugfree);
1016#endif
947 uma_alloc allocf;
948 uma_slab_t slab;
949 uint8_t *mem;
950 uint8_t flags;
951 int i;
952
953 mtx_assert(&keg->uk_lock, MA_OWNED);
954 slab = NULL;

--- 46 unchanged lines hidden (view full) ---

1001 slab->us_keg = keg;
1002 slab->us_data = mem;
1003 slab->us_freecount = keg->uk_ipers;
1004 slab->us_flags = flags;
1005 BIT_FILL(SLAB_SETSIZE, &slab->us_free);
1006#ifdef INVARIANTS
1007 BIT_ZERO(SLAB_SETSIZE, &slab->us_debugfree);
1008#endif
1017 if (keg->uk_flags & UMA_ZONE_REFCNT) {
1018 slabref = (uma_slabrefcnt_t)slab;
1019 for (i = 0; i < keg->uk_ipers; i++)
1020 slabref->us_refcnt[i] = 0;
1021 }
1022
1023 if (keg->uk_init != NULL) {
1024 for (i = 0; i < keg->uk_ipers; i++)
1025 if (keg->uk_init(slab->us_data + (keg->uk_rsize * i),
1026 keg->uk_size, wait) != 0)
1027 break;
1028 if (i != keg->uk_ipers) {
1029 keg_free_slab(keg, slab, i);

--- 231 unchanged lines hidden (view full) ---

1261 if (rsize & keg->uk_align)
1262 rsize = (rsize & ~keg->uk_align) + (keg->uk_align + 1);
1263 keg->uk_rsize = rsize;
1264
1265 KASSERT((keg->uk_flags & UMA_ZONE_PCPU) == 0 ||
1266 keg->uk_rsize < sizeof(struct pcpu),
1267 ("%s: size %u too large", __func__, keg->uk_rsize));
1268
1009
1010 if (keg->uk_init != NULL) {
1011 for (i = 0; i < keg->uk_ipers; i++)
1012 if (keg->uk_init(slab->us_data + (keg->uk_rsize * i),
1013 keg->uk_size, wait) != 0)
1014 break;
1015 if (i != keg->uk_ipers) {
1016 keg_free_slab(keg, slab, i);

--- 231 unchanged lines hidden (view full) ---

1248 if (rsize & keg->uk_align)
1249 rsize = (rsize & ~keg->uk_align) + (keg->uk_align + 1);
1250 keg->uk_rsize = rsize;
1251
1252 KASSERT((keg->uk_flags & UMA_ZONE_PCPU) == 0 ||
1253 keg->uk_rsize < sizeof(struct pcpu),
1254 ("%s: size %u too large", __func__, keg->uk_rsize));
1255
1269 if (keg->uk_flags & UMA_ZONE_REFCNT)
1270 rsize += sizeof(uint32_t);
1271
1272 if (keg->uk_flags & UMA_ZONE_OFFPAGE)
1273 shsize = 0;
1274 else
1275 shsize = sizeof(struct uma_slab);
1276
1277 keg->uk_ipers = (keg->uk_slabsize - shsize) / rsize;
1278 KASSERT(keg->uk_ipers > 0 && keg->uk_ipers <= SLAB_SETSIZE,
1279 ("%s: keg->uk_ipers %u", __func__, keg->uk_ipers));

--- 71 unchanged lines hidden (view full) ---

1351
1352 /* We can't do OFFPAGE if we're internal, bail out here. */
1353 if (keg->uk_flags & UMA_ZFLAG_INTERNAL)
1354 return;
1355
1356 /* Check whether we have enough space to not do OFFPAGE. */
1357 if ((keg->uk_flags & UMA_ZONE_OFFPAGE) == 0) {
1358 shsize = sizeof(struct uma_slab);
1256 if (keg->uk_flags & UMA_ZONE_OFFPAGE)
1257 shsize = 0;
1258 else
1259 shsize = sizeof(struct uma_slab);
1260
1261 keg->uk_ipers = (keg->uk_slabsize - shsize) / rsize;
1262 KASSERT(keg->uk_ipers > 0 && keg->uk_ipers <= SLAB_SETSIZE,
1263 ("%s: keg->uk_ipers %u", __func__, keg->uk_ipers));

--- 71 unchanged lines hidden (view full) ---

1335
1336 /* We can't do OFFPAGE if we're internal, bail out here. */
1337 if (keg->uk_flags & UMA_ZFLAG_INTERNAL)
1338 return;
1339
1340 /* Check whether we have enough space to not do OFFPAGE. */
1341 if ((keg->uk_flags & UMA_ZONE_OFFPAGE) == 0) {
1342 shsize = sizeof(struct uma_slab);
1359 if (keg->uk_flags & UMA_ZONE_REFCNT)
1360 shsize += keg->uk_ipers * sizeof(uint32_t);
1361 if (shsize & UMA_ALIGN_PTR)
1362 shsize = (shsize & ~UMA_ALIGN_PTR) +
1363 (UMA_ALIGN_PTR + 1);
1364
1365 if ((PAGE_SIZE * keg->uk_ppera) - keg->uk_rsize < shsize)
1366 keg->uk_flags |= UMA_ZONE_OFFPAGE;
1367 }
1368

--- 72 unchanged lines hidden (view full) ---

1441 keg->uk_name = zone->uz_name;
1442
1443 if (arg->flags & UMA_ZONE_VM)
1444 keg->uk_flags |= UMA_ZFLAG_CACHEONLY;
1445
1446 if (arg->flags & UMA_ZONE_ZINIT)
1447 keg->uk_init = zero_init;
1448
1343 if (shsize & UMA_ALIGN_PTR)
1344 shsize = (shsize & ~UMA_ALIGN_PTR) +
1345 (UMA_ALIGN_PTR + 1);
1346
1347 if ((PAGE_SIZE * keg->uk_ppera) - keg->uk_rsize < shsize)
1348 keg->uk_flags |= UMA_ZONE_OFFPAGE;
1349 }
1350

--- 72 unchanged lines hidden (view full) ---

1423 keg->uk_name = zone->uz_name;
1424
1425 if (arg->flags & UMA_ZONE_VM)
1426 keg->uk_flags |= UMA_ZFLAG_CACHEONLY;
1427
1428 if (arg->flags & UMA_ZONE_ZINIT)
1429 keg->uk_init = zero_init;
1430
1449 if (arg->flags & UMA_ZONE_REFCNT || arg->flags & UMA_ZONE_MALLOC)
1431 if (arg->flags & UMA_ZONE_MALLOC)
1450 keg->uk_flags |= UMA_ZONE_VTOSLAB;
1451
1452 if (arg->flags & UMA_ZONE_PCPU)
1453#ifdef SMP
1454 keg->uk_flags |= UMA_ZONE_OFFPAGE;
1455#else
1456 keg->uk_flags &= ~UMA_ZONE_PCPU;
1457#endif
1458
1459 if (keg->uk_flags & UMA_ZONE_CACHESPREAD) {
1460 keg_cachespread_init(keg);
1432 keg->uk_flags |= UMA_ZONE_VTOSLAB;
1433
1434 if (arg->flags & UMA_ZONE_PCPU)
1435#ifdef SMP
1436 keg->uk_flags |= UMA_ZONE_OFFPAGE;
1437#else
1438 keg->uk_flags &= ~UMA_ZONE_PCPU;
1439#endif
1440
1441 if (keg->uk_flags & UMA_ZONE_CACHESPREAD) {
1442 keg_cachespread_init(keg);
1461 } else if (keg->uk_flags & UMA_ZONE_REFCNT) {
1462 if (keg->uk_size >
1463 (UMA_SLAB_SIZE - sizeof(struct uma_slab_refcnt) -
1464 sizeof(uint32_t)))
1465 keg_large_init(keg);
1466 else
1467 keg_small_init(keg);
1468 } else {
1469 if (keg->uk_size > (UMA_SLAB_SIZE - sizeof(struct uma_slab)))
1470 keg_large_init(keg);
1471 else
1472 keg_small_init(keg);
1473 }
1474
1443 } else {
1444 if (keg->uk_size > (UMA_SLAB_SIZE - sizeof(struct uma_slab)))
1445 keg_large_init(keg);
1446 else
1447 keg_small_init(keg);
1448 }
1449
1475 if (keg->uk_flags & UMA_ZONE_OFFPAGE) {
1476 if (keg->uk_flags & UMA_ZONE_REFCNT) {
1477 if (keg->uk_ipers > uma_max_ipers_ref)
1478 panic("Too many ref items per zone: %d > %d\n",
1479 keg->uk_ipers, uma_max_ipers_ref);
1480 keg->uk_slabzone = slabrefzone;
1481 } else
1482 keg->uk_slabzone = slabzone;
1483 }
1450 if (keg->uk_flags & UMA_ZONE_OFFPAGE)
1451 keg->uk_slabzone = slabzone;
1484
1485 /*
1486 * If we haven't booted yet we need allocations to go through the
1487 * startup cache until the vm is ready.
1488 */
1489 if (keg->uk_ppera == 1) {
1490#ifdef UMA_MD_SMALL_ALLOC
1491 keg->uk_allocf = uma_small_alloc;

--- 20 unchanged lines hidden (view full) ---

1512 * justified offset into the memory on an ALIGN_PTR boundary.
1513 */
1514 if (!(keg->uk_flags & UMA_ZONE_OFFPAGE)) {
1515 u_int totsize;
1516
1517 /* Size of the slab struct and free list */
1518 totsize = sizeof(struct uma_slab);
1519
1452
1453 /*
1454 * If we haven't booted yet we need allocations to go through the
1455 * startup cache until the vm is ready.
1456 */
1457 if (keg->uk_ppera == 1) {
1458#ifdef UMA_MD_SMALL_ALLOC
1459 keg->uk_allocf = uma_small_alloc;

--- 20 unchanged lines hidden (view full) ---

1480 * justified offset into the memory on an ALIGN_PTR boundary.
1481 */
1482 if (!(keg->uk_flags & UMA_ZONE_OFFPAGE)) {
1483 u_int totsize;
1484
1485 /* Size of the slab struct and free list */
1486 totsize = sizeof(struct uma_slab);
1487
1520 /* Size of the reference counts. */
1521 if (keg->uk_flags & UMA_ZONE_REFCNT)
1522 totsize += keg->uk_ipers * sizeof(uint32_t);
1523
1524 if (totsize & UMA_ALIGN_PTR)
1525 totsize = (totsize & ~UMA_ALIGN_PTR) +
1526 (UMA_ALIGN_PTR + 1);
1527 keg->uk_pgoff = (PAGE_SIZE * keg->uk_ppera) - totsize;
1528
1529 /*
1530 * The only way the following is possible is if with our
1531 * UMA_ALIGN_PTR adjustments we are now bigger than
1532 * UMA_SLAB_SIZE. I haven't checked whether this is
1533 * mathematically possible for all cases, so we make
1534 * sure here anyway.
1535 */
1536 totsize = keg->uk_pgoff + sizeof(struct uma_slab);
1488 if (totsize & UMA_ALIGN_PTR)
1489 totsize = (totsize & ~UMA_ALIGN_PTR) +
1490 (UMA_ALIGN_PTR + 1);
1491 keg->uk_pgoff = (PAGE_SIZE * keg->uk_ppera) - totsize;
1492
1493 /*
1494 * The only way the following is possible is if with our
1495 * UMA_ALIGN_PTR adjustments we are now bigger than
1496 * UMA_SLAB_SIZE. I haven't checked whether this is
1497 * mathematically possible for all cases, so we make
1498 * sure here anyway.
1499 */
1500 totsize = keg->uk_pgoff + sizeof(struct uma_slab);
1537 if (keg->uk_flags & UMA_ZONE_REFCNT)
1538 totsize += keg->uk_ipers * sizeof(uint32_t);
1539 if (totsize > PAGE_SIZE * keg->uk_ppera) {
1540 printf("zone %s ipers %d rsize %d size %d\n",
1541 zone->uz_name, keg->uk_ipers, keg->uk_rsize,
1542 keg->uk_size);
1543 panic("UMA slab won't fit.");
1544 }
1545 }
1546

--- 245 unchanged lines hidden (view full) ---

1792
1793/* Public functions */
1794/* See uma.h */
1795void
1796uma_startup(void *bootmem, int boot_pages)
1797{
1798 struct uma_zctor_args args;
1799 uma_slab_t slab;
1501 if (totsize > PAGE_SIZE * keg->uk_ppera) {
1502 printf("zone %s ipers %d rsize %d size %d\n",
1503 zone->uz_name, keg->uk_ipers, keg->uk_rsize,
1504 keg->uk_size);
1505 panic("UMA slab won't fit.");
1506 }
1507 }
1508

--- 245 unchanged lines hidden (view full) ---

1754
1755/* Public functions */
1756/* See uma.h */
1757void
1758uma_startup(void *bootmem, int boot_pages)
1759{
1760 struct uma_zctor_args args;
1761 uma_slab_t slab;
1800 u_int slabsize;
1801 int i;
1802
1803#ifdef UMA_DEBUG
1804 printf("Creating uma keg headers zone and keg.\n");
1805#endif
1806 rw_init(&uma_rwlock, "UMA lock");
1807
1808 /* "manually" create the initial zone */

--- 42 unchanged lines hidden (view full) ---

1851#endif
1852
1853 /* Now make a zone for slab headers */
1854 slabzone = uma_zcreate("UMA Slabs",
1855 sizeof(struct uma_slab),
1856 NULL, NULL, NULL, NULL,
1857 UMA_ALIGN_PTR, UMA_ZFLAG_INTERNAL);
1858
1762 int i;
1763
1764#ifdef UMA_DEBUG
1765 printf("Creating uma keg headers zone and keg.\n");
1766#endif
1767 rw_init(&uma_rwlock, "UMA lock");
1768
1769 /* "manually" create the initial zone */

--- 42 unchanged lines hidden (view full) ---

1812#endif
1813
1814 /* Now make a zone for slab headers */
1815 slabzone = uma_zcreate("UMA Slabs",
1816 sizeof(struct uma_slab),
1817 NULL, NULL, NULL, NULL,
1818 UMA_ALIGN_PTR, UMA_ZFLAG_INTERNAL);
1819
1859 /*
1860 * We also create a zone for the bigger slabs with reference
1861 * counts in them, to accomodate UMA_ZONE_REFCNT zones.
1862 */
1863 slabsize = sizeof(struct uma_slab_refcnt);
1864 slabsize += uma_max_ipers_ref * sizeof(uint32_t);
1865 slabrefzone = uma_zcreate("UMA RCntSlabs",
1866 slabsize,
1867 NULL, NULL, NULL, NULL,
1868 UMA_ALIGN_PTR,
1869 UMA_ZFLAG_INTERNAL);
1870
1871 hashzone = uma_zcreate("UMA Hash",
1872 sizeof(struct slabhead *) * UMA_HASH_SIZE_INIT,
1873 NULL, NULL, NULL, NULL,
1874 UMA_ALIGN_PTR, UMA_ZFLAG_INTERNAL);
1875
1876 bucket_init();
1877
1878 booted = UMA_STARTUP;

--- 206 unchanged lines hidden (view full) ---

2085 }
2086 /*
2087 * The new master must also use vtoslab().
2088 */
2089 if ((zone->uz_flags & UMA_ZONE_VTOSLAB) != UMA_ZONE_VTOSLAB) {
2090 error = EINVAL;
2091 goto out;
2092 }
1820 hashzone = uma_zcreate("UMA Hash",
1821 sizeof(struct slabhead *) * UMA_HASH_SIZE_INIT,
1822 NULL, NULL, NULL, NULL,
1823 UMA_ALIGN_PTR, UMA_ZFLAG_INTERNAL);
1824
1825 bucket_init();
1826
1827 booted = UMA_STARTUP;

--- 206 unchanged lines hidden (view full) ---

2034 }
2035 /*
2036 * The new master must also use vtoslab().
2037 */
2038 if ((zone->uz_flags & UMA_ZONE_VTOSLAB) != UMA_ZONE_VTOSLAB) {
2039 error = EINVAL;
2040 goto out;
2041 }
2042
2093 /*
2043 /*
2094 * Both must either be refcnt, or not be refcnt.
2095 */
2096 if ((zone->uz_flags & UMA_ZONE_REFCNT) !=
2097 (master->uz_flags & UMA_ZONE_REFCNT)) {
2098 error = EINVAL;
2099 goto out;
2100 }
2101 /*
2102 * The underlying object must be the same size. rsize
2103 * may be different.
2104 */
2105 if (master->uz_size != zone->uz_size) {
2106 error = E2BIG;
2107 goto out;
2108 }
2109 /*

--- 1105 unchanged lines hidden (view full) ---

3215 MPASS(slab->us_keg == keg);
3216 LIST_INSERT_HEAD(&keg->uk_free_slab, slab, us_link);
3217 slabs--;
3218 }
3219 KEG_UNLOCK(keg);
3220}
3221
3222/* See uma.h */
2044 * The underlying object must be the same size. rsize
2045 * may be different.
2046 */
2047 if (master->uz_size != zone->uz_size) {
2048 error = E2BIG;
2049 goto out;
2050 }
2051 /*

--- 1105 unchanged lines hidden (view full) ---

3157 MPASS(slab->us_keg == keg);
3158 LIST_INSERT_HEAD(&keg->uk_free_slab, slab, us_link);
3159 slabs--;
3160 }
3161 KEG_UNLOCK(keg);
3162}
3163
3164/* See uma.h */
3223uint32_t *
3224uma_find_refcnt(uma_zone_t zone, void *item)
3225{
3226 uma_slabrefcnt_t slabref;
3227 uma_slab_t slab;
3228 uma_keg_t keg;
3229 uint32_t *refcnt;
3230 int idx;
3231
3232 slab = vtoslab((vm_offset_t)item & (~UMA_SLAB_MASK));
3233 slabref = (uma_slabrefcnt_t)slab;
3234 keg = slab->us_keg;
3235 KASSERT(keg->uk_flags & UMA_ZONE_REFCNT,
3236 ("uma_find_refcnt(): zone possibly not UMA_ZONE_REFCNT"));
3237 idx = ((uintptr_t)item - (uintptr_t)slab->us_data) / keg->uk_rsize;
3238 refcnt = &slabref->us_refcnt[idx];
3239 return refcnt;
3240}
3241
3242/* See uma.h */
3243static void
3244uma_reclaim_locked(bool kmem_danger)
3245{
3246
3247#ifdef UMA_DEBUG
3248 printf("UMA: vm asked us to release pages!\n");
3249#endif
3250 sx_assert(&uma_drain_lock, SA_XLOCKED);

--- 4 unchanged lines hidden (view full) ---

3255 zone_foreach(zone_drain);
3256 }
3257 /*
3258 * Some slabs may have been freed but this zone will be visited early
3259 * we visit again so that we can free pages that are empty once other
3260 * zones are drained. We have to do the same for buckets.
3261 */
3262 zone_drain(slabzone);
3165static void
3166uma_reclaim_locked(bool kmem_danger)
3167{
3168
3169#ifdef UMA_DEBUG
3170 printf("UMA: vm asked us to release pages!\n");
3171#endif
3172 sx_assert(&uma_drain_lock, SA_XLOCKED);

--- 4 unchanged lines hidden (view full) ---

3177 zone_foreach(zone_drain);
3178 }
3179 /*
3180 * Some slabs may have been freed but this zone will be visited early
3181 * we visit again so that we can free pages that are empty once other
3182 * zones are drained. We have to do the same for buckets.
3183 */
3184 zone_drain(slabzone);
3263 zone_drain(slabrefzone);
3264 bucket_zone_drain();
3265}
3266
3267void
3268uma_reclaim(void)
3269{
3270
3271 sx_xlock(&uma_drain_lock);

--- 498 unchanged lines hidden ---
3185 bucket_zone_drain();
3186}
3187
3188void
3189uma_reclaim(void)
3190{
3191
3192 sx_xlock(&uma_drain_lock);

--- 498 unchanged lines hidden ---