[SSI] openssi/kernel/cluster/ssi/util load_level.c,1.27,1.28

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/util
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv2173/cluster/ssi/util

Modified Files:
      Tag: OPENSSI-FC
	load_level.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: load_level.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/load_level.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- load_level.c	25 Oct 2010 04:53:03 -0000	1.27
+++ load_level.c	25 Oct 2010 05:01:38 -0000	1.28
@@ -72,6 +72,7 @@
 #ifdef REXEC_LOADTABLE_RACE_FIX
 #ifdef REXEC_LOADTABLE_FAST
 DECLARE_BITMAP(rexec_loadmap, NSC_MAX_NODE_VALUE);
+static DECLARE_MUTEX(rexec_loadmap_sem);
 #else
 int *rexec_loadtable;
 DECLARE_RWSEM(rexec_loadtable_sem);
@@ -300,28 +301,22 @@
 	loadlevel_log_init();
 }
 
+/* No need to hold loadinfo_lock */
 void
 initialize_loadinfo(clusternode_t node, int cpus, unsigned long cpupwr)
 {
-#ifdef REXEC_LOADTABLE_RACE_FIX
-	write_lock_bh(&loadinfo_lock);
-#endif
 	if (this_node == clms_master_node) {
 		loadinfo[node].node = node;
 	} else
-		loadinfo[node].node = 0;
+		SSI_ASSERT(loadinfo[node].node == 0);
 
-	if (!cpus || !cpupwr) {
-#ifdef REXEC_LOADTABLE_RACE_FIX
-		write_unlock_bh(&loadinfo_lock);
-#endif
+	if (!cpus || !cpupwr)
 		return;
-	}
 
 #ifdef CONFIG_MOSIX_LL
 #ifdef REXEC_LOADTABLE_FAST
 	loadinfo[node].altload = 0xffffffff;
-	loadinfo[node].load = 0;
+	/* loadinfo[node].load = 0; */
 #endif
 	loadinfo[node].ncpus = cpus;
 	loadinfo[node].speed = calc_speed(cpupwr);
@@ -332,10 +327,7 @@
 	printk(KERN_NOTICE "%s: node=%d ncpus=%d, speed=%lu\n",
 			__FUNCTION__, node, cpus, loadinfo[node].speed);
 #endif
-#endif
-#ifdef REXEC_LOADTABLE_RACE_FIX
-	write_unlock_bh(&loadinfo_lock);
-#endif
+#endif /* CONFIG_MOSIX_LL */
 }
 
 /*
@@ -363,7 +355,6 @@
 		 * for nodes except myself.  Current node keeps its
 		 * stats in the first entry [0].
 		 */
-		write_lock_bh(&loadinfo_lock);
 		for(i=1; i <= NSC_MAX_NODE_VALUE; i++) {
 			if (i == this_node)
 				continue;
@@ -375,7 +366,6 @@
 					__FUNCTION__, i, loadinfo[i].ncpus, loadinfo[i].speed);
 #endif
 		}
-		write_unlock_bh(&loadinfo_lock);
 		if (this_node != clms_master_node)
 			atomic_inc(&load_cnt);
 		im_ready = 1;
@@ -411,8 +401,9 @@
 
 #ifdef REXEC_LOADTABLE_RACE_FIX
 #ifdef MASTER_LOAD_ARRAY_SEND_SIZE
