From: jhigdon@unixconfigs.org
To: linux-kernel@vger.kernel.org
Cc: Rik van Riel <riel@redhat.com>
Subject: Re: [PATCH] token based thrashing control
Date: Fri, 30 Jul 2004 23:35:42 -0400 [thread overview]
Message-ID: <20040731033542.GA1703@linuxfools.org> (raw)
In-Reply-To: <Pine.LNX.4.58.0407301730440.9228@dhcp030.home.surriel.com>
On Fri, Jul 30, 2004 at 05:37:18PM -0400, Rik van Riel wrote:
>
> The following experimental patch implements token based thrashing
> protection, using the algorithm described in:
>
> http://www.cs.wm.edu/~sjiang/token.htm
>
> When there are pageins going on, a task can grab a token, that
> protects the task from pageout (except by itself) until it is
> no longer doing heavy pageins, or until the maximum hold time
> of the token is over.
>
> If the maximum hold time is exceeded, the task isn't eligable
> to hold the token for a while more, since it wasn't doing it
> much good anyway.
>
> I have run a very unscientific benchmark on my system to test
> the effectiveness of the patch, timing how a 230MB two-process
> qsbench run takes, with and without the token thrashing
> protection present.
>
> normal 2.6.8-rc6: 6m45s
> 2.6.8-rc6 + token: 4m24s
>
> This is a quick hack, implemented without having talked to the
> inventor of the algorithm. He's copied on the mail and I suspect
> we'll be able to do better than my quick implementation ...
>
> Please test this patch.
Hello,
I tested this patch on my laptop which is a p2 400 and 128mb of ram.
After loading many applications far more then I usually do (fc2 running gnome2)
the application I currently use tends to be better responsiveness wise.
>
> include/linux/sched.h | 4 ++
> include/linux/swap.h | 21 ++++++++++
> kernel/fork.c | 2 +
> mm/Makefile | 2 -
> mm/filemap.c | 1
> mm/memory.c | 1
> mm/rmap.c | 3 +
> mm/thrash.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 8 files changed, 133 insertions(+), 1 deletion(-)
>
> --- linux-2.6.7/include/linux/swap.h.token 2004-07-30 13:22:17.000000000 -0400
> +++ linux-2.6.7/include/linux/swap.h 2004-07-30 16:39:27.000000000 -0400
> @@ -204,6 +204,27 @@
> extern struct page * lookup_swap_cache(swp_entry_t);
> extern struct page * read_swap_cache_async(swp_entry_t, struct vm_area_struct *vma,
> unsigned long addr);
> +/* linux/mm/thrash.c */
> +#ifdef CONFIG_SWAP
> +extern struct mm_struct * swap_token_mm;
> +extern void grab_swap_token(void);
> +extern void __put_swap_token(struct mm_struct *);
> +
> +static inline int has_swap_token(struct mm_struct * mm)
> +{
> + return (mm == swap_token_mm);
> +}
> +
> +static inline void put_swap_token(struct mm_struct * mm)
> +{
> + if (has_swap_token(mm))
> + __put_swap_token(mm);
> +}
> +#else /* CONFIG_SWAP */
> +#define put_swap_token do { } while(0)
> +#define grab_swap_token do { } while(0)
> +#define has_swap_token 0
> +#endif /* CONFIG_SWAP */
>
> /* linux/mm/swapfile.c */
> extern long total_swap_pages;
> --- linux-2.6.7/include/linux/sched.h.token 2004-07-30 13:22:28.000000000 -0400
> +++ linux-2.6.7/include/linux/sched.h 2004-07-30 13:22:29.000000000 -0400
> @@ -239,6 +239,10 @@
> /* Architecture-specific MM context */
> mm_context_t context;
>
> + /* Token based thrashing protection. */
> + unsigned long swap_token_time;
> + char recent_pagein;
> +
> /* coredumping support */
> int core_waiters;
> struct completion *core_startup_done, core_done;
> --- linux-2.6.7/kernel/fork.c.token 2004-07-30 13:22:27.000000000 -0400
> +++ linux-2.6.7/kernel/fork.c 2004-07-30 13:22:29.000000000 -0400
> @@ -36,6 +36,7 @@
> #include <linux/mount.h>
> #include <linux/audit.h>
> #include <linux/rmap.h>
> +#include <linux/swap.h>
>
> #include <asm/pgtable.h>
> #include <asm/pgalloc.h>
> @@ -463,6 +464,7 @@
> exit_aio(mm);
> exit_mmap(mm);
> mmdrop(mm);
> + put_swap_token(mm);
> }
> }
>
> --- linux-2.6.7/mm/memory.c.token 2004-07-30 13:22:28.000000000 -0400
> +++ linux-2.6.7/mm/memory.c 2004-07-30 13:22:29.000000000 -0400
> @@ -1433,6 +1433,7 @@
> /* Had to read the page from swap area: Major fault */
> ret = VM_FAULT_MAJOR;
> inc_page_state(pgmajfault);
> + grab_swap_token();
> }
>
> mark_page_accessed(page);
> --- linux-2.6.7/mm/filemap.c.token 2004-07-30 13:22:28.000000000 -0400
> +++ linux-2.6.7/mm/filemap.c 2004-07-30 13:22:29.000000000 -0400
> @@ -1195,6 +1195,7 @@
> * effect.
> */
> error = page_cache_read(file, pgoff);
> + grab_swap_token();
>
> /*
> * The page we want has now been added to the page cache.
> --- /dev/null 2003-09-15 09:40:47.000000000 -0400
> +++ linux-2.6.7/mm/thrash.c 2004-07-30 16:55:00.000000000 -0400
> @@ -0,0 +1,100 @@
> +/*
> + * mm/thrash.c
> + *
> + * Copyright (C) 2004, Red Hat, Inc.
> + * Copyright (C) 2004, Rik van Riel <riel@redhat.com>
> + * Released under the GPL, see the file COPYING for details.
> + *
> + * Simple token based thrashing protection, using the algorithm
> + * described in: http://www.cs.wm.edu/~sjiang/token.pdf
> + */
> +#include <linux/jiffies.h>
> +#include <linux/mm.h>
> +#include <linux/sched.h>
> +#include <linux/swap.h>
> +
> +static spinlock_t swap_token_lock = SPIN_LOCK_UNLOCKED;
> +static unsigned long swap_token_timeout;
> +unsigned long swap_token_check;
> +struct mm_struct * swap_token_mm = &init_mm;
> +
> +#define SWAP_TOKEN_CHECK_INTERVAL (HZ * 2)
> +#define SWAP_TOKEN_TIMEOUT (HZ * 300)
> +
> +/*
> + * Take the token away if the process had no page faults
> + * in the last interval, or if it has held the token for
> + * too long.
> + */
> +#define SWAP_TOKEN_ENOUGH_RSS 1
> +#define SWAP_TOKEN_TIMED_OUT 2
> +static int should_release_swap_token(struct mm_struct * mm)
> +{
> + int ret = 0;
> + if (!mm->recent_pagein)
> + ret = SWAP_TOKEN_ENOUGH_RSS;
> + else if (time_after(jiffies, swap_token_timeout))
> + ret = SWAP_TOKEN_TIMED_OUT;
> + mm->recent_pagein = 0;
> + return ret;
> +}
> +
> +/*
> + * Try to grab the swapout protection token. We only try to
> + * grab it once every TOKEN_CHECK_INTERVAL, both to prevent
> + * SMP lock contention and to check that the process that held
> + * the token before is no longer thrashing.
> + */
> +void grab_swap_token(void)
> +{
> + struct mm_struct * mm;
> + int reason;
> +
> + /* We have the token. Let others know we still need it. */
> + if (has_swap_token(current->mm)) {
> + current->mm->recent_pagein = 1;
> + return;
> + }
> +
> + if (time_after(jiffies, swap_token_check)) {
> +
> + /* Can't get swapout protection if we exceed our RSS limit. */
> + // if (current->mm->rss > current->mm->rlimit_rss)
> + // return;
> +
> + /* ... or if we recently held the token. */
> + if (time_before(jiffies, current->mm->swap_token_time))
> + return;
> +
> + if (!spin_trylock(&swap_token_lock))
> + return;
> +
> + swap_token_check = jiffies + SWAP_TOKEN_CHECK_INTERVAL;
> +
> + mm = swap_token_mm;
> + if ((reason = should_release_swap_token(mm))) {
> + unsigned long eligable = jiffies;
> + if (reason == SWAP_TOKEN_TIMED_OUT) {
> + eligable += SWAP_TOKEN_TIMEOUT;
> + }
> + mm->swap_token_time = eligable;
> + swap_token_timeout = jiffies + SWAP_TOKEN_TIMEOUT;
> + swap_token_mm = current->mm;
> + printk("Took swap token, pid %d (%s)\n",
> + current->pid, current->comm);
> + }
> + spin_unlock(&swap_token_lock);
> + }
> + return;
> +}
> +
> +/* Called on process exit. */
> +void __put_swap_token(struct mm_struct * mm)
> +{
> + spin_lock(&swap_token_lock);
> + if (mm == swap_token_mm) {
> + swap_token_mm = &init_mm;
> + swap_token_check = jiffies;
> + }
> + spin_unlock(&swap_token_lock);
> +}
> --- linux-2.6.7/mm/rmap.c.token 2004-07-30 13:22:24.000000000 -0400
> +++ linux-2.6.7/mm/rmap.c 2004-07-30 13:22:29.000000000 -0400
> @@ -230,6 +230,9 @@
> if (ptep_clear_flush_young(vma, address, pte))
> referenced++;
>
> + if (mm != current->mm && has_swap_token(mm))
> + referenced++;
> +
> (*mapcount)--;
>
> out_unmap:
> --- linux-2.6.7/mm/Makefile.token 2004-07-30 13:22:27.000000000 -0400
> +++ linux-2.6.7/mm/Makefile 2004-07-30 13:22:29.000000000 -0400
> @@ -12,7 +12,7 @@
> readahead.o slab.o swap.o truncate.o vmscan.o \
> $(mmu-y)
>
> -obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o
> +obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o
> obj-$(CONFIG_X86_4G) += usercopy.o
> obj-$(CONFIG_HUGETLBFS) += hugetlb.o
> obj-$(CONFIG_NUMA) += mempolicy.o
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo@kvack.org. For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"aart@kvack.org"> aart@kvack.org </a>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
next prev parent reply other threads:[~2004-07-31 4:14 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-07-30 21:37 [PATCH] token based thrashing control Rik van Riel
2004-07-31 3:35 ` jhigdon [this message]
2004-07-31 11:34 ` Nikita Danilov
2004-07-31 11:43 ` Rik van Riel
2004-08-01 11:05 ` Andrew Morton
2004-08-01 11:13 ` Arjan van de Ven
2004-08-01 21:52 ` Rik van Riel
2004-08-01 13:02 ` Rik van Riel
2004-08-01 13:02 ` Rik van Riel
2004-08-02 0:56 ` Andrew Morton
2004-08-02 0:56 ` Andrew Morton
2004-08-02 1:36 ` Rik van Riel
2004-08-02 1:36 ` Rik van Riel
2004-08-02 2:52 ` Con Kolivas
2004-08-02 3:33 ` Rik van Riel
2004-08-02 3:33 ` Rik van Riel
2004-08-02 5:13 ` Con Kolivas
2004-08-02 5:18 ` Con Kolivas
2004-08-03 0:34 ` Song Jiang
2004-08-03 0:34 ` Song Jiang
2004-08-03 1:20 ` Rik van Riel
2004-08-03 1:20 ` Rik van Riel
2004-08-04 4:51 ` Song Jiang
2004-08-04 4:51 ` Song Jiang
2004-08-04 11:30 ` Rik van Riel
2004-08-04 11:30 ` Rik van Riel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040731033542.GA1703@linuxfools.org \
--to=jhigdon@unixconfigs.org \
--cc=linux-kernel@vger.kernel.org \
--cc=riel@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.