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 --- |