swap: make each swap partition have one address_space
[~shefty/rdma-dev.git] / mm / swap_state.c
index 0cb36fb..8d6644c 100644 (file)
@@ -36,12 +36,12 @@ static struct backing_dev_info swap_backing_dev_info = {
        .capabilities   = BDI_CAP_NO_ACCT_AND_WRITEBACK | BDI_CAP_SWAP_BACKED,
 };
 
-struct address_space swapper_space = {
-       .page_tree      = RADIX_TREE_INIT(GFP_ATOMIC|__GFP_NOWARN),
-       .tree_lock      = __SPIN_LOCK_UNLOCKED(swapper_space.tree_lock),
-       .a_ops          = &swap_aops,
-       .i_mmap_nonlinear = LIST_HEAD_INIT(swapper_space.i_mmap_nonlinear),
-       .backing_dev_info = &swap_backing_dev_info,
+struct address_space swapper_spaces[MAX_SWAPFILES] = {
+       [0 ... MAX_SWAPFILES - 1] = {
+               .page_tree      = RADIX_TREE_INIT(GFP_ATOMIC|__GFP_NOWARN),
+               .a_ops          = &swap_aops,
+               .backing_dev_info = &swap_backing_dev_info,
+       }
 };
 
 #define INC_CACHE_INFO(x)      do { swap_cache_info.x++; } while (0)
@@ -53,9 +53,19 @@ static struct {
        unsigned long find_total;
 } swap_cache_info;
 
+unsigned long total_swapcache_pages(void)
+{
+       int i;
+       unsigned long ret = 0;
+
+       for (i = 0; i < MAX_SWAPFILES; i++)
+               ret += swapper_spaces[i].nrpages;
+       return ret;
+}
+
 void show_swap_cache_info(void)
 {
-       printk("%lu pages in swap cache\n", total_swapcache_pages);
+       printk("%lu pages in swap cache\n", total_swapcache_pages());
        printk("Swap cache stats: add %lu, delete %lu, find %lu/%lu\n",
                swap_cache_info.add_total, swap_cache_info.del_total,
                swap_cache_info.find_success, swap_cache_info.find_total);
@@ -70,6 +80,7 @@ void show_swap_cache_info(void)
 static int __add_to_swap_cache(struct page *page, swp_entry_t entry)
 {
        int error;
+       struct address_space *address_space;
 
        VM_BUG_ON(!PageLocked(page));
        VM_BUG_ON(PageSwapCache(page));
@@ -79,14 +90,16 @@ static int __add_to_swap_cache(struct page *page, swp_entry_t entry)
        SetPageSwapCache(page);
        set_page_private(page, entry.val);
 
-       spin_lock_irq(&swapper_space.tree_lock);
-       error = radix_tree_insert(&swapper_space.page_tree, entry.val, page);
+       address_space = swap_address_space(entry);
+       spin_lock_irq(&address_space->tree_lock);
+       error = radix_tree_insert(&address_space->page_tree,
+                                       entry.val, page);
        if (likely(!error)) {
-               total_swapcache_pages++;
+               address_space->nrpages++;
                __inc_zone_page_state(page, NR_FILE_PAGES);
                INC_CACHE_INFO(add_total);
        }
-       spin_unlock_irq(&swapper_space.tree_lock);
+       spin_unlock_irq(&address_space->tree_lock);
 
        if (unlikely(error)) {
                /*
@@ -122,14 +135,19 @@ int add_to_swap_cache(struct page *page, swp_entry_t entry, gfp_t gfp_mask)
  */
 void __delete_from_swap_cache(struct page *page)
 {
+       swp_entry_t entry;
+       struct address_space *address_space;
+
        VM_BUG_ON(!PageLocked(page));
        VM_BUG_ON(!PageSwapCache(page));
        VM_BUG_ON(PageWriteback(page));
 
-       radix_tree_delete(&swapper_space.page_tree, page_private(page));
+       entry.val = page_private(page);
+       address_space = swap_address_space(entry);
+       radix_tree_delete(&address_space->page_tree, page_private(page));
        set_page_private(page, 0);
        ClearPageSwapCache(page);
-       total_swapcache_pages--;
+       address_space->nrpages--;
        __dec_zone_page_state(page, NR_FILE_PAGES);
        INC_CACHE_INFO(del_total);
 }
@@ -195,12 +213,14 @@ int add_to_swap(struct page *page)
 void delete_from_swap_cache(struct page *page)
 {
        swp_entry_t entry;
+       struct address_space *address_space;
 
        entry.val = page_private(page);
 
-       spin_lock_irq(&swapper_space.tree_lock);
+       address_space = swap_address_space(entry);
+       spin_lock_irq(&address_space->tree_lock);
        __delete_from_swap_cache(page);
-       spin_unlock_irq(&swapper_space.tree_lock);
+       spin_unlock_irq(&address_space->tree_lock);
 
        swapcache_free(entry, page);
        page_cache_release(page);
@@ -263,7 +283,7 @@ struct page * lookup_swap_cache(swp_entry_t entry)
 {
        struct page *page;
 
-       page = find_get_page(&swapper_space, entry.val);
+       page = find_get_page(swap_address_space(entry), entry.val);
 
        if (page)
                INC_CACHE_INFO(find_success);
@@ -290,7 +310,8 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
                 * called after lookup_swap_cache() failed, re-calling
                 * that would confuse statistics.
                 */
-               found_page = find_get_page(&swapper_space, entry.val);
+               found_page = find_get_page(swap_address_space(entry),
+                                       entry.val);
                if (found_page)
                        break;