[SSI] openssi/kernel/cluster/ssi/mosixll balance.c, 1.18, 1.19 load.c, 1.12, 1.13

Roger Tsang <[email protected]> Tue, 09 Nov 2010 02:14:05 +0000
Newsgroups gmane.linux.cluster.ssic.cvs
Message-ID <[email protected]>
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv8003/cluster/ssi/mosixll

Modified Files:
      Tag: OPENSSI-FC
	balance.c load.c 
Log Message:
MOSIX:
- consider: don't call kernel_fpu_begin/end(). There are no MMX instructions.
- choose, mchoose: only consider thread group leaders. OpenSSI migrates thread group.
- choose, consider: calculate thread stats at group level. It was removed in previous checkin. Now that we skip non-thread group leaders it is no longer O(n^2).

 cluster/ssi/mosixll/balance.c |   98 ++++++++++++++++++++--------------
 cluster/ssi/mosixll/load.c    |    4 -
 cluster/ssi/util/load_level.c |    4 -
 3 files changed, 61 insertions(+), 45 deletions(-)


Index: load.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/load.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- load.c	25 Oct 2010 05:50:41 -0000	1.12
+++ load.c	9 Nov 2010 02:14:03 -0000	1.13
@@ -134,9 +134,9 @@
 }
 
 /* Locking:
+ * down(&mosix_calc_load_sem)
  * spin_lock_bh(&snap_load_lock)
- * down(&load_left_lock)
- * -> write_lock(&acpuse_lock)
+ * spin_lock(&load_left_lock)
  * spin_lock(&loadinfo_lock)
  */
 void