-	/* for loop bound by master_load_array_max_index */
-	SSI_ASSERT(len <= NSC_MAX_NODE_VALUE);
+	if (len > NSC_MAX_NODE_VALUE)
+		len = NSC_MAX_NODE_VALUE;
+
 	for(i=1; i <= len; i++) {
 #else
 	for(i=1; i <= NSC_MAX_NODE_VALUE; i++) {
@@ -433,8 +424,8 @@
 #ifdef REXEC_LOADTABLE_FAST
 		alt_load = altload(larray[i].load, loadinfo[i].speed, loadinfo[i].ncpus);
 #endif
+		spin_lock(&loadinfo_lock);
 #endif /* CONFIG_MOSIX_LL */
-		write_lock_bh(&loadinfo_lock);
 		if (!loadinfo[i].node) {
 			loadinfo[i].node = i;
 			if (this_node != clms_master_node)
@@ -451,10 +442,10 @@
 		loadinfo[i].load = larray[i].load;
 #endif
 		loadinfo[i].mem = larray[i].mem;
+		spin_unlock(&loadinfo_lock);
 #else
 		loadinfo[i].load = larray[i].load;
 #endif /* CONFIG_MOSIX_LL */
-		write_unlock_bh(&loadinfo_lock);
 	}
 #else /* !REXEC_LOADTABLE_RACE_FIX */
 	n = 0;
@@ -526,15 +517,6 @@
 		printk("%s: node %d too big\n", __FUNCTION__, node);
 		return;
 	}
-
-#ifdef REXEC_LOADTABLE_FAST
-	if (node != this_node) {
-		/* No lock required. See update_load_info() */
-		alt_load = altload(*load,
-				loadinfo[node].speed, loadinfo[node].ncpus);
-	}
-#endif
-	write_lock_bh(&loadinfo_lock);
 #endif
 	if (master_load_array[node].node == 0) {
 		master_load_array[node].node = node;
@@ -556,6 +538,11 @@
 #ifdef CONFIG_MOSIX_LL
 	if (node != this_node) {
 #ifdef REXEC_LOADTABLE_FAST
+		alt_load = altload(*load,
+				loadinfo[node].speed, loadinfo[node].ncpus);
+#endif
+		spin_lock(&loadinfo_lock);
+#ifdef REXEC_LOADTABLE_FAST
 		loadinfo[node].altload = alt_load;
 #endif
 #ifdef CONFIG_SSI_LOADINFO_RLOAD
@@ -564,13 +551,11 @@
 		loadinfo[node].load = *load;
 #endif
 		loadinfo[node].mem = mem ? *mem : 0;
+		spin_unlock(&loadinfo_lock);
 	}
 #else
 	loadinfo[node].load = *load;
 #endif /* !CONFIG_MOSIX_LL */
-#ifdef REXEC_LOADTABLE_RACE_FIX
-	write_unlock_bh(&loadinfo_lock);
-#endif
 }
 
 /*
@@ -583,26 +568,24 @@
 {
 	if (this_node == clms_master_node) {
 		update_load_array(info->node, &info->load, &info->mem);
-#ifdef CONFIG_MOSIX_LL
-		mosix_calc_load(0);
-#endif
-	} else
+	} else {
 #ifdef REXEC_LOADTABLE_RACE_FIX
 		update_load_info(info);
 #else
 		update_load_info(info, info[0].load);
 #endif
 #ifdef CONFIG_MOSIX_LL
-	/* call MOSIX's balancing algorithms */
+		/* call MOSIX's balancing algorithms */
 #ifdef REXEC_LOADTABLE_RACE_FIX
-	if (atomic_read(&load_cnt) > 1 && atomic_read(&loadlevel_on)) {
+		if (atomic_read(&load_cnt) > 1 && atomic_read(&loadlevel_on)) {
 #else
-	if (load_cnt > 1 && atomic_read(&loadlevel_on)) {
+		if (load_cnt > 1 && atomic_read(&loadlevel_on)) {
 #endif
-		load_balance();
-		memory_balance();
-	}
+			load_balance();
+			memory_balance();
+		}
 #endif
+	}
 }
 
 void
@@ -611,23 +594,21 @@
         struct loadinfo *l;
 
 #ifdef REXEC_LOADTABLE_FAST
-	read_lock_bh(&loadinfo_lock);
+	down(&rexec_loadmap_sem);
 	for (l = &loadinfo[1]; l <= &loadinfo[NSC_MAX_NODE_VALUE]; l++) {
 		if (l->node && l->node != this_node) {
 			if (l->mem && l->altload <= loadinfo[0].altload)
-				set_bit(l->node - 1, rexec_loadmap);
+				__set_bit(l->node - 1, rexec_loadmap);
 			else
-				clear_bit(l->node - 1, rexec_loadmap);
+				__clear_bit(l->node - 1, rexec_loadmap);
 		}
 	}
-	read_unlock_bh(&loadinfo_lock);
-	smp_mb(); /* ensure all CPU's see rexec_loadmap changes */
+	up(&rexec_loadmap_sem);
 #else /* !REXEC_LOADTABLE_FAST */
 #ifdef REXEC_LOADTABLE_RACE_FIX
 	down_write(&rexec_loadtable_sem);
 	memset(&rexec_loadtable[1], 0, sizeof(*rexec_loadtable) * NSC_MAX_NODE_VALUE);
 
-	read_lock_bh(&loadinfo_lock);
 	load = altload(export_load, loadinfo[0].speed, loadinfo[0].ncpus);
 #else
 	memset(&rexec_loadtable[1], 0, sizeof(int) * NSC_MAX_NODE_VALUE);
@@ -641,7 +622,6 @@
 		}
 	}
 #ifdef REXEC_LOADTABLE_RACE_FIX
