[SSI] openssi/kernel/cluster/ssi/mosixll balance.c,1.21,1.22
Roger Tsang <[email protected]> Wed, 15 Dec 2010 07:03:12 +0000
| Newsgroups | gmane.linux.cluster.ssic.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv13700/kernel/cluster/ssi/mosixll
Modified Files:
Tag: OPENSSI-FC
balance.c
Log Message:
- choose: fix race over last_consider field in memory descriptor due to updating this field outside choose_sem semaphore.
- mchoose: fix race over mlast_consider field in memory descriptor. use mchoose_sem semaphore.
- mchoose: move get_jiffies_64() call outside for-loop and tasklist_lock. reduce lock contention.
- altload: return ULONG_MAX instead of hard-coded maximum value of 32-bit long because type long can be 64-bit. altruistic load values probably never go that high or beyond 32-bit range, but is a bug when this happens on 64-bit kernels.
Index: balance.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/balance.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- balance.c 9 Nov 2010 02:46:03 -0000 1.21
+++ balance.c 15 Dec 2010 07:03:10 -0000 1.22
@@ -424,7 +424,7 @@
unsigned long threshold;
if (!speed || !ncpus)
- return 0xffffffff;
+ return ULONG_MAX;
threshold = ((unsigned long)(MF * STD_SPD)) / speed;
@@ -477,17 +477,19 @@
{
struct task_struct *p, *sel = NULL;
unsigned long minload, load, bestload = -1;
- unsigned int priority, lastpri = 0; /* ms */
+ unsigned int consider, last_consider = 0; /* ms */
unsigned int pri, bestpri; /* ms */
cputime_t time;
const unsigned int mintime = 1000; /* 1000ms */
const unsigned int very_mintime = mintime / 3;
static DECLARE_MUTEX(choose_sem);
- if (chosen_for_balance)
- return;
if (down_trylock(&choose_sem))
return;
+ if (chosen_for_balance) {
+ up(&choose_sem);
+ return;
+ }
/* Unlike OpenSSI, Mosix acpuse is always <= (MF * num_online_cpus()) */
bestpri = mintime; /* SSI: skip acpuse */
@@ -524,10 +526,11 @@
time = cputime_add(time, p->signal->cutime);
time = cputime_add(time, p->signal->cstime);
}
- priority = cputime_to_msecs(time);
+ consider = cputime_to_msecs(time);
- priority -= p->mm->last_consider;
- pri = priority < 4000 ? priority : 4000; /* 4000ms */
+ pri = consider - p->mm->last_consider;
+ if (pri > 4000)
+ pri = 4000; /* 4000ms */
task_lock(p);
load = p->mm->load;
@@ -560,33 +563,31 @@
sel = p;
bestload = load;
bestpri = pri;
- lastpri = priority;
+ last_consider = consider;
} else
mmput(p->mm);
}
read_unlock(&tasklist_lock);
- if(!sel) {
+ if (!sel) {
up(&choose_sem);
return;
}
spin_lock(&whereto_lock);
-
- /* Release choose_sem early since
- * mosix_do_add_to_whereto() path might be re-entrant
- */
- up(&choose_sem);
-
- if(chosen_for_balance)
- {
+ if (chosen_for_balance) {
spin_unlock(&whereto_lock);
+ up(&choose_sem);
mmput(sel->mm);
put_task_struct(sel);
return;
}
chosen_for_balance = sel;
- sel->mm->last_consider += lastpri;
+ sel->mm->last_consider = last_consider;
+
+ /* Release choose_sem now that mm->last_consider is updated */
+ up(&choose_sem);
+
mmput(sel->mm);
load_balancing_counter = BALANCING_TIMEOUT;
@@ -596,7 +597,7 @@
#ifdef CONFIG_MOSIX_DEBUG
if(ds_debug & (DSDEB_LOAD|DSDEB_CONSIDER))
printk("selected %s for load-balancing, pri=%d, load=%lu, priority=%d\n",
- desc_mostask(&sel->mosix), (int)bestpri, bestload, (int)lastpri);
+ desc_mostask(&sel->mosix), (int)bestpri, bestload, (int)last_consider);
#endif /* CONFIG_MOSIX_DEBUG */
}
@@ -756,16 +757,22 @@
unsigned long need = (unsigned long)arg;
#ifdef SSI_BALANCE_MEMORY
unsigned long quality, bestquality = 0;
- u64 df, diff = MIN_MCHOOSE_AGAIN / 1000;
+ u64 df, timestamp, diff = MIN_MCHOOSE_AGAIN / 1000;
#else
int quality, bestquality = 0;
int df, diff = MIN_MCHOOSE_AGAIN;
#endif
now_t dff;
struct task_struct *p, *sel = NULL;
+static DECLARE_MUTEX(mchoose_sem);
- if (chosen_for_mdp)
+ if (down_trylock(&mchoose_sem))
return;
+ if (chosen_for_mdp) {
+ up(&mchoose_sem);
+ return;
+ }
+ timestamp = get_jiffies_64();
read_lock(&tasklist_lock);
for_each_process(p) {
@@ -780,7 +787,7 @@
if (!get_task_mm(p))
continue;
- dff = get_jiffies_64() - p->mm->last_mconsider;
+ dff = timestamp - p->mm->last_mconsider;
if (dff)
dff /= HZ;
@@ -804,18 +811,26 @@
mmput(p->mm);
}
read_unlock(&tasklist_lock);
- if(!sel)
+
+ if (!sel) {
+ up(&mchoose_sem);
return;
+ }
spin_lock(&whereto_lock);
if (chosen_for_mdp) {
spin_unlock(&whereto_lock);
+ up(&mchoose_sem);
mmput(sel->mm);
put_task_struct(sel);
return;
}
chosen_for_mdp = sel;
- sel->mm->last_mconsider = get_jiffies_64();
+ sel->mm->last_mconsider = timestamp;
+
+ /* Release mchoose_sem now that last_mconsider is updated */
+ up(&mchoose_sem);
+
mmput(sel->mm);
memory_balancing_counter = BALANCING_TIMEOUT;
------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d