Index: balance.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/balance.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- balance.c	25 Oct 2010 05:50:41 -0000	1.18
+++ balance.c	9 Nov 2010 02:14:03 -0000	1.19
@@ -495,10 +495,29 @@
 
 	read_lock(&tasklist_lock);
 	for_each_process(p) {
-		if (p->mosix.stay || p == chosen_for_mdp ||
-		    p->execnode || !is_loadlevelable(p, NULL))
+		if (p->mosix.stay || p == chosen_for_mdp)
 			continue;
-		time = cputime_add(p->utime, p->stime);
+		/* Process already migrating */
+		if (p->execnode)
+			continue;
+		/* Skip kernel threads / non-thread group leaders */
+		if (p->mm == NULL || p != p->group_leader)
+			continue;
+		if (!is_loadlevelable(p, NULL))
+			continue;
+
+		time = cputime_zero;
+		/* This block from 2.6.11 fs/proc/array.c:do_task_stat() */
+		{
+			task_t *t = p;
+			/* add up live thread stats at the group level */
+			do {
+				time = cputime_add(time, t->utime);
+				time = cputime_add(time, t->stime);
+				t = next_thread(t);
+			} while (t != p);
+		}
+
 		if (p->signal) {
 			time = cputime_add(time, p->signal->utime);
 			time = cputime_add(time, p->signal->stime);
@@ -684,20 +703,17 @@
 load_balance(void)
 {
 #ifdef CONFIG_SSI
+static DECLARE_WORK(work, choose, NULL);
+	struct loadinfo *l;
 #ifndef REXEC_LOADTABLE_FAST
 	unsigned long load;
-#endif
-	struct loadinfo *l;
-static DECLARE_WORK(work, choose, NULL);
 
-#ifndef REXEC_LOADTABLE_FAST
 	load = altload(loadinfo[0].load, loadinfo[0].speed, loadinfo[0].ncpus);
-#endif
 	for(l = &loadinfo[1]; l < &loadinfo[INFO_WIN] ; l++)
-#ifdef REXEC_LOADTABLE_FAST
-	if (l->node && l->mem && l->altload <= loadinfo[0].altload)
-#else
 	if(l->node && l->mem && altload(l->load, l->speed, l->ncpus) <= load)
+#else
+	for(l = &loadinfo[1]; l < &loadinfo[INFO_WIN] ; l++)
+	if (l->node && l->mem && l->altload <= loadinfo[0].altload)
 #endif
 	{
 		/* Avoid stack overflow due to unchoose_me() recursion */
@@ -714,6 +730,7 @@
 		return;
 
 	read_lock_bh(&loadinfo_lock);
+	load = altload(loadinfo[0].load, loadinfo[0].speed, loadinfo[0].ncpus);
 	for(l = &loadinfo[1]; l < &loadinfo[INFO_WIN] ; l++)
 	if(l->pe && l->mem > 0 && altload(l->load, l->speed, l->ncpus) <= load)
 	{
@@ -741,31 +758,37 @@
 #endif
 	now_t dff;
 	struct task_struct *p, *sel = NULL;
-	register struct mosix_task *m;
 
 	if (chosen_for_mdp)
 		return;
 
 	read_lock(&tasklist_lock);
-	for_each_process(p)
-	if (!((m=&p->mosix)->stay) && p != chosen_for_balance &&
-					is_loadlevelable(p, NULL))
-	{
+	for_each_process(p) {
+		if (p->mosix.stay || p == chosen_for_balance)
+			continue;
+		/* Process already migrating */
+		if (p->execnode)
+			continue;
+		/* Skip kernel threads / non-thread group leaders */
+		if (p->mm == NULL || p != p->group_leader)
+			continue;
+		if (!is_loadlevelable(p, NULL))
+			continue;
+
 		task_lock(p);
-		dff = time_since(m->last_mconsider);
+		dff = time_since(p->mosix.last_mconsider);
 		task_unlock(p);
-		if(dff > MAX_MCHOOSE_AGAIN)
-			df = MAX_MCHOOSE_AGAIN;
-		else
-			df = dff;
+
+		df = min_t(typeof(dff), dff, MAX_MCHOOSE_AGAIN);
 		if(df < diff)
 			continue;
+
 		quality = memory_relief_quality(p, need);
 		if(quality > bestquality || (quality > 0 && df > diff))
                 {
+			get_task_struct(p);
 			if(sel)
 				put_task_struct(sel);
-			get_task_struct(p);
                         sel = p;
                         bestquality = quality;
 			diff = df;
@@ -864,13 +887,13 @@
 memory_balance(void)
 {
 #ifdef CONFIG_SSI
+static DECLARE_WORK(work, mchoose, NULL);
 	struct loadinfo *l;
 #ifdef SSI_BALANCE_MEMORY
 	unsigned long need;
 #else
 	int need;
 #endif
-static DECLARE_WORK(work, mchoose, NULL);
 
 #ifdef SSI_BALANCE_MEMORY
 	if (mosadmin_mode_quiet || !memory_badly_required(&need))
@@ -974,7 +997,6 @@
 #if MAX_CONSIDERED > 127
 #error char is not enough for map
 #endif /*MAX_CONSIDERED*/
-	//struct task_struct *t;
 	struct task_struct *p = current;
 	struct mosix_task *m = &p->mosix;
 	long long tim, costs[MAX_CONSIDERED];
@@ -992,9 +1014,6 @@
 
 	migpages = run_over_dirty_pages(NULL, 0);
 
-#ifndef CONFIG_SSI
-	read_lock_bh(&loadinfo_lock);
-#endif
 	for(i = 0 ; i < INFO_WIN ; i++)
 	if(loadinfo[i].node && loadinfo[i].speed
 		&& (i == 0 || (loadinfo[i].mem >= migpages)))
@@ -1021,20 +1040,24 @@
 		}
 		n++;
 	}
-#ifndef CONFIG_SSI
-	read_unlock_bh(&loadinfo_lock);
-#endif
 
 	if(n == 0 || (n == 1 && mach[0] == 0))
 		goto out;	/* save time */
 
-	/* we must NOT sleep throughout the following FP calculations:*/
-#ifndef CONFIG_USERMODE
-	kernel_fpu_begin();
-#endif
-
+	time = cputime_zero;
 	read_lock(&tasklist_lock);
-	time = cputime_add(p->utime, p->stime);
+
+	/* This block from 2.6.11 fs/proc/array.c:do_task_stat() */
+	{
+		task_t *t = p;
+		/* add up live thread stats at the group level */
+		do {
+			time = cputime_add(time, t->utime);
+			time = cputime_add(time, t->stime);
+			t = next_thread(t);
+		} while (t != p);
+	}
+
 	if (p->signal) {
 		time = cputime_add(time, p->signal->utime);
 		time = cputime_add(time, p->signal->stime);
@@ -1087,9 +1110,6 @@
 		mach[j] = k;
 	}
 
-#ifndef CONFIG_USERMODE
-	kernel_fpu_end();
-#endif
 	for(i = 0 ; i < n ; i++)
 	{
 		if((k = mach[i]) == 0)


------------------------------------------------------------------------------
The Next 800 Companies to Lead America's Growth: New Video Whitepaper
David G. Thomson, author of the best-selling book "Blueprint to a 
Billion" shares his insights and actions to help propel your 
business during the next growth cycle. Listen Now!
http://p.sf.net/sfu/SAP-dev2dev