-	read_unlock_bh(&loadinfo_lock);
 	up_write(&rexec_loadtable_sem);
 #endif
 #endif /* !REXEC_LOADTABLE_FAST */
@@ -655,10 +635,7 @@
 cleanup_loadinfo(clusternode_t node)
 {
 #ifdef REXEC_LOADTABLE_RACE_FIX
-	write_lock_bh(&loadinfo_lock);
-#endif
 	if (master_load_array[node].node != 0) {
-#ifdef REXEC_LOADTABLE_RACE_FIX
 		atomic_dec(&load_cnt);
 		master_load_array[node].node = 0;
 #ifdef MASTER_LOAD_ARRAY_SEND_SIZE
@@ -674,10 +651,27 @@
 			SSI_ASSERT(i > 0);
 		}
 #endif
-#else
+	}
+
+	down(&rexec_loadmap_sem);
+
+	spin_lock(&loadinfo_lock);
+	if (loadinfo[node].node != 0) {
+		loadinfo[node].node = 0;
+#ifdef REXEC_LOADTABLE_FAST
+		loadinfo[node].altload = 0xffffffff;
+#endif
+		loadinfo[node].load = 0;
+		loadinfo[node].mem = 0;
+		atomic_dec(&load_cnt);
+		__clear_bit(node - 1, rexec_loadmap);
+	}
+	spin_unlock(&loadinfo_lock);
+	up(&rexec_loadmap_sem);
+#else /* REXEC_LOADTABLE_RACE_FIX */
+	if (master_load_array[node].node != 0) {
 		master_load_array[node].node = 0;
 		load_cnt--;
-#endif /* !REXEC_LOADTABLE_RACE_FIX */
 		loadinfo[node].node = 0;
 		loadinfo[node].load = 0xffffffff;
 		loadinfo[node].mem = 0;
@@ -685,20 +679,9 @@
 	else if (loadinfo[node].node != 0 && (this_node != clms_master_node)) {
 		loadinfo[node].node = 0;
 		loadinfo[node].load = 0;
-#ifdef REXEC_LOADTABLE_RACE_FIX
-		atomic_dec(&load_cnt);
-#else
 		load_cnt--;
-#endif
 	}
-#ifdef REXEC_LOADTABLE_FAST
-	loadinfo[node].altload = 0xffffffff;
-	clear_bit(node - 1, rexec_loadmap);
-	smp_mb();
-#endif
-#ifdef REXEC_LOADTABLE_RACE_FIX
-	write_unlock_bh(&loadinfo_lock);
-#endif
+#endif /* !REXEC_LOADTABLE_RACE_FIX */
 }
 
 /*


------------------------------------------------------------------------------
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