aboutsummaryrefslogtreecommitdiffstats
path: root/mm/vmscan.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r--mm/vmscan.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index f713e9f6ac73..548e023c193b 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -33,6 +33,7 @@
33#include <linux/cpuset.h> 33#include <linux/cpuset.h>
34#include <linux/notifier.h> 34#include <linux/notifier.h>
35#include <linux/rwsem.h> 35#include <linux/rwsem.h>
36#include <linux/delay.h>
36 37
37#include <asm/tlbflush.h> 38#include <asm/tlbflush.h>
38#include <asm/div64.h> 39#include <asm/div64.h>
@@ -1784,11 +1785,13 @@ unsigned long shrink_all_memory(unsigned long nr_pages)
1784 pg_data_t *pgdat; 1785 pg_data_t *pgdat;
1785 unsigned long nr_to_free = nr_pages; 1786 unsigned long nr_to_free = nr_pages;
1786 unsigned long ret = 0; 1787 unsigned long ret = 0;
1788 unsigned retry = 2;
1787 struct reclaim_state reclaim_state = { 1789 struct reclaim_state reclaim_state = {
1788 .reclaimed_slab = 0, 1790 .reclaimed_slab = 0,
1789 }; 1791 };
1790 1792
1791 current->reclaim_state = &reclaim_state; 1793 current->reclaim_state = &reclaim_state;
1794repeat:
1792 for_each_pgdat(pgdat) { 1795 for_each_pgdat(pgdat) {
1793 unsigned long freed; 1796 unsigned long freed;
1794 1797
@@ -1798,6 +1801,10 @@ unsigned long shrink_all_memory(unsigned long nr_pages)
1798 if ((long)nr_to_free <= 0) 1801 if ((long)nr_to_free <= 0)
1799 break; 1802 break;
1800 } 1803 }
1804 if (retry-- && ret < nr_pages) {
1805 blk_congestion_wait(WRITE, HZ/5);
1806 goto repeat;
1807 }
1801 current->reclaim_state = NULL; 1808 current->reclaim_state = NULL;
1802 return ret; 1809 return ret;
1803} 1810}