* Reduces the given reservation's population count. If the population count * becomes zero, the reservation is destroyed. Additionally, moves the * reservation to the tail of the partially populated reservation queue if the * population count is non-zero. */
| 445 | * population count is non-zero. |
| 446 | */ |
| 447 | static void |
| 448 | vm_reserv_depopulate(vm_reserv_t rv, int index) |
| 449 | { |
| 450 | struct vm_domain *vmd; |
| 451 | |
| 452 | vm_reserv_assert_locked(rv); |
| 453 | CTR5(KTR_VM, "%s: rv %p object %p popcnt %d inpartpop %d", |
| 454 | __FUNCTION__, rv, rv->object, rv->popcnt, rv->inpartpopq); |
| 455 | KASSERT(rv->object != NULL, |
| 456 | ("vm_reserv_depopulate: reserv %p is free", rv)); |
| 457 | KASSERT(popmap_is_set(rv->popmap, index), |
| 458 | ("vm_reserv_depopulate: reserv %p's popmap[%d] is clear", rv, |
| 459 | index)); |
| 460 | KASSERT(rv->popcnt > 0, |
| 461 | ("vm_reserv_depopulate: reserv %p's popcnt is corrupted", rv)); |
| 462 | KASSERT(rv->domain < vm_ndomains, |
| 463 | ("vm_reserv_depopulate: reserv %p's domain is corrupted %d", |
| 464 | rv, rv->domain)); |
| 465 | if (rv->popcnt == VM_LEVEL_0_NPAGES) { |
| 466 | KASSERT(rv->pages->psind == 1, |
| 467 | ("vm_reserv_depopulate: reserv %p is already demoted", |
| 468 | rv)); |
| 469 | rv->pages->psind = 0; |
| 470 | } |
| 471 | popmap_clear(rv->popmap, index); |
| 472 | rv->popcnt--; |
| 473 | if ((unsigned)(ticks - rv->lasttick) >= PARTPOPSLOP || |
| 474 | rv->popcnt == 0) { |
| 475 | vm_reserv_domain_lock(rv->domain); |
| 476 | if (rv->inpartpopq) { |
| 477 | TAILQ_REMOVE(&vm_rvd[rv->domain].partpop, rv, partpopq); |
| 478 | rv->inpartpopq = FALSE; |
| 479 | } |
| 480 | if (rv->popcnt != 0) { |
| 481 | rv->inpartpopq = TRUE; |
| 482 | TAILQ_INSERT_TAIL(&vm_rvd[rv->domain].partpop, rv, |
| 483 | partpopq); |
| 484 | } |
| 485 | vm_reserv_domain_unlock(rv->domain); |
| 486 | rv->lasttick = ticks; |
| 487 | } |
| 488 | vmd = VM_DOMAIN(rv->domain); |
| 489 | if (rv->popcnt == 0) { |
| 490 | vm_reserv_remove(rv); |
| 491 | vm_domain_free_lock(vmd); |
| 492 | vm_phys_free_pages(rv->pages, VM_LEVEL_0_ORDER); |
| 493 | vm_domain_free_unlock(vmd); |
| 494 | counter_u64_add(vm_reserv_freed, 1); |
| 495 | } |
| 496 | vm_domain_freecnt_inc(vmd, 1); |
| 497 | } |
| 498 | |
| 499 | /* |
| 500 | * Returns the reservation to which the given page might belong. |
no test coverage detected