summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorRik van Riel <riel@redhat.com>2004-08-22 22:59:16 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-22 22:59:16 -0700
commitd4f9d02b9151b9ff87a950ed42220de4f740d27b (patch)
tree58b215108246a04e922e8cea8cb1d1153950d680 /include/linux
parentf09de30ce99733fc534888ecc12a1c0284524c24 (diff)
[PATCH] token based thrashing control
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 ... Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/sched.h4
-rw-r--r--include/linux/swap.h22
2 files changed, 25 insertions, 1 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 65256f313eb6..a01f849da7a5 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -220,6 +220,10 @@ struct mm_struct {
/* 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;
diff --git a/include/linux/swap.h b/include/linux/swap.h
index b081066b5f11..371e8260c577 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -204,7 +204,6 @@ extern void free_pages_and_swap_cache(struct page **, int);
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/swapfile.c */
extern long total_swap_pages;
extern unsigned int nr_swapfiles;
@@ -229,6 +228,22 @@ extern spinlock_t swaplock;
#define swap_device_lock(p) spin_lock(&p->sdev_lock)
#define swap_device_unlock(p) spin_unlock(&p->sdev_lock)
+/* linux/mm/thrash.c */
+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 total_swap_pages 0
@@ -266,6 +281,11 @@ static inline swp_entry_t get_swap_page(void)
return entry;
}
+/* linux/mm/thrash.c */
+#define put_swap_token(x) do { } while(0)
+#define grab_swap_token() do { } while(0)
+#define has_swap_token(x) 0
+
#endif /* CONFIG_SWAP */
#endif /* __KERNEL__*/
#endif /* _LINUX_SWAP_H */