Lines 1404-1447
keg_free_slab(uma_keg_t keg, uma_slab_t slab, int start)
Link Here
|
1404 |
uma_total_dec(PAGE_SIZE * keg->uk_ppera); |
1404 |
uma_total_dec(PAGE_SIZE * keg->uk_ppera); |
1405 |
} |
1405 |
} |
1406 |
|
1406 |
|
1407 |
/* |
|
|
1408 |
* Frees pages from a keg back to the system. This is done on demand from |
1409 |
* the pageout daemon. |
1410 |
* |
1411 |
* Returns nothing. |
1412 |
*/ |
1413 |
static void |
1407 |
static void |
1414 |
keg_drain(uma_keg_t keg) |
1408 |
keg_drain_domain(uma_keg_t keg, int domain) |
1415 |
{ |
1409 |
{ |
1416 |
struct slabhead freeslabs; |
1410 |
struct slabhead freeslabs; |
1417 |
uma_domain_t dom; |
1411 |
uma_domain_t dom; |
1418 |
uma_slab_t slab, tmp; |
1412 |
uma_slab_t slab, tmp; |
1419 |
int i, n; |
1413 |
int n, skip; |
1420 |
|
1414 |
|
1421 |
if (keg->uk_flags & UMA_ZONE_NOFREE || keg->uk_freef == NULL) |
1415 |
dom = &keg->uk_domain[domain]; |
1422 |
return; |
1416 |
LIST_INIT(&freeslabs); |
1423 |
|
1417 |
|
1424 |
for (i = 0; i < vm_ndomains; i++) { |
1418 |
CTR4(KTR_UMA, "keg_drain %s(%p) domain %d free items: %u", |
1425 |
CTR4(KTR_UMA, "keg_drain %s(%p) domain %d free items: %u", |
1419 |
keg->uk_name, keg, i, dom->ud_free_items); |
1426 |
keg->uk_name, keg, i, dom->ud_free_items); |
|
|
1427 |
dom = &keg->uk_domain[i]; |
1428 |
LIST_INIT(&freeslabs); |
1429 |
|
1420 |
|
1430 |
KEG_LOCK(keg, i); |
1421 |
KEG_LOCK(keg, domain); |
|
|
1422 |
if ((skip = keg->uk_reserve) != 0) { |
1431 |
if ((keg->uk_flags & UMA_ZFLAG_HASH) != 0) { |
1423 |
if ((keg->uk_flags & UMA_ZFLAG_HASH) != 0) { |
1432 |
LIST_FOREACH(slab, &dom->ud_free_slab, us_link) |
1424 |
LIST_FOREACH(slab, &dom->ud_free_slab, us_link) { |
1433 |
UMA_HASH_REMOVE(&keg->uk_hash, slab); |
1425 |
if (skip > 0) |
|
|
1426 |
skip -= keg->uk_ppera; |
1427 |
else |
1428 |
UMA_HASH_REMOVE(&keg->uk_hash, slab); |
1429 |
} |
1430 |
} |
1431 |
} else { |
1432 |
LIST_FOREACH(slab, &dom->ud_free_slab, us_link) |
1433 |
UMA_HASH_REMOVE(&keg->uk_hash, slab); |
1434 |
} |
1435 |
LIST_SWAP(&freeslabs, &dom->ud_free_slab, uma_slab, us_link); |
1436 |
n = dom->ud_free_slabs; |
1437 |
if ((skip = keg->uk_reserve) != 0) { |
1438 |
LIST_FOREACH_SAFE(slab, &freeslabs, us_link, tmp) { |
1439 |
if (skip <= 0) |
1440 |
break; |
1441 |
LIST_REMOVE(slab, us_link); |
1442 |
LIST_INSERT_HEAD(&dom->ud_free_slab, slab, us_link); |
1443 |
skip -= keg->uk_ppera; |
1444 |
n--; |
1434 |
} |
1445 |
} |
1435 |
n = dom->ud_free_slabs; |
|
|
1436 |
LIST_SWAP(&freeslabs, &dom->ud_free_slab, uma_slab, us_link); |
1437 |
dom->ud_free_slabs = 0; |
1438 |
dom->ud_free_items -= n * keg->uk_ipers; |
1439 |
dom->ud_pages -= n * keg->uk_ppera; |
1440 |
KEG_UNLOCK(keg, i); |
1441 |
|
1442 |
LIST_FOREACH_SAFE(slab, &freeslabs, us_link, tmp) |
1443 |
keg_free_slab(keg, slab, keg->uk_ipers); |
1444 |
} |
1446 |
} |
|
|
1447 |
dom->ud_free_slabs -= n; |
1448 |
dom->ud_free_items -= n * keg->uk_ipers; |
1449 |
dom->ud_pages -= n * keg->uk_ppera; |
1450 |
KEG_UNLOCK(keg, domain); |
1451 |
|
1452 |
LIST_FOREACH_SAFE(slab, &freeslabs, us_link, tmp) |
1453 |
keg_free_slab(keg, slab, keg->uk_ipers); |
1454 |
} |
1455 |
|
1456 |
/* |
1457 |
* Frees pages from a keg back to the system. This is done on demand from |
1458 |
* the pageout daemon. |
1459 |
* |
1460 |
* Returns nothing. |
1461 |
*/ |
1462 |
static void |
1463 |
keg_drain(uma_keg_t keg) |
1464 |
{ |
1465 |
int i; |
1466 |
|
1467 |
if ((keg->uk_flags & UMA_ZONE_NOFREE) != 0) |
1468 |
return; |
1469 |
for (i = 0; i < vm_ndomains; i++) |
1470 |
keg_drain_domain(keg, i); |
1445 |
} |
1471 |
} |
1446 |
|
1472 |
|
1447 |
static void |
1473 |
static void |