* vm_object_collapse: * * Collapse an object with the object backing it. * Pages in the backing object are moved into the * parent, and the backing object is deallocated. */
| 1898 | * parent, and the backing object is deallocated. |
| 1899 | */ |
| 1900 | void |
| 1901 | vm_object_collapse(vm_object_t object) |
| 1902 | { |
| 1903 | vm_object_t backing_object, new_backing_object; |
| 1904 | |
| 1905 | VM_OBJECT_ASSERT_WLOCKED(object); |
| 1906 | |
| 1907 | while (TRUE) { |
| 1908 | KASSERT((object->flags & (OBJ_DEAD | OBJ_ANON)) == OBJ_ANON, |
| 1909 | ("collapsing invalid object")); |
| 1910 | |
| 1911 | /* |
| 1912 | * Wait for the backing_object to finish any pending |
| 1913 | * collapse so that the caller sees the shortest possible |
| 1914 | * shadow chain. |
| 1915 | */ |
| 1916 | backing_object = vm_object_backing_collapse_wait(object); |
| 1917 | if (backing_object == NULL) |
| 1918 | return; |
| 1919 | |
| 1920 | KASSERT(object->ref_count > 0 && |
| 1921 | object->ref_count > object->shadow_count, |
| 1922 | ("collapse with invalid ref %d or shadow %d count.", |
| 1923 | object->ref_count, object->shadow_count)); |
| 1924 | KASSERT((backing_object->flags & |
| 1925 | (OBJ_COLLAPSING | OBJ_DEAD)) == 0, |
| 1926 | ("vm_object_collapse: Backing object already collapsing.")); |
| 1927 | KASSERT((object->flags & (OBJ_COLLAPSING | OBJ_DEAD)) == 0, |
| 1928 | ("vm_object_collapse: object is already collapsing.")); |
| 1929 | |
| 1930 | /* |
| 1931 | * We know that we can either collapse the backing object if |
| 1932 | * the parent is the only reference to it, or (perhaps) have |
| 1933 | * the parent bypass the object if the parent happens to shadow |
| 1934 | * all the resident pages in the entire backing object. |
| 1935 | */ |
| 1936 | if (backing_object->ref_count == 1) { |
| 1937 | KASSERT(backing_object->shadow_count == 1, |
| 1938 | ("vm_object_collapse: shadow_count: %d", |
| 1939 | backing_object->shadow_count)); |
| 1940 | vm_object_pip_add(object, 1); |
| 1941 | vm_object_set_flag(object, OBJ_COLLAPSING); |
| 1942 | vm_object_pip_add(backing_object, 1); |
| 1943 | vm_object_set_flag(backing_object, OBJ_DEAD); |
| 1944 | |
| 1945 | /* |
| 1946 | * If there is exactly one reference to the backing |
| 1947 | * object, we can collapse it into the parent. |
| 1948 | */ |
| 1949 | vm_object_collapse_scan(object); |
| 1950 | |
| 1951 | #if VM_NRESERVLEVEL > 0 |
| 1952 | /* |
| 1953 | * Break any reservations from backing_object. |
| 1954 | */ |
| 1955 | if (__predict_false(!LIST_EMPTY(&backing_object->rvq))) |
| 1956 | vm_reserv_break_all(backing_object); |
| 1957 | #endif |
no test coverage detected