[SSI] openssi/kernel/cluster/ssi/mosixll balance.c, 1.16, 1.17 info.c, 1.11, 1.12 kernel.c, 1.10, 1.11 load.c, 1.10, 1.11
Roger Tsang <[email protected]> Mon, 25 Oct 2010 05:01:40 +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-serv2173/cluster/ssi/mosixll
Modified Files:
Tag: OPENSSI-FC
balance.c info.c kernel.c load.c
Log Message:
MOSIX:
- Do lockless loadinfo[] reads. Reduce contention in various paths.
- Upgrade loadinfo_lock read/write spinlock to spinlock.
- Re-enable interrupts for loadinfo_lock and whereto_lock. OpenSSI does not acquire these locks in interrupt context.
- In memory_balance() allow to kmalloc() to fail. Avoid blocking ics_llunack_daemon.
- Optimize away the for-loop in release_migrations().
cluster/ssi/mosixll/balance.c | 68 ++++++++++++---
cluster/ssi/mosixll/info.c | 38 ++++++--
cluster/ssi/mosixll/kernel.c | 8 -
cluster/ssi/mosixll/load.c | 24 ++---
cluster/ssi/util/load_level.c | 115 +++++++++++---------------
include/cluster/ssi/mosixll/balance.h | 2
6 files changed, 145 insertions(+), 110 deletions(-)
Index: kernel.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/kernel.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- kernel.c 17 Nov 2009 06:09:02 -0000 1.10
+++ kernel.c 25 Oct 2010 05:01:37 -0000 1.11
@@ -129,7 +129,7 @@
}
#endif /* !CONFIG_SSI */
-/* Called with spin_lock_irq on whereto_lock */
+/* Called with spin_lock on whereto_lock */
inline void
mosix_do_add_to_whereto(struct task_struct *p, int w)
{
@@ -137,17 +137,17 @@
if ((w == BALANCE) && (p == chosen_for_mdp)) {
put_task_struct(p);
chosen_for_balance = NULL;
- spin_unlock_irq(&whereto_lock);
+ spin_unlock(&whereto_lock);
return;
}
if ((w == MEMBALANCE) && (p == chosen_for_balance)) {
put_task_struct(p);
chosen_for_mdp = NULL;
- spin_unlock_irq(&whereto_lock);
+ spin_unlock(&whereto_lock);
return;
}
/* Release whereto_lock for VProc context */
- spin_unlock_irq(&whereto_lock);
+ spin_unlock(&whereto_lock);
wake_up_mosix(p);
#else
if(balpriority(p->mosix.whereto) >= balpriority(w))
Index: load.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/load.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- load.c 25 Oct 2010 04:53:03 -0000 1.10
+++ load.c 25 Oct 2010 05:01:37 -0000 1.11
@@ -55,7 +55,6 @@
unsigned long load_left; /* load of processes that just left */
unsigned proc_ticks; /* # of ticks included in for load leveler to run */
-/* SSI: export_load is protected by loadinfo_lock */
unsigned long export_load; /* load reported to other processors */
#else
unsigned load_adder; /* accumulator of `running' every clock tick */
@@ -91,7 +90,7 @@
* spin_lock_irqsave(&snap_load_lock)
* down(&load_left_lock)
* -> write_lock(&acpuse_lock)
- * -> write_lock_bh(&loadinfo_lock)
+ * spin_lock(&loadinfo_lock)
*/
void
mosix_calc_load(unsigned long unused)
@@ -106,8 +105,6 @@
static int display_counter = 0;
#endif
#ifdef REXEC_LOADTABLE_FAST
- unsigned long new_altload;
-
extern int altload(int, int, int);
#endif
@@ -123,7 +120,7 @@
if (ticks == 0)
return;
- /* Protect upper_load, accload */
+ /* Protect load_left, upper_load, accload */
down(&load_left_lock);
ladd = ladd * ((long long)(MF * STD_SPD)) /
@@ -165,14 +162,13 @@
(int)accload, (int)upper_load, (int)ladd, (int)ticks);
}
#endif /* DEBUG */
+ load_left = 0;
+ up(&load_left_lock);
+ spin_lock(&loadinfo_lock);
#ifdef REXEC_LOADTABLE_FAST
- new_altload = altload(new_expload, loadinfo[0].speed, loadinfo[0].ncpus);
-#endif
- write_lock_bh(&loadinfo_lock);
-
-#ifdef REXEC_LOADTABLE_FAST
- loadinfo[0].altload = new_altload;
+ loadinfo[0].altload =
+ altload(new_expload, loadinfo[0].speed, loadinfo[0].ncpus);
#endif
#ifdef CONFIG_SSI_LOADINFO_RLOAD
/* SSI_XXX: newload already factored in load_left - aka. rload */
@@ -181,11 +177,9 @@
loadinfo[0].load = newload;
#endif
loadinfo[0].mem = latest_free_mem;
- export_load = new_expload;
- load_left = 0;
- write_unlock_bh(&loadinfo_lock);
+ spin_unlock(&loadinfo_lock);
- up(&load_left_lock);
+ set_mb(export_load, new_expload);
/* SSI_XXX: Need inc_decays() ? */
age_balancing();
Index: balance.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/balance.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- balance.c 25 Oct 2010 04:53:03 -0000 1.16
+++ balance.c 25 Oct 2010 05:01:37 -0000 1.17
@@ -147,7 +147,11 @@
void
age_balancing(void)
{
+#ifdef CONFIG_SSI
+ spin_lock(&whereto_lock);
+#else
spin_lock_irq(&whereto_lock);
+#endif
if(load_balancing_counter-- == 0 && chosen_for_balance)
{
put_task_struct(chosen_for_balance);
@@ -158,7 +162,11 @@
put_task_struct(chosen_for_mdp);
chosen_for_mdp = NULL;
}
+#ifdef CONFIG_SSI
+ spin_unlock(&whereto_lock);
+#else
spin_unlock_irq(&whereto_lock);
+#endif
}
#ifndef CONFIG_SSI
@@ -465,7 +473,7 @@
* read_lock(&tasklist_lock)
* -> sighand->siglock
* task_lock()
- * spin_lock_irq(&whereto_lock)
+ * spin_lock(&whereto_lock)
*/
void
choose(void)
@@ -561,11 +569,11 @@
if(!sel)
return;
- spin_lock_irq(&whereto_lock);
+ spin_lock(&whereto_lock);
if(chosen_for_balance)
{
- spin_unlock_irq(&whereto_lock);
+ spin_unlock(&whereto_lock);
put_task_struct(sel);
return;
}
@@ -691,7 +699,9 @@
}
#endif /* !CONFIG_SSI */
+#ifndef CONFIG_SSI
/* Acquires read_lock_bh(&loadinfo_lock) */
+#endif
void
load_balance(void)
{
@@ -708,9 +718,9 @@
#ifndef CONFIG_SSI
if(mosadmin_mode_stay)
return;
-#endif
read_lock_bh(&loadinfo_lock);
+#endif
#ifndef REXEC_LOADTABLE_FAST
load = altload(loadinfo[0].load, loadinfo[0].speed, loadinfo[0].ncpus);
#endif
@@ -729,7 +739,9 @@
break;
}
+#ifndef CONFIG_SSI
read_unlock_bh(&loadinfo_lock);
+#endif
if(doit)
#ifdef CONFIG_SSI
/* Avoid stack overflow due to unchoose_me() recursion */
@@ -810,11 +822,19 @@
read_unlock(&tasklist_lock);
if(!sel)
return;
+#ifdef CONFIG_SSI
+ spin_lock(&whereto_lock);
+#else
spin_lock_irq(&whereto_lock);
+#endif
if(chosen_for_mdp)
{
put_task_struct(sel);
+#ifdef CONFIG_SSI
+ spin_unlock(&whereto_lock);
+#else
spin_unlock_irq(&whereto_lock);
+#endif
return;
}
#ifdef CONFIG_SSI
@@ -847,7 +867,9 @@
#endif
}
+#ifndef CONFIG_SSI
/* Acquires read_lock_bh(&loadinfo_lock) */
+#endif
/* Code path may acquire read_lock(&tasklist_lock) */
void
memory_balance(void)
@@ -868,7 +890,9 @@
|| (need = memory_badly_required()) <= 0)
return;
#endif
+#ifndef CONFIG_SSI
read_lock_bh(&loadinfo_lock);
+#endif
for(l = &loadinfo[1]; l < &loadinfo[INFO_WIN] ; l++)
#ifdef CONFIG_SSI
if(l->node && (l->mem > MIN_EXPECTED_PROC_SIZE))
@@ -879,12 +903,14 @@
doit = 1;
break;
}
- read_unlock_bh(&loadinfo_lock);
#ifdef CONFIG_SSI
if(doit) {
unsigned long *arg;
- arg = kmalloc_nofail(sizeof(*arg));
+ arg = kmalloc(sizeof(*arg), GFP_KERNEL);
+ if (!arg)
+ return;
+
*arg = need;
/* Avoid stack overflow due to unchoose_me() recursion */
if (nsc_async_queue(nsc_generic_async_queue,
@@ -893,6 +919,7 @@
printk(KERN_WARNING "Failed to queue mchoose\n");
}
#else
+ read_unlock_bh(&loadinfo_lock);
if(doit)
mchoose(need);
#endif
@@ -938,7 +965,6 @@
#ifdef CONFIG_SSI
/* Locking: this function may acquire ...
- * read_lock_bh(&loadinfo_lock)
* read_lock(&tasklist_lock)
* -> sighand->siglock
* task_lock()
@@ -946,11 +972,10 @@
/* Locking: called functions may acquire...
* down_read(&mm->mmap_sem)
* -> spin_lock(&mm->page_table_lock)
- * write_lock_bh(&loadinfo_lock)
- * -> task_lock()
+ * spin_lock(&loadinfo_lock)
+ * task_lock()
* down(&load_left_lock)
- * spin_lock_irq(&whereto_lock)
- * read_lock_bh(&loadinfo_lock)
+ * spin_lock(&whereto_lock)
* read_lock(&tasklist_lock)
* task_lock()
*/
@@ -973,7 +998,6 @@
unsigned long migpages, aload[MAX_CONSIDERED];
int64_t ms;
int i, n = 0, j, k;
- int depmach = -1;
int remote = (m->dflags & DREMOTE) ? 1 : 0;
if ((m->stay & DSTAY) || !PE || mosadmin_mode_quiet)
@@ -983,9 +1007,11 @@
migpages = run_over_dirty_pages(NULL, 0);
+#ifndef CONFIG_SSI
read_lock_bh(&loadinfo_lock);
+#endif
for(i = 0 ; i < INFO_WIN ; i++)
- if(loadinfo[i].node && loadinfo[i].speed && loadinfo[i].node != depmach
+ if(loadinfo[i].node && loadinfo[i].speed
&& (i == 0 || (loadinfo[i].mem >= migpages)))
{
#ifdef REXEC_LOADTABLE_FAST
@@ -1010,7 +1036,9 @@
}
n++;
}
+#ifndef CONFIG_SSI
read_unlock_bh(&loadinfo_lock);
+#endif
if(n == 0 || (n == 1 && mach[0] == 0))
goto out; /* save time */
@@ -1539,9 +1567,15 @@
}
#endif /* !CONFIG_SSI */
+#ifdef CONFIG_SSI
+/* Acquires spin_lock(&whereto_lock) */
+#else
/* Acquires spin_lock_irq(&whereto_lock) */
+#endif
/* Called functions may acquire...
+#ifndef CONFIG_SSI
* read_lock_bh(&loadinfo_lock)
+#endif
* read_lock(&tasklist_lock)
*/
void
@@ -1563,8 +1597,10 @@
printk("unchoose_me: %s state %ld\n",
desc_mostask(&p->mosix), p->state);
#endif /* CONFIG_MOSIX_DEBUG */
-#endif
+ spin_lock(&whereto_lock);
+#else
spin_lock_irq(&whereto_lock);
+#endif /* !CONFIG_SSI */
if(p == chosen_for_balance)
{
put_task_struct(p);
@@ -1577,7 +1613,11 @@
chosen_for_mdp = NULL;
m = 1;
}
+#ifdef CONFIG_SSI
+ spin_unlock(&whereto_lock);
+#else
spin_unlock_irq(&whereto_lock);
+#endif
if(l)
load_balance();
else if(m)
Index: info.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/info.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- info.c 18 Nov 2009 06:16:53 -0000 1.11
+++ info.c 25 Oct 2010 05:01:37 -0000 1.12
@@ -40,8 +40,7 @@
#endif /* !CONFIG_SSI */
#ifdef CONFIG_SSI
-__cacheline_aligned_in_smp DEFINE_RWLOCK(loadinfo_lock);
-
+__cacheline_aligned_in_smp DEFINE_SPINLOCK(loadinfo_lock);
struct loadinfo *loadinfo;
#else
#if 0
@@ -343,10 +342,12 @@
stable_export = (MF+2) * STD_SPD / (s * num_online_cpus());
if(stable_export == MF * STD_SPD / (s * num_online_cpus()))
stable_export++;
+#ifdef CONFIG_SSI
+ loadinfo[0].speed = s;
+#else
write_lock_bh(&loadinfo_lock);
loadinfo[0].speed = s;
write_unlock_bh(&loadinfo_lock);
-#ifndef CONFIG_SSI
info_update_costs();
info_update_mfscosts();
#endif /* !CONFIG_SSI */
@@ -969,15 +970,23 @@
* further migrations.
*/
/* Locking: will acquire...
+ * task_lock()
+#ifdef CONFIG_SSI
+ * spin_lock(&loadinfo_lock)
+#else
* write_lock_bh(&loadinfo_lock)
- * -> task_lock()
+ * -> task_rq_lock()
+#endif
* down(&load_left_lock)
- * spin_lock_irq(&whereto_lock)
* task_lock()
*/
/* Called functions may acquire...
+#ifdef CONFIG_SSI
+ * spin_lock(&whereto_lock)
+#else
* spin_lock_irq(&whereto_lock)
* read_lock_bh(&loadinfo_lock)
+#endif
* read_lock(&tasklist_lock)
*/
void
@@ -991,7 +1000,7 @@
register struct mosix_task *m = &p->mosix;
#ifdef CONFIG_SSI
unsigned long load;
- int i;
+ unsigned int i;
#else
struct runqueue *rq;
unsigned long flags;
@@ -1004,14 +1013,16 @@
/* Decrease the local load by the load caused by this process,
* to avoid over-migration.
*/
- write_lock_bh(&loadinfo_lock);
#ifdef CONFIG_SSI
task_lock(p);
load = m->load * STD_SPD / 4 / cpuspeed;
task_unlock(p);
load /= num_online_cpus();
+
+ spin_lock(&loadinfo_lock);
#else
+ write_lock_bh(&loadinfo_lock);
rq = task_rq_lock(p, &flags);
load = m->load * STD_SPD / 4 / cpuspeed;
load /= num_online_cpus();
@@ -1032,10 +1043,12 @@
#endif
/* increase the receiver's-load */
- for(i = 1 ; i < INFO_WIN ; i++)
#ifdef CONFIG_SSI
+ i = whereto;
+ BUG_ON(i < 1 || i > NSC_MAX_NODE_VALUE);
if(loadinfo[i].node == whereto)
#else
+ for(i = 1 ; i < INFO_WIN ; i++)
if(loadinfo[i].pe == whereto)
#endif
{
@@ -1058,14 +1071,19 @@
i, whereto, (int)loadinfo[i].load,
(int)loadinfo[i].mem);
#endif
+#ifndef CONFIG_SSI
break;
+#endif
}
+#ifndef CONFIG_SSI
write_unlock_bh(&loadinfo_lock);
-#ifdef CONFIG_SSI
+#else
+ spin_unlock(&loadinfo_lock);
+
down(&load_left_lock);
load_left += load;
up(&load_left_lock);
-#endif
+#endif /* CONFIG_SSI */
#ifdef CONFIG_MOSIX_DEBUG
if((ds_debug & (DSDEB_LOADS|DSDEB_CONSIDER)) && i == INFO_WIN)
printk("release_migrations: Could not adjust machine #%d (not in list)\n", whereto);
------------------------------------------------------------------------------
Nokia and AT&T present the 2010 Calling All Innovators-North America contest
Create new apps & games for the Nokia N8 for consumers in U.S. and Canada
$10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing
Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store
http://p.sf.net/sfu/nokia-dev2dev