[SSI] openssi/kernel/fs exec.c,1.16,1.17

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/fs
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv754/fs

Modified Files:
      Tag: OPENSSI-FC
	exec.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: exec.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/fs/exec.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- exec.c	13 Mar 2010 10:50:36 -0000	1.16
+++ exec.c	25 Oct 2010 04:53:03 -0000	1.17
@@ -1273,50 +1273,54 @@
 }
 
 #ifdef CONFIG_LDLVL
+#ifdef REXEC_LOADTABLE_FAST
 static inline int
-__ssi_do_execve(char * filename,
-	char __user *__user *argv,
-	char __user *__user *envp,
-	struct pt_regs * regs)
+__ssi_choose_node(void)
 {
-#ifdef REXEC_LOADTABLE_FAST
-	unsigned int start;
-	clusternode_t node;
-static DEFINE_SPINLOCK(execve_ll_sem); /* for rexec_loadtable[0] */
-
-	if (!is_loadlevelable(current, filename))
-		return -EPERM;
-
-	down_read(&rexec_loadtable_sem);
+static clusternode_t node = 0; /* bit in rexec_loadmap */
+static __cacheline_aligned_in_smp DEFINE_SPINLOCK(choose_node_lock);
+	clusternode_t ret;
+	int retry = 0;
 
-	if (!rexec_loadtable[1]) {
-		/* empty set */
-		up_read(&rexec_loadtable_sem);
+again:
+	if (bitmap_empty(rexec_loadmap, NSC_MAX_NODE_VALUE))
 		return -EAGAIN;
-	}
 
-	spin_lock(&execve_ll_sem);
-
-	start = rexec_loadtable[0] & (~0U >> NODESHIFT);
-	node = rexec_loadtable[start];
-
-	/* round-robin "start" element in rexec_loadtable[] array */
-	if (++start > NSC_MAX_NODE_VALUE || !rexec_loadtable[start])
-		start = 1;
+	spin_lock(&choose_node_lock);
+	node = find_next_bit(rexec_loadmap, NSC_MAX_NODE_VALUE, node);
+	if (node >= NSC_MAX_NODE_VALUE)
+		node = find_first_bit(rexec_loadmap, NSC_MAX_NODE_VALUE);
 
-	rexec_loadtable[0] = start | (node << NODESHIFT);
-	spin_unlock(&execve_ll_sem);
+	if (node >= NSC_MAX_NODE_VALUE) {
+		/* Lost race with exec_balance() */
+		spin_unlock(&choose_node_lock);
+		if (unlikely(retry++ > 10)) {
+			printk(KERN_WARNING "%s: pid %d retry limit reached\n",
+				__FUNCTION__, current->pid);
+			return -EBUSY;
+		}
+		goto again;
+	}
 
-	up_read(&rexec_loadtable_sem);
+	/* Round-robin */
+	ret = ++node;
+	if (node == NSC_MAX_NODE_VALUE)
+		node = 0;
+	spin_unlock(&choose_node_lock);
 
 #ifdef DEBUG_LDLVL
 	printk(KERN_DEBUG "%s: pid %d chose node %d\n",
-		__FUNCTION__, current->pid, node);
+		__FUNCTION__, current->pid, ret);
 #endif
-
-	node |= (1 << NODESHIFT); /* rexec_ll */
-	return dvp_rexecve((clusternode_t) node, filename, argv, envp, regs);
-#else /* !REXEC_LOADTABLE_FAST */
+	return ret;
+}
+#else /* REXEC_LOADTABLE_FAST */
+static inline int
+__ssi_do_execve(char * filename,
+	char __user *__user *argv,
+	char __user *__user *envp,
+	struct pt_regs * regs)
+{
 	unsigned int start, end, i;
 #ifdef REXEC_LOADTABLE_RACE_FIX
 static DECLARE_MUTEX(execve_ll_sem); /* for rexec_loadtable[0] */
@@ -1385,8 +1389,8 @@
 	up(&execve_ll_sem);
 	up_read(&rexec_loadtable_sem);
 	return -EAGAIN;
-#endif /* !REXEC_LOADTABLE_FAST */
 }
+#endif /* !REXEC_LOADTABLE_FAST */
 #endif /* CONFIG_LDLVL */
 
 int ssi_do_execve(char *filename,
@@ -1403,14 +1407,38 @@
 
 #ifdef CONFIG_SSI
 #ifdef CONFIG_LDLVL
-	/* First reset pvp_loadlevel */
-	(void) is_loadlevelable(current, filename);
+#ifdef REXEC_LOADTABLE_FAST
+	if (remote_okay && !current->execnode && atomic_read(&loadlevel_on)) {
+		/* First reset pvp_loadlevel */
+		(void) is_loadlevelable(current, filename);
+
+		if (!is_loadlevelable(current, filename))
+			goto local_execve;
+
+		do {
+			clusternode_t node;
+
+			retval = __ssi_choose_node();
+			if (retval < 0)
+				break;
 
+			node = retval | (1 << NODESHIFT); /* rexec_ll */
+			retval = dvp_rexecve(node, filename, argv, envp, regs);
+			if (!retval)
+				goto out_ret;
+		} while (retval == -EREMOTE);
+	}
+local_execve:
+#else
 	if (remote_okay && !current->execnode && atomic_read(&loadlevel_on)) {
+		/* First reset pvp_loadlevel */
+		(void) is_loadlevelable(current, filename);
+
 		retval = __ssi_do_execve(filename, argv, envp, regs);
 		if (!retval)
 			goto out_ret;
 	}
+#endif /* !REXEC_LOADTABLE_FAST */
 #endif /* CONFIG_LDLVL */
 #endif /* CONFIG_SSI */
 


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