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

Roger Tsang <[email protected]> Mon, 25 Oct 2010 04:53:05 +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-serv754/cluster/ssi/util

Modified Files:
      Tag: OPENSSI-FC
	load_level.c 
Log Message:
VPROC:
- In ssi_do_execve() optimize away is_loadlevelable() when the chosen node is the current node.

VPROC (#ifdef REXEC_LOADTABLE_FAST):
- In __ssi_do_execve() retry on -EREMOTE. There could be other nodes in cluster that are available.
- Rename __ssi_do_execve() to __ssi_choose_node().
- Convert rexec_loadtable[] array to rexec_loadmap Linux bitmap.
- Do lockless rexec_loadmap update. Reduce contention in exec_balance(), rexecve(2) and execve(2).
- Remove redundant altload() calculations since the results only change during loadinfo_received() or nm_master_send(). Evaluate altload() and store result in altload element in loadinfo structure.

 cluster/ssi/mosixll/balance.c    |   19 +++++
 cluster/ssi/mosixll/load.c       |   13 +++
 cluster/ssi/util/load_level.c    |   78 +++++++++++++----------
 fs/exec.c                        |  102 +++++++++++++++++++------------
 include/cluster/ssi/load_level.h |    7 +-
 5 files changed, 144 insertions(+), 75 deletions(-)


Index: load_level.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/load_level.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- load_level.c	17 Dec 2009 06:43:51 -0000	1.26
+++ load_level.c	25 Oct 2010 04:53:03 -0000	1.27
@@ -71,11 +71,11 @@
 
 #ifdef REXEC_LOADTABLE_RACE_FIX
 #ifdef REXEC_LOADTABLE_FAST
-clusternode_t *rexec_loadtable;
+DECLARE_BITMAP(rexec_loadmap, NSC_MAX_NODE_VALUE);
 #else
 int *rexec_loadtable;
-#endif
 DECLARE_RWSEM(rexec_loadtable_sem);
+#endif
 #else
 int rexec_loadtable[NSC_MAX_NODE_VALUE + 1];
 #endif
@@ -289,10 +289,9 @@
 #endif
 	master_load_array =
 		kzmalloc_nofail(sizeof(*master_load_array) * (NSC_MAX_NODE_VALUE + 1));
-	rexec_loadtable =
-		kzmalloc_nofail(sizeof(*rexec_loadtable) * (NSC_MAX_NODE_VALUE + 1));
+	bitmap_zero(rexec_loadmap, NSC_MAX_NODE_VALUE);
 #ifdef DEBUG_LDLVL
-	printk(KERN_NOTICE "%s: rexec_loadtable 0x%p\n", __FUNCTION__, rexec_loadtable);
+	printk(KERN_NOTICE "%s: rexec_loadmap 0x%p\n", __FUNCTION__, rexec_loadmap);
 #endif
 #endif
 
@@ -320,6 +319,10 @@
 	}
 
 #ifdef CONFIG_MOSIX_LL
+#ifdef REXEC_LOADTABLE_FAST
+	loadinfo[node].altload = 0xffffffff;
+	loadinfo[node].load = 0;
+#endif
 	loadinfo[node].ncpus = cpus;
 	loadinfo[node].speed = calc_speed(cpupwr);
 #ifdef CONFIG_SSI_LOADINFO_RLOAD
@@ -414,6 +417,9 @@
 #else
 	for(i=1; i <= NSC_MAX_NODE_VALUE; i++) {
 #endif
+#ifdef REXEC_LOADTABLE_FAST
+		unsigned long alt_load;
+#endif
 		/* Test: master_load_array[node].node == node */
 		if (i != larray[i].node)
 			continue;
@@ -424,6 +430,9 @@
 #ifdef CONFIG_MOSIX_LL
 		if (i == this_node)
 			continue;
+#ifdef REXEC_LOADTABLE_FAST
+		alt_load = altload(larray[i].load, loadinfo[i].speed, loadinfo[i].ncpus);
+#endif
 #endif /* CONFIG_MOSIX_LL */
 		write_lock_bh(&loadinfo_lock);
 		if (!loadinfo[i].node) {
@@ -433,6 +442,9 @@
 		}
 
 #ifdef CONFIG_MOSIX_LL
+#ifdef REXEC_LOADTABLE_FAST
+		loadinfo[i].altload = alt_load;
+#endif
 #ifdef CONFIG_SSI_LOADINFO_RLOAD
 		loadinfo[i].load = larray[i].load + loadinfo[i].rload;
 #else
@@ -506,11 +518,22 @@
 update_load_array(clusternode_t node, unsigned long *load, unsigned long *mem)
 {
 #ifdef REXEC_LOADTABLE_RACE_FIX
+#ifdef REXEC_LOADTABLE_FAST
+	unsigned long alt_load = 0;
+#endif
+
 	if (unlikely(node > NSC_MAX_NODE_VALUE)) {
 		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) {
@@ -532,6 +555,9 @@
 	/* update loadinfo structure as well */
 #ifdef CONFIG_MOSIX_LL
 	if (node != this_node) {
+#ifdef REXEC_LOADTABLE_FAST
+		loadinfo[node].altload = alt_load;
+#endif
 #ifdef CONFIG_SSI_LOADINFO_RLOAD
 		loadinfo[node].load = *load + loadinfo[node].rload;
 #else
@@ -583,40 +609,19 @@
 exec_balance(void)
 {
         struct loadinfo *l;
-	unsigned long load;
-#ifdef REXEC_LOADTABLE_FAST
-	unsigned int start = 0, i = 1;
-	clusternode_t node;
-
-	/* SSI_ASSERT(NSC_MAX_NODE_VALUE < UINT_MAX); */
-
-	down_write(&rexec_loadtable_sem);
-	node = rexec_loadtable[0] >> NODESHIFT; /* last exec_ll node */
 
+#ifdef REXEC_LOADTABLE_FAST
 	read_lock_bh(&loadinfo_lock);
-	load = altload(export_load, loadinfo[0].speed, loadinfo[0].ncpus);
-
-	for(l = &loadinfo[1]; l <= &loadinfo[NSC_MAX_NODE_VALUE]; l++) {
-		if(l->node && l->node != this_node &&
-		   l->mem > 0 && l->speed &&
-		   altload(l->load, l->speed, l->ncpus) <= load) {
-			rexec_loadtable[i++] = l->node;
-			/* Find "start" position in rexec_loadtable[] for exec_ll */
-			if (!start && l->node > node)
-				start = i - 1;
+	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);
+			else
+				clear_bit(l->node - 1, rexec_loadmap);
 		}
 	}
 	read_unlock_bh(&loadinfo_lock);
-
-	if (i <= NSC_MAX_NODE_VALUE)
-		rexec_loadtable[i] = 0; /* end */
-
-	/* Set "start" position for __ssi_do_execve() */
-	start = start ? : 1;
-	if ((rexec_loadtable[0] & (~0U >> NODESHIFT)) != start)
-		rexec_loadtable[0] = start | (node << NODESHIFT);
-
-	up_write(&rexec_loadtable_sem);
+	smp_mb(); /* ensure all CPU's see rexec_loadmap changes */
 #else /* !REXEC_LOADTABLE_FAST */
 #ifdef REXEC_LOADTABLE_RACE_FIX
 	down_write(&rexec_loadtable_sem);
@@ -686,6 +691,11 @@
 		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


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