[SSI] openssi/kernel/cluster/ssi/util load_level.c,1.29,1.30

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

Modified Files:
      Tag: OPENSSI-FC
	load_level.c 
Log Message:
- Reduce amount of work in interrupt context.
  - Offload mosix_snap_load() to bottom half. Actual work is moved to do_mosix_snap_load().
  - Invoke do_mosix_snap_load() every MF user ticks instead of every system tick.
  - Move mosix_calc_process_loads() back to mosix_calc_load() which runs in process context in OpenSSI.
- Fix compute_freemem() might reset value of exported freemem if below UTIL_TOLERANCE.
- In choose() re-adjust bestpri and mintime values since MF appears to be based on USER_HZ. 2.6.11 kernel HZ is 1000.
- No longer need acpuse_lock since acpuse value is "constant".
- Remove mosix_task->page_allocs. Not used.
- Fix invalid mosix_task->load value due to invalid mosix_task->ran that is calculated from load_ticks which is not reset prior the next mosix_task->ran calculation. In OpenSSI mosix_calc_load() resets load_ticks, but mosix_task->ran is calculated many times in another thread before load_ticks is reset. In this fix we use Linux ctime/stime from task_struct instead of load_ticks.
- Optimize away runqueue lock if possible in mosix_calc_process_loads().
- Change load_left_lock semaphore to spinlock. This lock used to protect other global variables from multiple mosix_calc_load() threads, but we reduced the number of mosix_calc_load() threads to one.
- Fix choose() and consider() skipped system CPU time.
- Fix update_load_array() filling master_load_array after incrementing load_cnt could race with nm_master_send(). When nm_master_send() lost the race CLMS clients would see incorrect ncpus and speed in loadinfo structure.
- Defer Mosix choose() and mchoose() to Linux work queue instead of nsc_async_queue.
- Fix mosix_do_add_to_whereto() race with age_balancing(). If age_balancing() won the race wake_up_mosix() could be using stale task struct which might cause memory corruption.

 cluster/ssi/mosixll/balance.c           |  316 +++++++++++-------------
 cluster/ssi/mosixll/freemem.c           |   15 -
 cluster/ssi/mosixll/info.c              |   17 -
 cluster/ssi/mosixll/kernel.c            |   15 -
 cluster/ssi/mosixll/load.c              |  246 +++++++++---------
 cluster/ssi/util/load_level.c           |   87 ++++--
 include/cluster/ssi/mosixll/balance.h   |    3 
 include/cluster/ssi/mosixll/defs.h      |    4 
 include/cluster/ssi/mosixll/mosixtask.h |    5 
 include/cluster/ssi/mosixll/routines.h  |    1 
 10 files changed, 368 insertions(+), 341 deletions(-)


Index: load_level.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/load_level.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- load_level.c	25 Oct 2010 05:04:28 -0000	1.29
+++ load_level.c	25 Oct 2010 05:50:41 -0000	1.30
@@ -89,7 +89,6 @@
 #ifdef CONFIG_MOSIX_LL
 extern struct loadinfo *loadinfo;
 extern unsigned long calc_speed(unsigned long);
-extern int altload(int, int, int);
 extern void mosix_calc_load(unsigned long);
 int im_ready;
 int loadlvl_enabled = 1;
@@ -490,14 +489,6 @@
 #ifdef CONFIG_MOSIX_LL
 	/* call MOSIX's balancing algorithms */
 	mosix_calc_load(0);
-#ifdef REXEC_LOADTABLE_RACE_FIX
-	if (atomic_read(&load_cnt) > 1 && atomic_read(&loadlevel_on))
-		exec_balance();
-#else
-	if (load_cnt > 1 && atomic_read(&loadlevel_on)) {
-		exec_balance();
-	}
-#endif
 #endif /* CONFIG_MOSIX_LL */
 }
 
@@ -518,6 +509,9 @@
 		return;
 	}
 #endif
+	master_load_array[node].load = *load;
+	master_load_array[node].mem = mem ? *mem : 0;
+
 	if (master_load_array[node].node == 0) {
 		master_load_array[node].node = node;
 #ifdef MASTER_LOAD_ARRAY_SEND_SIZE
@@ -531,9 +525,6 @@
 #endif
 	}
 
-	master_load_array[node].load = *load;
-	master_load_array[node].mem = mem ? *mem : 0;
-
 	/* update loadinfo structure as well */
 #ifdef CONFIG_MOSIX_LL
 	if (node != this_node) {
@@ -558,6 +549,36 @@
 #endif /* !CONFIG_MOSIX_LL */
 }
 
+#ifdef CONFIG_MOSIX_LL
+struct loadinfo_wq {
+	struct work_struct lw_work;
+	load_array_t lw_info[NSC_MAX_NODE_VALUE + 1];
+};
+
+static void loadinfo_received_wq(void *data)
+{
+	struct loadinfo_wq *lw = (struct loadinfo_wq *)data;
+	load_array_t *info = lw->lw_info;
+
+#ifdef REXEC_LOADTABLE_RACE_FIX
+	update_load_info(info);
+#else
+	update_load_info(info, info[0].load);
+#endif
+	free_page((unsigned long)lw);
+
+	/* call MOSIX's balancing algorithms */
+#ifdef REXEC_LOADTABLE_RACE_FIX
+	if (atomic_read(&load_cnt) > 1 && atomic_read(&loadlevel_on)) {
+#else
+	if (load_cnt > 1 && atomic_read(&loadlevel_on)) {
+#endif
+		load_balance();
+		memory_balance();
+	}
+}
+#endif /* CONFIG_MOSIX_LL */
+
 /*
  * Called from ics when a loadinfo packet is received.
  * Dependent nodes only need to update their loadinfo structure.
@@ -566,26 +587,48 @@
 void
 loadinfo_received(load_array_t *info)
 {
+#ifdef CONFIG_MOSIX_LL
+	struct loadinfo_wq *lw;
+	unsigned int len;
+
 	if (this_node == clms_master_node) {
 		update_load_array(info->node, &info->load, &info->mem);
-	} else {
+		return;
+	}
+
+	if (unlikely(!im_ready)) {
 #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 */
+		return;
+	}
+
+	BUG_ON(PAGE_SIZE < sizeof(struct loadinfo_wq));
+
+	/* We would rather skip a few data updates than miss heartbeats */
+	lw = (typeof(lw)) __get_free_page(GFP_KERNEL|__GFP_NORETRY|__GFP_NOWARN);
+	if (!lw)
+		return;
+	(void) (&lw->lw_info[0] == &info[0]);
+	len = min_t(typeof(len), info[0].load, NSC_MAX_NODE_VALUE) + 1;
+	len *= sizeof(*info);
+	memcpy(lw->lw_info, info, len);
+
+	INIT_WORK(&lw->lw_work, loadinfo_received_wq, (void *)lw);
+	if (!schedule_work(&lw->lw_work))
+		free_page((unsigned long)lw);
+#else /* CONFIG_MOSIX_LL */
+	if (this_node == clms_master_node)
+		update_load_array(info->node, &info->load, &info->mem);
+	else
 #ifdef REXEC_LOADTABLE_RACE_FIX
-		if (atomic_read(&load_cnt) > 1 && atomic_read(&loadlevel_on)) {
+		update_load_info(info);
 #else
-		if (load_cnt > 1 && atomic_read(&loadlevel_on)) {
-#endif
-			load_balance();
-			memory_balance();
-		}
+		update_load_info(info, info[0].load);
 #endif
-	}
+#endif /* !CONFIG_MOSIX_LL */
 }
 
 void


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