View | Details | Raw Unified | Return to bug 248008 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/vm/uma_core.c (-27 / +53 lines)
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

Return to bug 248008