[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