* vm_object_deallocate: * * Release a reference to the specified object, * gained either through a vm_object_allocate * or a vm_object_reference call. When all references * are gone, storage associated with this object * may be relinquished. * * No object may be locked. */
| 615 | * No object may be locked. |
| 616 | */ |
| 617 | void |
| 618 | vm_object_deallocate(vm_object_t object) |
| 619 | { |
| 620 | vm_object_t temp; |
| 621 | bool released; |
| 622 | |
| 623 | while (object != NULL) { |
| 624 | /* |
| 625 | * If the reference count goes to 0 we start calling |
| 626 | * vm_object_terminate() on the object chain. A ref count |
| 627 | * of 1 may be a special case depending on the shadow count |
| 628 | * being 0 or 1. These cases require a write lock on the |
| 629 | * object. |
| 630 | */ |
| 631 | if ((object->flags & OBJ_ANON) == 0) |
| 632 | released = refcount_release_if_gt(&object->ref_count, 1); |
| 633 | else |
| 634 | released = refcount_release_if_gt(&object->ref_count, 2); |
| 635 | if (released) |
| 636 | return; |
| 637 | |
| 638 | if (object->type == OBJT_VNODE) { |
| 639 | VM_OBJECT_RLOCK(object); |
| 640 | if (object->type == OBJT_VNODE) { |
| 641 | vm_object_deallocate_vnode(object); |
| 642 | return; |
| 643 | } |
| 644 | VM_OBJECT_RUNLOCK(object); |
| 645 | } |
| 646 | |
| 647 | VM_OBJECT_WLOCK(object); |
| 648 | KASSERT(object->ref_count > 0, |
| 649 | ("vm_object_deallocate: object deallocated too many times: %d", |
| 650 | object->type)); |
| 651 | |
| 652 | /* |
| 653 | * If this is not the final reference to an anonymous |
| 654 | * object we may need to collapse the shadow chain. |
| 655 | */ |
| 656 | if (!refcount_release(&object->ref_count)) { |
| 657 | if (object->ref_count > 1 || |
| 658 | object->shadow_count == 0) { |
| 659 | if ((object->flags & OBJ_ANON) != 0 && |
| 660 | object->ref_count == 1) |
| 661 | vm_object_set_flag(object, |
| 662 | OBJ_ONEMAPPING); |
| 663 | VM_OBJECT_WUNLOCK(object); |
| 664 | return; |
| 665 | } |
| 666 | |
| 667 | /* Handle collapsing last ref on anonymous objects. */ |
| 668 | object = vm_object_deallocate_anon(object); |
| 669 | continue; |
| 670 | } |
| 671 | |
| 672 | /* |
| 673 | * Handle the final reference to an object. We restart |
| 674 | * the loop with the backing object to avoid recursion. |
no test coverage detected