K32 Writing Backing Storage

K.3.2.1 Function: swap_writepage() (mm/swapstate.c)

This is the function registered in swap_aops for writing out pages. Its function is pretty simple. First, it calls remove_exclusive_swap_page() to try and free the page. If the page was freed, the page will be unlocked here before returning because no I/O is pending on the page. Otherwise, rw_swap_page() is called to sync the page with backing storage.

24 static int swap_writepage(struct page *page)

26 if (remove_exclusive_swap_page(page)) {

27 UnlockPage(page);

28 return 0;

30 rw_swap_page(WRITE, page);

31 return 0;

26-29 remove_exclusive_swap_page() (See Section K.3.2.2) will reclaim the page from the swap cache if possible. If the page is reclaimed, this unlocks it before returning.

30 Otherwise, the page is still in the swap cache, so this synchronizes it with backing storage by calling rw_swap_page() (See Section K.3.3.1).

K.3.2.2 Function: remove_exclusive_swap_page() (mm/swapfile.c)

This function will try to work out if other processes are sharing this page. If possible, the page will be removed from the swap cache and freed. After it is removed from the swap cache, swap_free() is decremented to indicate that the swap cache is no longer using the slot. The count will instead reflect the number of PTEs that contain a swp_entry_t for this slot.

287 int remove_exclusive_swap_page(struct page *page)

289 int retval;

290 struct swap_info_struct * p;

291 swp_entry_t entry;

293 if (!PageLocked(page))

295 if (!PageSwapCache(page))

296 return 0;

297 if (page_count(page) - !!page->buffers != 2) /* 2: us + cache */

298 return 0;

300 entry.val = page->index;

303 return 0;

305 /* Is the only swap cache user the cache itself? */

308 /* Recheck the page count with the pagecache lock held.. */

309 spin_lock(&pagecache_lock);

310 if (page_count(page) - !!page->buffers == 2) {

311 __delete_from_swap_cache(page);

312 SetPageDirty(page);

315 spin_unlock(&pagecache_lock);

317 swap_info_put(p);

320 block_flushpage(page, 0);

321 swap_free(entry);

322 page_cache_release(page);

325 return retval;

293-294 This operation should only be made with the page locked.

295-296 If the page is not in the swap cache, then there is nothing to do.

297-298 If there are other users of the page, then it cannot be reclaimed, so it returns.

300 The swp_entry_t for the page is stored in page^index as explained in Section 2.5.

301 Gets the swap_info_struct with swap_info_get() (See Section K.2.3.1).

307 If the only user of the swap slot is the swap cache itself (i.e, no process is mapping it), this deletes this page from the swap cache to free the slot. Later, the swap slot usage count will be decremented because the swap cache is no longer using it.

310 If the current user is the only user of this page, it is safe to remove from the swap cache. If another process is sharing it, it must remain here.

311 Deletes from the swap cache.

313 Sets retval to 1 so that the caller knows the page was freed and so that swap_free() (See Section K.2.2.1) will be called to decrement the usage count in the swap_map.

317 Drops the reference to the swap slot that was taken with swap_info_get() (See Section K.2.3.1).

320 The slot is being freed to call block_flushpage() so that all I/O will complete and any buffers associated with the page will be freed.

321 Frees the swap slot with swap_free().

322 Drops the reference to the page.

K.3.2.3 Function: free_swap_and_cache() (mm/swapfile.c)

This function frees an entry from the swap cache and tries to reclaim the page.

Note that this function only applies to the swap cache.

332 void free_swap_and_cache(swp_entry_t entry)

334 struct swap_info_struct * p;

335 struct page *page = NULL;

339 if (swap_entry_free(p, SWP_OFFSET(entry)) == 1)

340 page = find_trylock_page(&swapper_space, entry.val);

341 swap_info_put(p);

344 page_cache_get(page);

345 /* Only cache user (+us), or swap space full? Free it! */

346 if (page_count(page) - !!page->buffers == 2 ||

347 delete_from_swap_cache(page);

348 SetPageDirty(page);

350 UnlockPage(page);

351 page_cache_release(page);

337 Gets the swap_info struct for the requsted entry.

338-342 Presuming the swap area information struct exists, this calls swap_entry_free() to free the swap entry. The page for the entry is then located in the swap cache using find_trylock_page(). Note that the page is returned locked.

341 Drops the reference taken to the swap info struct at line 337.

343-352 If the page was located, then we try to reclaim it.

344 Takes a reference to the page so that it will not be freed prematurely.

346-349 The page is deleted from the swap cache if no processes are mapping the page or if the swap area is more than 50 percent full (checked by vm_swap_full() ).

350 Unlocks the page again.

351 Drops the local reference to the page taken at line 344.

This is the main function used for reading data from backing storage into a page or writing data from a page to backing storage. Which operation it performs depends on the first parameter rw. It is basically a wrapper function around the core function rw_swap_page_base(). This simply enforces that the operations are only performed on pages in the swap cache.

85 void rw_swap_page(int rw, struct page *page)

Was this article helpful?

0 0

Post a comment