* swap_pager_swapoff: * * Page in all of the pages that have been paged out to the * given device. The corresponding blocks in the bitmap must be * marked as allocated and the device must be flagged SW_CLOSING. * There may be no processes swapped out to the device. * * This routine may block. */
| 1875 | * This routine may block. |
| 1876 | */ |
| 1877 | static void |
| 1878 | swap_pager_swapoff(struct swdevt *sp) |
| 1879 | { |
| 1880 | vm_object_t object; |
| 1881 | int retries; |
| 1882 | |
| 1883 | sx_assert(&swdev_syscall_lock, SA_XLOCKED); |
| 1884 | |
| 1885 | retries = 0; |
| 1886 | full_rescan: |
| 1887 | mtx_lock(&vm_object_list_mtx); |
| 1888 | TAILQ_FOREACH(object, &vm_object_list, object_list) { |
| 1889 | if (object->type != OBJT_SWAP) |
| 1890 | continue; |
| 1891 | mtx_unlock(&vm_object_list_mtx); |
| 1892 | /* Depends on type-stability. */ |
| 1893 | VM_OBJECT_WLOCK(object); |
| 1894 | |
| 1895 | /* |
| 1896 | * Dead objects are eventually terminated on their own. |
| 1897 | */ |
| 1898 | if ((object->flags & OBJ_DEAD) != 0) |
| 1899 | goto next_obj; |
| 1900 | |
| 1901 | /* |
| 1902 | * Sync with fences placed after pctrie |
| 1903 | * initialization. We must not access pctrie below |
| 1904 | * unless we checked that our object is swap and not |
| 1905 | * dead. |
| 1906 | */ |
| 1907 | atomic_thread_fence_acq(); |
| 1908 | if (object->type != OBJT_SWAP) |
| 1909 | goto next_obj; |
| 1910 | |
| 1911 | swap_pager_swapoff_object(sp, object); |
| 1912 | next_obj: |
| 1913 | VM_OBJECT_WUNLOCK(object); |
| 1914 | mtx_lock(&vm_object_list_mtx); |
| 1915 | } |
| 1916 | mtx_unlock(&vm_object_list_mtx); |
| 1917 | |
| 1918 | if (sp->sw_used) { |
| 1919 | /* |
| 1920 | * Objects may be locked or paging to the device being |
| 1921 | * removed, so we will miss their pages and need to |
| 1922 | * make another pass. We have marked this device as |
| 1923 | * SW_CLOSING, so the activity should finish soon. |
| 1924 | */ |
| 1925 | retries++; |
| 1926 | if (retries > 100) { |
| 1927 | panic("swapoff: failed to locate %d swap blocks", |
| 1928 | sp->sw_used); |
| 1929 | } |
| 1930 | pause("swpoff", hz / 20); |
| 1931 | goto full_rescan; |
| 1932 | } |
| 1933 | EVENTHANDLER_INVOKE(swapoff, sp); |
| 1934 | } |
no test coverage detected