Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

file 77 lines (67 sloc) 1.967 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
/*
* 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
*
* 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.
*/

#include <linux/jiffies.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/swap.h>

static DEFINE_SPINLOCK(swap_token_lock);
struct mm_struct *swap_token_mm;
static unsigned int global_faults;

void grab_swap_token(struct mm_struct *mm)
{
int current_interval;

global_faults++;

current_interval = global_faults - mm->faultstamp;

if (!spin_trylock(&swap_token_lock))
return;

/* First come first served */
if (swap_token_mm == NULL) {
mm->token_priority = mm->token_priority + 2;
swap_token_mm = mm;
goto out;
}

if (mm != swap_token_mm) {
if (current_interval < mm->last_interval)
mm->token_priority++;
else {
if (likely(mm->token_priority > 0))
mm->token_priority--;
}
/* Check if we deserve the token */
if (mm->token_priority > swap_token_mm->token_priority) {
mm->token_priority += 2;
swap_token_mm = mm;
}
} else {
/* Token holder came in again! */
mm->token_priority += 2;
}

out:
mm->faultstamp = global_faults;
mm->last_interval = current_interval;
spin_unlock(&swap_token_lock);
}

/* Called on process exit. */
void __put_swap_token(struct mm_struct *mm)
{
spin_lock(&swap_token_lock);
if (likely(mm == swap_token_mm))
swap_token_mm = NULL;
spin_unlock(&swap_token_lock);
}
Something went wrong with that request. Please try again.