Blame view
mm/thrash.c
1.92 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 |
/* * 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 |
7602bdf2f [PATCH] new schem... |
10 11 12 13 14 15 16 17 |
* * Sep 2006, Ashwin Chaugule <ashwin.chaugule@celunite.com> * Improved algorithm to pass token: * Each task has a priority which is incremented if it contended * for the token in an interval less than its previous attempt. * If the token is acquired, that task's priority is boosted to prevent * the token from bouncing around too often and to let the task make * some progress in its execution. |
1da177e4c Linux-2.6.12-rc2 |
18 |
*/ |
7602bdf2f [PATCH] new schem... |
19 |
|
1da177e4c Linux-2.6.12-rc2 |
20 21 22 23 24 25 |
#include <linux/jiffies.h> #include <linux/mm.h> #include <linux/sched.h> #include <linux/swap.h> static DEFINE_SPINLOCK(swap_token_lock); |
7602bdf2f [PATCH] new schem... |
26 |
struct mm_struct *swap_token_mm; |
e30500557 [PATCH] make mm/t... |
27 |
static unsigned int global_faults; |
1da177e4c Linux-2.6.12-rc2 |
28 |
|
a5c9b696e mm: pass mm to gr... |
29 |
void grab_swap_token(struct mm_struct *mm) |
1da177e4c Linux-2.6.12-rc2 |
30 |
{ |
7602bdf2f [PATCH] new schem... |
31 |
int current_interval; |
1da177e4c Linux-2.6.12-rc2 |
32 |
|
7602bdf2f [PATCH] new schem... |
33 |
global_faults++; |
1da177e4c Linux-2.6.12-rc2 |
34 |
|
a5c9b696e mm: pass mm to gr... |
35 |
current_interval = global_faults - mm->faultstamp; |
1da177e4c Linux-2.6.12-rc2 |
36 |
|
7602bdf2f [PATCH] new schem... |
37 38 |
if (!spin_trylock(&swap_token_lock)) return; |
1da177e4c Linux-2.6.12-rc2 |
39 |
|
7602bdf2f [PATCH] new schem... |
40 41 |
/* First come first served */ if (swap_token_mm == NULL) { |
a5c9b696e mm: pass mm to gr... |
42 43 |
mm->token_priority = mm->token_priority + 2; swap_token_mm = mm; |
7602bdf2f [PATCH] new schem... |
44 45 |
goto out; } |
1da177e4c Linux-2.6.12-rc2 |
46 |
|
a5c9b696e mm: pass mm to gr... |
47 48 49 |
if (mm != swap_token_mm) { if (current_interval < mm->last_interval) mm->token_priority++; |
7602bdf2f [PATCH] new schem... |
50 |
else { |
a5c9b696e mm: pass mm to gr... |
51 52 |
if (likely(mm->token_priority > 0)) mm->token_priority--; |
7602bdf2f [PATCH] new schem... |
53 54 |
} /* Check if we deserve the token */ |
a5c9b696e mm: pass mm to gr... |
55 56 57 |
if (mm->token_priority > swap_token_mm->token_priority) { mm->token_priority += 2; swap_token_mm = mm; |
1da177e4c Linux-2.6.12-rc2 |
58 |
} |
7602bdf2f [PATCH] new schem... |
59 60 |
} else { /* Token holder came in again! */ |
a5c9b696e mm: pass mm to gr... |
61 |
mm->token_priority += 2; |
1da177e4c Linux-2.6.12-rc2 |
62 |
} |
7602bdf2f [PATCH] new schem... |
63 64 |
out: |
a5c9b696e mm: pass mm to gr... |
65 66 |
mm->faultstamp = global_faults; mm->last_interval = current_interval; |
7602bdf2f [PATCH] new schem... |
67 |
spin_unlock(&swap_token_lock); |
1da177e4c Linux-2.6.12-rc2 |
68 69 70 71 72 73 |
} /* Called on process exit. */ void __put_swap_token(struct mm_struct *mm) { spin_lock(&swap_token_lock); |
7602bdf2f [PATCH] new schem... |
74 75 |
if (likely(mm == swap_token_mm)) swap_token_mm = NULL; |
1da177e4c Linux-2.6.12-rc2 |
76 77 |
spin_unlock(&swap_token_lock); } |