mm: frontswap: split out __frontswap_unuse_pages
[platform/adaptation/renesas_rcar/renesas_kernel.git] / mm / frontswap.c
index e250255..faa43b7 100644 (file)
@@ -111,7 +111,7 @@ void __frontswap_init(unsigned type)
        if (sis->frontswap_map == NULL)
                return;
        if (frontswap_enabled)
-               (*frontswap_ops.init)(type);
+               frontswap_ops.init(type);
 }
 EXPORT_SYMBOL(__frontswap_init);
 
@@ -134,7 +134,7 @@ int __frontswap_store(struct page *page)
        BUG_ON(sis == NULL);
        if (frontswap_test(sis, offset))
                dup = 1;
-       ret = (*frontswap_ops.store)(type, offset, page);
+       ret = frontswap_ops.store(type, offset, page);
        if (ret == 0) {
                frontswap_set(sis, offset);
                inc_frontswap_succ_stores();
@@ -148,8 +148,9 @@ int __frontswap_store(struct page *page)
                frontswap_clear(sis, offset);
                atomic_dec(&sis->frontswap_pages);
                inc_frontswap_failed_stores();
-       } else
+       } else {
                inc_frontswap_failed_stores();
+       }
        if (frontswap_writethrough_enabled)
                /* report failure so swap also writes to swap device */
                ret = -1;
@@ -173,7 +174,7 @@ int __frontswap_load(struct page *page)
        BUG_ON(!PageLocked(page));
        BUG_ON(sis == NULL);
        if (frontswap_test(sis, offset))
-               ret = (*frontswap_ops.load)(type, offset, page);
+               ret = frontswap_ops.load(type, offset, page);
        if (ret == 0)
                inc_frontswap_loads();
        return ret;
@@ -190,7 +191,7 @@ void __frontswap_invalidate_page(unsigned type, pgoff_t offset)
 
        BUG_ON(sis == NULL);
        if (frontswap_test(sis, offset)) {
-               (*frontswap_ops.invalidate_page)(type, offset);
+               frontswap_ops.invalidate_page(type, offset);
                atomic_dec(&sis->frontswap_pages);
                frontswap_clear(sis, offset);
                inc_frontswap_invalidates();
@@ -209,12 +210,61 @@ void __frontswap_invalidate_area(unsigned type)
        BUG_ON(sis == NULL);
        if (sis->frontswap_map == NULL)
                return;
-       (*frontswap_ops.invalidate_area)(type);
+       frontswap_ops.invalidate_area(type);
        atomic_set(&sis->frontswap_pages, 0);
        memset(sis->frontswap_map, 0, sis->max / sizeof(long));
 }
 EXPORT_SYMBOL(__frontswap_invalidate_area);
 
+static unsigned long __frontswap_curr_pages(void)
+{
+       int type;
+       unsigned long totalpages = 0;
+       struct swap_info_struct *si = NULL;
+
+       assert_spin_locked(&swap_lock);
+       for (type = swap_list.head; type >= 0; type = si->next) {
+               si = swap_info[type];
+               totalpages += atomic_read(&si->frontswap_pages);
+       }
+       return totalpages;
+}
+
+static int __frontswap_unuse_pages(unsigned long total, unsigned long *unused,
+                                       int *swapid)
+{
+       int ret = -EINVAL;
+       struct swap_info_struct *si = NULL;
+       int si_frontswap_pages;
+       unsigned long total_pages_to_unuse = total;
+       unsigned long pages = 0, pages_to_unuse = 0;
+       int type;
+
+       assert_spin_locked(&swap_lock);
+       for (type = swap_list.head; type >= 0; type = si->next) {
+               si = swap_info[type];
+               si_frontswap_pages = atomic_read(&si->frontswap_pages);
+               if (total_pages_to_unuse < si_frontswap_pages) {
+                       pages = pages_to_unuse = total_pages_to_unuse;
+               } else {
+                       pages = si_frontswap_pages;
+                       pages_to_unuse = 0; /* unuse all */
+               }
+               /* ensure there is enough RAM to fetch pages from frontswap */
+               if (security_vm_enough_memory_mm(current->mm, pages)) {
+                       ret = -ENOMEM;
+                       continue;
+               }
+               vm_unacct_memory(pages);
+               *unused = pages_to_unuse;
+               *swapid = type;
+               ret = 0;
+               break;
+       }
+
+       return ret;
+}
+
 /*
  * Frontswap, like a true swap device, may unnecessarily retain pages
  * under certain circumstances; "shrink" frontswap is essentially a
@@ -225,11 +275,9 @@ EXPORT_SYMBOL(__frontswap_invalidate_area);
  */
 void frontswap_shrink(unsigned long target_pages)
 {
-       struct swap_info_struct *si = NULL;
-       int si_frontswap_pages;
        unsigned long total_pages = 0, total_pages_to_unuse;
-       unsigned long pages = 0, pages_to_unuse = 0;
-       int type;
+       unsigned long pages_to_unuse = 0;
+       int type, ret;
        bool locked = false;
 
        /*
@@ -239,30 +287,12 @@ void frontswap_shrink(unsigned long target_pages)
         */
        spin_lock(&swap_lock);
        locked = true;
-       total_pages = 0;
-       for (type = swap_list.head; type >= 0; type = si->next) {
-               si = swap_info[type];
-               total_pages += atomic_read(&si->frontswap_pages);
-       }
+       total_pages = __frontswap_curr_pages();
        if (total_pages <= target_pages)
                goto out;
        total_pages_to_unuse = total_pages - target_pages;
-       for (type = swap_list.head; type >= 0; type = si->next) {
-               si = swap_info[type];
-               si_frontswap_pages = atomic_read(&si->frontswap_pages);
-               if (total_pages_to_unuse < si_frontswap_pages)
-                       pages = pages_to_unuse = total_pages_to_unuse;
-               else {
-                       pages = si_frontswap_pages;
-                       pages_to_unuse = 0; /* unuse all */
-               }
-               /* ensure there is enough RAM to fetch pages from frontswap */
-               if (security_vm_enough_memory_mm(current->mm, pages))
-                       continue;
-               vm_unacct_memory(pages);
-               break;
-       }
-       if (type < 0)
+       ret = __frontswap_unuse_pages(total_pages_to_unuse, &pages_to_unuse, &type);
+       if (ret < 0)
                goto out;
        locked = false;
        spin_unlock(&swap_lock);
@@ -281,16 +311,12 @@ EXPORT_SYMBOL(frontswap_shrink);
  */
 unsigned long frontswap_curr_pages(void)
 {
-       int type;
        unsigned long totalpages = 0;
-       struct swap_info_struct *si = NULL;
 
        spin_lock(&swap_lock);
-       for (type = swap_list.head; type >= 0; type = si->next) {
-               si = swap_info[type];
-               totalpages += atomic_read(&si->frontswap_pages);
-       }
+       totalpages = __frontswap_curr_pages();
        spin_unlock(&swap_lock);
+
        return totalpages;
 }
 EXPORT_SYMBOL(frontswap_curr_pages);