[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