summaryrefslogtreecommitdiffstats
path: root/mm/vmscan.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r--mm/vmscan.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index b586bce72..884e67150 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -12,7 +12,6 @@
#include <linux/mm.h>
#include <linux/sched.h>
-#include <linux/head.h>
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
#include <linux/errno.h>
@@ -24,6 +23,7 @@
#include <linux/dcache.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
+#include <linux/init.h>
#include <asm/bitops.h>
#include <asm/pgtable.h>
@@ -491,7 +491,7 @@ static int do_try_to_free_page(int gfp_mask)
* may be printed in the middle of another driver's init
* message). It looks very bad when that happens.
*/
-void kswapd_setup(void)
+void __init kswapd_setup(void)
{
int i;
char *revision="$Revision: 1.5 $", *s, *e;
@@ -529,6 +529,20 @@ int kswapd(void *unused)
namings for POSIX.4 realtime scheduling
priorities. */
+ /*
+ * Tell the memory management that we're a "memory allocator",
+ * and that if we need more memory we should get access to it
+ * regardless (see "try_to_free_pages()"). "kswapd" should
+ * never get caught in the normal page freeing logic.
+ *
+ * (Kswapd normally doesn't need memory anyway, but sometimes
+ * you need a small amount of memory in order to be able to
+ * page out something else, and this flag essentially protects
+ * us from recursively trying to free more memory as we're
+ * trying to free the first piece of memory in the first place).
+ */
+ current->flags |= PF_MEMALLOC;
+
init_swap_timer();
add_wait_queue(&kswapd_wait, &wait);
while (1) {
@@ -592,7 +606,7 @@ int try_to_free_pages(unsigned int gfp_mask, int count)
int retval = 1;
lock_kernel();
- if (current->flags & PF_MEMALLOC) {
+ if (!(current->flags & PF_MEMALLOC)) {
current->flags |= PF_MEMALLOC;
do {
retval = do_try_to_free_page(gfp_mask);
@@ -600,7 +614,7 @@ int try_to_free_pages(unsigned int gfp_mask, int count)
break;
count--;
} while (count > 0);
- current->flags &= PF_MEMALLOC;
+ current->flags &= ~PF_MEMALLOC;
}
unlock_kernel();
return retval;