[SSI] openssi/kernel/cluster/ssi/mosixll balance.c, 1.19, 1.20 freemem.c, 1.13, 1.14 info.c, 1.13, 1.14 kernel.c, 1.12, 1.13 load.c, 1.13, 1.14 service.c, 1.10, 1.11

Roger Tsang <[email protected]> Tue, 09 Nov 2010 02:31:03 +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-serv10374/cluster/ssi/mosixll

Modified Files:
      Tag: OPENSSI-FC
	balance.c freemem.c info.c kernel.c load.c service.c 
Log Message:
MOSIX:
- ssi_do_decay: fix did not operate on chosen task.
- ssi_do_decay: deprecated. consider() no longer requires mosix_task->dctime.
- consider: reduce excessive stack usage and useless math.
- mosix_calc_process_loads: remove unused code.
- mosix_calc_process_loads: no need to test for interrupt context. Caller in process context.
- mosix_calc_process_loads: calculate struct mosix_task->load for thread group so that in release_migrations() the thread group's load is accounted for when adjusting home/destination node's load value. OpenSSI migrates the thread group.
- release_migrations: clean-up and split CONFIG_SSI code.
- memory_badly_required: clean-up and split SSI_BALANCE_MEMORY code.
- memory_badly_required: only look at thread group leader's mosix_task->pages_i_bring. OpenSSI migrates the thread group.
- mosix_calc_process_loads, mosix_mem_daemon: OpenSSI is only interested in loadlevelable processes. Reduce unnecessary work.
- mosix_mem_daemon: call sort_and_age_pages() for thread group leaders only. reduce redundant work. (#ifdef SSI_BALANCE_MEMORY)
- run_over_dirty_pages: optimize away pte_really_dirty() call for the common code path.
- choose: use KERN_DEBUG log level. (#ifdef DEBUG)
- deactivate_task, activate_task: kernel threads no longer call run_on() / run_off(). Kernel threads do not migrate.
- Fix incorrect last_mconsider value in struct mosix_task after process migration. time_now() values are cross-node incompatible.
- No need to use task_rq_lock() to protect mosix_task->load. Switch to task_lock().

MOSIX (#ifdef REXEC_LOADTABLE_FAST):
- release_migrations: fix forgot to re-calculate value of altload in loadinfo array. Without recalculating altload other processes were not discouraged from migrating away. Regression introduced in CVS tag OPENSSI-FC-1-9-6-PRE45.
- mosix_calc_load: calculate the cached altload using value of newload, not export_load. In other places altload() is passed the value of load field in loadinfo structure and mosix_calc_load() stores the value of newload in load field.

 cluster/ssi/mosixll/balance.c           |  244 ++++++------------------
 cluster/ssi/mosixll/freemem.c           |   82 +++-----
 cluster/ssi/mosixll/info.c              |  160 ++++++++-------
 cluster/ssi/mosixll/kernel.c            |    3 
 cluster/ssi/mosixll/load.c              |   95 +++++----
 cluster/ssi/mosixll/service.c           |    4 
 cluster/ssi/vproc/rproc_cli_pproc.c     |    4 
 cluster/ssi/vproc/rproc_svr_pproc.c     |    4 
 include/cluster/gen/rproc_platform.x    |    6 
 include/cluster/ssi/mosixll/mosixtask.h |    6 
 kernel/sched.c                          |    6 
 11 files changed, 269 insertions(+), 345 deletions(-)


Index: load.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/load.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- load.c	9 Nov 2010 02:14:03 -0000	1.13
+++ load.c	9 Nov 2010 02:31:01 -0000	1.14
@@ -85,52 +85,65 @@
 #endif /* CONFIG_MOSIX_RESEARCH */
 
 #ifdef CONFIG_SSI
-/* Caller might be in interrupt context */
 static void
-mosix_calc_process_loads(unsigned long ticks)
+mosix_calc_process_loads(unsigned long u_ticks)
 {
-	struct task_struct *p;
+	struct task_struct *p, *t;
 	struct mosix_task *m;
 	struct runqueue *rq = NULL;
 	unsigned long flags;
-	int need_lock = !in_softirq();
+	unsigned long load = 0;
+	clock_t ran = 0;
+	cputime_t time;
 
-	/* Based on original mosix_calc_load().
-	 * Added locking where appropriate since in OpenSSI
-	 * mosix_calc_load() is no longer in top half.
+	/* Based on original mosix_calc_load() but also account for threads.
+	 * Unlike Mosix this is no longer in top half.
 	 */
 	read_lock(&tasklist_lock);
-	for_each_process(p)
-	{
-		m = &p->mosix;
-
-		if (!m->ran)
+	for_each_process(p) {
+		if (!p->mm || !thread_group_leader(p))
 			continue;
-		if (need_lock)
-			rq = task_rq_lock(p, &flags);
+		if (p->execnode || !is_loadlevelable(p, NULL))
+			continue;
+		/* Add thread group's mosix_task->ran cputime */
+		time = cputime_zero, t = p;
+		do {
+			t = next_thread(t);
+			m = &t->mosix;
+			if (!m->ran && t != p)
+				continue;
 
-		if (m->ran) {
-			m->load = m->load * DECAY +
-				cputime_to_clock_t(m->ran) *
-				MF * 4*NEWDATA / ticks;
-			m->ran = cputime_zero;
-		}
-		if (need_lock)
+			rq = task_rq_lock(t, &flags);
+			if (m->ran) {
+				time = cputime_add(time, m->ran);
+				m->ran = cputime_zero;
+			}
 			task_rq_unlock(rq, &flags);
-	}
-	read_unlock(&tasklist_lock);
 
-#ifdef SSI_SKIP
-#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
-		if (nsc_async_queue(nsc_generic_async_queue,
-					(void *)load_balance, NULL, 0, 0))
-			printk(KERN_WARNING "Failed to queue load balance \n");
+			/* Update leader's mosix_task->load */
+			if (t == p) {
+				if (time) {
+					ran = min_t(clock_t,
+						cputime_to_clock_t(time),
+						u_ticks * num_online_cpus());
+				}
+
+				task_lock(t);
+				m->load *= DECAY;
+				if (time) {
+					m->load += ran * stable_export *
+							4*NEWDATA / u_ticks;
+				}
+				load = m->load;
+				task_unlock(t);
+			}
+		} while (t != p);
+
+		/* Update group's mosix_task->load */
+		while_each_thread(p, t)
+			t->mosix.load = load;
 	}
-#endif
+	read_unlock(&tasklist_lock);
 }
 
 /* Locking:
@@ -186,11 +199,13 @@
 	newload = (accload+64) / 128;
 
 	spin_lock(&load_left_lock);
-	if(newload < load_left)
-		newload = 0;
-	else
-		newload -= load_left;
-	load_left = 0;
+	if (load_left) {
+		if(newload < load_left)
+			newload = 0;
+		else
+			newload -= load_left;
+		load_left = 0;
+	}
 	spin_unlock(&load_left_lock);
 
 #ifdef DEBUG
@@ -210,7 +225,7 @@
 		mosix_calc_process_loads(ticks);
 
 #ifdef REXEC_LOADTABLE_FAST
-	__altload = altload(export_load, loadinfo[0].speed, loadinfo[0].ncpus);
+	__altload = altload(newload, loadinfo[0].speed, loadinfo[0].ncpus);
 #endif
 	spin_lock(&loadinfo_lock);
 #ifdef REXEC_LOADTABLE_FAST

Index: balance.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/balance.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- balance.c	9 Nov 2010 02:14:03 -0000	1.19
+++ balance.c	9 Nov 2010 02:31:01 -0000	1.20
@@ -66,7 +66,7 @@
 int mosadmin_gateways;
 #else
 int mosadmin_mode_quiet;
-void ssi_do_decay(struct mosix_task *);
+void ssi_do_decay(struct mosix_task *, unsigned int);
 #endif /* CONFIG_SSI */
 
 #ifndef CONFIG_SSI
@@ -470,8 +470,6 @@
 #ifdef CONFIG_SSI
 /* Locking: this function may acquire ...
  * read_lock(&tasklist_lock)
- * -> sighand->siglock
- * task_lock()
  * spin_lock(&whereto_lock)
  */
 void
@@ -482,12 +480,15 @@
         unsigned long minload, load, bestload = -1;
         unsigned int priority, lastpri = 0; /* ms */
 	unsigned int pri, bestpri; /* ms */
+	cputime_t time;
 	const unsigned int mintime = 1000; /* 1000ms */
 	const unsigned int very_mintime = mintime / 3;
-	cputime_t time;
+static DECLARE_MUTEX(choose_sem);
 
 	if (chosen_for_balance)
 		return;
+	if (down_trylock(&choose_sem))
+		return;
 
 	/* Unlike OpenSSI, Mosix acpuse is always <= (MF * num_online_cpus()) */
 	bestpri = mintime; /* SSI: skip acpuse */
@@ -500,8 +501,7 @@
 		/* Process already migrating */
 		if (p->execnode)
 			continue;
-		/* Skip kernel threads / non-thread group leaders */
-		if (p->mm == NULL || p != p->group_leader)
+		if (p->mm == NULL || !thread_group_leader(p))
 			continue;
 		if (!is_loadlevelable(p, NULL))
 			continue;
@@ -527,20 +527,15 @@
 		priority = cputime_to_msecs(time);
 
 		m = &p->mosix;
-
-		task_lock(p);
-		ssi_do_decay(m);
 		priority -= m->last_consider;
-		task_unlock(p);
-
 		pri = priority < 4000 ? priority : 4000; /* 4000ms */
 
                 load = m->load;
 #ifdef DEBUG
 if(Tload)
-	printk("process=%d, load=%lu pri=%u bestpri=%u mload=%lu, bload=%lu \n",
-					p->pid, load, pri, bestpri, minload,
-					bestload);
+	printk(KERN_DEBUG "%s: process=%d, load=%lu pri=%u bestpri=%u "
+		"mload=%lu, bload=%lu \n", __FUNCTION__, p->pid, load,
+		pri, bestpri, minload, bestload);
 #endif /* DEBUG */
 
                 if(pri < bestpri)
@@ -566,25 +561,27 @@
         }
 	read_unlock(&tasklist_lock);
 
-        if(!sel)
+        if(!sel) {
+		up(&choose_sem);
 		return;
+	}
 
 	spin_lock(&whereto_lock);
 
+	/* Release choose_sem early since
+	 * mosix_do_add_to_whereto() path might be re-entrant
+	 */
+	up(&choose_sem);
+
 	if(chosen_for_balance)
 	{
 		spin_unlock(&whereto_lock);
 		put_task_struct(sel);
 		return;
 	}
-
-	task_lock(sel);
-        sel->mosix.last_consider += lastpri;
-	task_unlock(sel);
-
 	chosen_for_balance = sel;
+        sel->mosix.last_consider += lastpri;
 	load_balancing_counter = BALANCING_TIMEOUT;
-
 	mosix_do_add_to_whereto(sel, BALANCE);
 	/* whereto_lock unlocked */
 
@@ -751,7 +748,7 @@
 	unsigned long need = (unsigned long)arg;
 #ifdef SSI_BALANCE_MEMORY
 	unsigned long quality, bestquality = 0;
-	now_t df, diff = MIN_MCHOOSE_AGAIN;
+	u64 df, diff = MIN_MCHOOSE_AGAIN / 1000;
 #else
 	int quality, bestquality = 0;
 	int df, diff = MIN_MCHOOSE_AGAIN;
@@ -769,17 +766,16 @@
 		/* Process already migrating */
 		if (p->execnode)
 			continue;
-		/* Skip kernel threads / non-thread group leaders */
-		if (p->mm == NULL || p != p->group_leader)
+		if (p->mm == NULL || !thread_group_leader(p))
 			continue;
 		if (!is_loadlevelable(p, NULL))
 			continue;
 
-		task_lock(p);
-		dff = time_since(p->mosix.last_mconsider);
-		task_unlock(p);
+		dff = get_jiffies_64() - p->mosix.last_mconsider;
+		if (dff)
+			dff /= HZ;
 
-		df = min_t(typeof(dff), dff, MAX_MCHOOSE_AGAIN);
+		df = min_t(typeof(dff), dff, MAX_MCHOOSE_AGAIN / 1000);
 		if(df < diff)
 			continue;
 
@@ -804,10 +800,8 @@
 		spin_unlock(&whereto_lock);
 		return;
 	}
-	task_lock(sel);
-	sel->mosix.last_mconsider = time_now();
-	task_unlock(sel);
 	chosen_for_mdp = sel;
+	sel->mosix.last_mconsider = get_jiffies_64();
 	memory_balancing_counter = BALANCING_TIMEOUT;
 	mosix_do_add_to_whereto(sel, MEMBALANCE);
 	/* whereto_lock unlocked */
@@ -971,157 +965,56 @@
 #endif /* !CONFIG_SSI */
 
 #ifdef CONFIG_SSI
-/* Locking: this function may acquire ...
- * read_lock(&tasklist_lock)
- * -> sighand->siglock
- * task_lock()
- */
-/* Locking: called functions may acquire...
- * down_read(&mm->mmap_sem)
- * -> spin_lock(&mm->page_table_lock)
- * spin_lock(&loadinfo_lock)
- * task_lock()
- * down(&load_left_lock)
- * spin_lock(&whereto_lock)
- * read_lock(&tasklist_lock)
- * task_lock()
- */
 void
 consider(int reason, clusternode_t *node)
 {
-#if defined(CONFIG_MOSIX_FS) || defined(CONFIG_MOSIX_TOPOLOGY)
-#error not supported
-#endif
-#define	INFLOAD 0x8000000
-#define	MAX_CONSIDERED	(INFO_WIN)
-#if MAX_CONSIDERED > 127
-#error char is not enough for map
-#endif /*MAX_CONSIDERED*/
 	struct task_struct *p = current;
-	struct mosix_task *m = &p->mosix;
-	long long tim, costs[MAX_CONSIDERED];
-	int64_t ms;
-	unsigned long migpages, aload[MAX_CONSIDERED];
-	cputime_t time;
-	clusternode_t mach[MAX_CONSIDERED];
-	int i, n = 0, j, k;
-	int remote = (m->dflags & DREMOTE) ? 1 : 0;
+	unsigned long cost, least_cost = 0;
+	unsigned long migpages;
+	int i, n = 0;
 
-	if ((m->stay & DSTAY) || !PE || mosadmin_mode_quiet)
-		goto out;
-	if (reason && m->stay)
+	SSI_ASSERT(!(p->mosix.dflags & DREMOTE));
+	SSI_ASSERT(reason == BALANCE);
+	SSI_ASSERT(node);
+
+	if (p->mosix.stay || !PE || mosadmin_mode_quiet)
 		goto out;
 
+	if (!p->mm)
+		goto out;
 	migpages = run_over_dirty_pages(NULL, 0);
 
-	for(i = 0 ; i < INFO_WIN ; i++)
-	if(loadinfo[i].node && loadinfo[i].speed
-		&& (i == 0 || (loadinfo[i].mem >= migpages)))
-	{
+	for (i = 0; i < INFO_WIN; i++) {
+		if (i && (!loadinfo[i].node || loadinfo[i].mem < migpages))
+			continue;
+		/* Skipped various constant factors: tim, mosix.pagetime */
+		if (i == 0 && !latest_free_mem)
+			cost = ULONG_MAX;
+		else
 #ifdef REXEC_LOADTABLE_FAST
-		aload[n] = loadinfo[i].altload;
+			cost = loadinfo[i].altload;
 #else
-		aload[n] = altload(loadinfo[i].load, loadinfo[i].speed,
-				loadinfo[i].ncpus);
+			cost = altload(loadinfo[i].load, loadinfo[i].speed,
+					loadinfo[i].ncpus);
 #endif
-		if(i)
-			mach[n] = loadinfo[i].node;
-		else
-		{
-			mach[n] = 0;
-			if(reason == MEMBALANCE)
-			{
-				if(remote)
-					continue;
-				aload[n] += INFLOAD;
-			}
-			if (!latest_free_mem)
-				aload[0] = INT_MAX;
+		/* Find least cost */
+		if (i == 0) {
+			least_cost = cost;
+			*node = 0;
+		} else if (cost < least_cost) {
+			least_cost = cost;
+			*node = loadinfo[i].node;
 		}
 		n++;
 	}
+	rmb();
+	if (n <= 1 || *node == 0)
+		goto out; /* this node is least loaded */
 
-	if(n == 0 || (n == 1 && mach[0] == 0))
-		goto out;	/* save time */
-
-	time = cputime_zero;
-	read_lock(&tasklist_lock);
-
-	/* 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);
-		time = cputime_add(time, p->signal->cutime);
-		time = cputime_add(time, p->signal->cstime);
-	}
-	read_unlock(&tasklist_lock);
-
-	task_lock(p);
-	ms = cputime_to_msecs(time) - m->dctime;
-	task_unlock(p);
-
-	tim = (ms ? : 2) * cpuspeed / STD_SPD;
-
-	for(i = 0 ; i < n ; i++)
-		costs[i] = tim * aload[i] / MF;
-
-	if (reason != MEMBALANCE)
-	{
-		/* migration cost: */
-		/* SSI_XXX: fudge costs for now */
-		/* MIGRATION_BASIC + m->migpages * MIGRATION_PER_PAGE */
-		tim = HZ + migpages * HZ / 20;
-
-		task_lock(p);
-		if(m->dctime > 0) {	/* decay occured */
-			//ms = cputime_to_msecs(p->utime);
-			if(ms)
-				//tim = tim * ((long long)ms - (long long)m->dctime) / ms;
-				/* already subtracted dctime from ms */
-				tim = tim * ((long long)ms) / ((long long)m->dctime + ms);
-		}
-		task_unlock(p);
-
-		for(i = 0 ; i < n ; i++)
-		if(i != remote)
-			costs[i] += tim;
-	}
-
-	/* sort by least cost */
-	for(i = 0 ; i < n-1 ; i++)
-	for(j = i+1 ; j < n ; j++)
-	if(costs[i] > costs[j])
-	{
-		tim = costs[i];
-		costs[i] = costs[j];
-		costs[j] = tim;
-		k = mach[i];
-		mach[i] = mach[j];
-		mach[j] = k;
-	}
-
-	for(i = 0 ; i < n ; i++)
-	{
-		if((k = mach[i]) == 0)
-			goto out;
-		if (node) {
-			*node = k;
-			/* cleanup stuff */
-			release_migrations(k, migpages);
-			neutralize_my_load(1);
-		}
-		return;
-	}
+	/* cleanup stuff */
+	release_migrations(*node, migpages);
+	neutralize_my_load(1);
+	return;
 out:
 	unchoose_me(p);
 }
@@ -1827,22 +1720,21 @@
 #endif
 }
 
-/* Called under read_lock(&tasklist_lock), task_lock() */
-void ssi_do_decay(struct mosix_task *m)
+#ifdef SSI_SKIP
+/* Called under task_lock */
+void __deprecated ssi_do_decay(struct mosix_task *m, unsigned int ms)
 {
-	/* register struct mosix_task *m = &current->mosix; */
-	int d = m->decay;
-	int64_t ms;
+	const int d = DEFAULT_SLOW_ALPHA;
 
-	/* ms = ticks_to_ms(current->utime) - m->dctime; */
-	ms = cputime_to_msecs(current->utime) - m->dctime;
+	m->m_ms = ms - m->dctime;
 #ifdef CONFIG_MOSIX_DEBUG
 	if(ds_debug & DSDEB_DECAY)
 		printk("decaying %s by adding %d/%d of %d to %d\n",
 		desc_mostask(m), DECAY_QUOTIENT - d, DECAY_QUOTIENT,
 						(int)ms, (int)m->dctime);
 #endif /* CONFIG_MOSIX_DEBUG */
-	if(ms > 0)
-		m->dctime += ms * (DECAY_QUOTIENT - d) / DECAY_QUOTIENT;
+	if(m->m_ms > 0)
+		m->dctime += m->m_ms * (DECAY_QUOTIENT - d) / DECAY_QUOTIENT;
 }
+#endif /* SSI_SKIP */
 #endif /* CONFIG_SSI */

Index: freemem.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/freemem.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- freemem.c	25 Oct 2010 05:50:41 -0000	1.13
+++ freemem.c	9 Nov 2010 02:31:01 -0000	1.14
@@ -85,21 +85,11 @@
 /* Acquires read_lock(&tasklist_lock), task_lock() */
 int
 memory_badly_required(unsigned long *need)
-#else
-int
-memory_badly_required(void)
-#endif
 {
-#ifdef SSI_BALANCE_MEMORY
 	unsigned long n, b = 0;
 	char do_need = 0;
-#else
-	register int n, s = 0;
-	struct mm_struct *mm;
-#endif
 	struct task_struct *p;
 
-#ifdef SSI_BALANCE_MEMORY
 	/* Free minus pages migrating to this node minus swap */
 	if ((n = current_free_mem()) < pages_to_keep_free) {
 		do_need = 1;
@@ -109,37 +99,14 @@
 		n -= pages_to_keep_free;
 
 	read_lock(&tasklist_lock);
-#else
-	n = current_free_mem() - pages_to_keep_free;
-	write_lock_irq(&tasklist_lock);
-	++marker;
-#endif /* !SSI_BALANCE_MEMORY */
-	for_each_process(p)
-	{
-#ifdef CONFIG_SSI
-#ifdef SSI_BALANCE_MEMORY
-		/* SSI: mosix.pages_i_bring is +ve. See release_migrations() */
-		task_lock(p);
-		b += p->mosix.pages_i_bring;
-		task_unlock(p);
-#endif
-
+	for_each_process(p) {
 		if (p->mosix.stay)
 			continue;
-#else
-		n -= p->mosix.pages_i_bring;
-#endif /* !CONFIG_SSI */
-#ifndef SSI_BALANCE_MEMORY
-		task_lock(p);
-		if((mm = p->mm) && mm->mark != marker && mm->last_memsort)
-		{
-			s += mm->swapped;
-			mm->mark = marker;
-		}
-		task_unlock(p);
-#endif /* !SSI_BALANCE_MEMORY */
+		if (!p->mm || !thread_group_leader(p))
+			continue;
+		/* SSI: mosix.pages_i_bring is +ve. See release_migrations() */
+		b += p->mosix.pages_i_bring;
 	}
-#ifdef SSI_BALANCE_MEMORY
 	read_unlock(&tasklist_lock);
 
 	if (do_need || n < b) {  /* add negative pages */
@@ -152,22 +119,48 @@
 			if (n < MIN_EXPECTED_PROC_SIZE)
 				n = (long)MIN_EXPECTED_PROC_SIZE;
 			else
-				/* n += s; */
 				n += nr_swap_pages;
 		}
 		*need = n;
 		return 1;
 	}
 	return 0;
+}
+#else /* SSI_BALANCE_MEMORY */
+int
+memory_badly_required(void)
+{
+	register int n, s = 0;
+	struct mm_struct *mm;
+	struct task_struct *p;
+
+	n = current_free_mem() - pages_to_keep_free;
+	write_lock_irq(&tasklist_lock);
+	++marker;
+	for_each_process(p)
+	{
+#ifdef CONFIG_SSI
+		if (p->mosix.stay)
+			continue;
 #else
+		n -= p->mosix.pages_i_bring;
+#endif /* !CONFIG_SSI */
+		task_lock(p);
+		if((mm = p->mm) && mm->mark != marker && mm->last_memsort)
+		{
+			s += mm->swapped;
+			mm->mark = marker;
+		}
+		task_unlock(p);
+	}
 	write_unlock_irq(&tasklist_lock);
 	if(n < 0 && n > -MIN_EXPECTED_PROC_SIZE)
 		n = (int)-MIN_EXPECTED_PROC_SIZE;
 	if(n < 0)
 		n -= s;
 	return(-n);
-#endif
 }
+#endif /* !SSI_BALANCE_MEMORY */
 
 #define	MDP_HIGHEST_QUALITY	(MIN_EXPECTED_PROC_SIZE * 10)
 
@@ -671,8 +664,13 @@
 		n = 0;
 #ifdef SSI_BALANCE_MEMORY
 		read_lock(&tasklist_lock);
-		for_each_process(p)
-		if (!(p->mosix.stay & DSTAY_PER_MM)) {
+		for_each_process(p) {
+			if (p->mosix.stay & DSTAY_PER_MM)
+				continue;
+			if (!p->mm || !thread_group_leader(p))
+				continue;
+			if (p->execnode || !is_loadlevelable(p, NULL))
+				continue;
 			mm = get_task_mm(p);
 			if (!mm)
 				continue;

Index: service.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/service.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- service.c	18 Apr 2010 20:42:24 -0000	1.10
+++ service.c	9 Nov 2010 02:31:01 -0000	1.11
@@ -247,8 +247,8 @@
 				if(pte_end > pmd_end)
 					pte_end = pmd_end;
 				if(pte_present(*pte) ?
-				   (isfile && !pte_really_dirty(*pte)) :
-				   pte_none(*pte)) {
+				   (isfile && count_in_file &&
+				    !pte_really_dirty(*pte)) : pte_none(*pte)) {
 					if(isfile && count_in_file)
 						count++;
 					continue;

Index: info.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/info.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- info.c	25 Oct 2010 05:50:41 -0000	1.13
+++ info.c	9 Nov 2010 02:31:01 -0000	1.14
@@ -969,72 +969,125 @@
  * but not before we adjust the local and remote loads to discourage
  * further migrations.
  */
-/* Locking: will acquire...
- * task_lock()
 #ifdef CONFIG_SSI
+/* Locking: will acquire...
+ * read_lock(&tasklist_lock);
+ * task_rq_lock()
+ * spin_lock(&load_left_lock)
  * spin_lock(&loadinfo_lock)
-#else
- * write_lock_bh(&loadinfo_lock)
- * -> task_rq_lock()
-#endif
- * down(&load_left_lock)
  * task_lock()
  */
-/* Called functions may acquire...
-#ifdef CONFIG_SSI
- * spin_lock(&whereto_lock)
-#else
- * spin_lock_irq(&whereto_lock)
- * read_lock_bh(&loadinfo_lock)
-#endif
- * read_lock(&tasklist_lock)
- */
 void
-#ifdef CONFIG_SSI
-release_migrations(int whereto, unsigned long pages)
+release_migrations(int i, unsigned long pages)
+{
+	struct task_struct *p = current;
+#ifdef SSI_BALANCE_MEMORY
+	struct task_struct *t = p;
+#endif
+	unsigned long load, mig_load;
+
+	/* Decrease the local load by the load caused by this process,
+	 * to avoid over-migration.
+	 */
+	read_lock(&tasklist_lock);
+	task_lock(p->group_leader);
+	load = p->group_leader->mosix.load;
+	task_unlock(p->group_leader);
+	read_unlock(&tasklist_lock);
+
+	load = load * STD_SPD / 4 / cpuspeed / num_online_cpus();
+
+	spin_lock(&load_left_lock);
+	load_left += load;
+	spin_unlock(&load_left_lock);
+
+	if (loadinfo[i].node) {
+		/* slightly more than 1 process worth of load */
+		mig_load = MF * 102 * STD_SPD;
+		mig_load /= loadinfo[i].speed * loadinfo[i].ncpus * 100;
+	} else
+		mig_load = 0;
+
+	spin_lock(&loadinfo_lock);
+	  /* It is ON PURPOSE that `acpuse' is not taken into account */
+	if(loadinfo[0].load < load)   /* should not happen, but ... */
+		load = loadinfo[0].load;
+
+	loadinfo[0].load -= load;
+#ifdef	CONFIG_MOSIX_DEBUG
+	if(ds_debug & (DSDEB_LOADS|DSDEB_CONSIDER))
+		printk("local load down by %d to %d due to leaving (to %d)\n",
+					(int)load, (int)loadinfo[0].load, i);
+#endif
+#ifdef REXEC_LOADTABLE_FAST
+	loadinfo[0].altload = altload(loadinfo[0].load,
+				loadinfo[0].speed, loadinfo[0].ncpus);
+
+	cond_resched_lock(&loadinfo_lock);
+#endif
+
+	/* increase the receiver's-load */
+	if (loadinfo[i].node) {
+		/* add slightly more than 1 process worth of load */
+		loadinfo[i].load += mig_load;
+		if (loadinfo[i].mem < pages) /* should not happen, but ... */
+			loadinfo[i].mem = 0;
+		else
+			loadinfo[i].mem -= pages;
+#ifdef CONFIG_SSI_LOADINFO_RLOAD
+		loadinfo[i].rload += load;
+		loadinfo[0].rload = load;
+#endif
+#ifdef CONFIG_MOSIX_DEBUG
+		if(ds_debug & (DSDEB_LOADS|DSDEB_CONSIDER))
+			printk("loadinfo[%d], pe=%d increased to %d due to "
+				"migration; mem decreased to %d\n",
+				i, i, (int)loadinfo[i].load,
+				(int)loadinfo[i].mem);
+#endif
+#ifdef REXEC_LOADTABLE_FAST
+		loadinfo[i].altload = altload(loadinfo[i].load,
+					loadinfo[i].speed, loadinfo[i].ncpus);
+#endif
+	}
+	spin_unlock(&loadinfo_lock);
+
+#ifdef SSI_BALANCE_MEMORY
+	/* discourage 'memory_badly_required' */
+	read_lock(&tasklist_lock);
+	do {
+		t->mosix.pages_i_bring = pages;
+	} while_each_thread(p, t);
+	read_unlock(&tasklist_lock);
 #else
-release_migrations(int whereto)
+	p->mosix.pages_i_bring = -pages; /* discourage 'memory_badly_required' */
 #endif
+	unchoose_me(p);
+}
+#else /* CONFIG_SSI */
+release_migrations(int whereto)
 {
 	struct task_struct *p = current;
 	register struct mosix_task *m = &p->mosix;
 	struct runqueue *rq;
 	unsigned long flags;
-#ifdef CONFIG_SSI
-	unsigned long load;
-	unsigned int i;
-#else
 	register int load, i;
 	int pages = m->migpages ? : count_migrating_pages();
 
 	this_machine_is_favourite(whereto);
-#endif /* CONFIG_SSI */
 
 	/* Decrease the local load by the load caused by this process,
 	 * to avoid over-migration.
 	 */
-#ifdef CONFIG_SSI
-	rq = task_rq_lock(p, &flags);
-	load = m->load;
-	task_rq_unlock(rq, &flags);
-
-	load = load * STD_SPD / 4 / cpuspeed;
-	load /= num_online_cpus();
-
-	spin_lock(&loadinfo_lock);
-#else
 	write_lock_bh(&loadinfo_lock);
 	rq = task_rq_lock(p, &flags);
 	load = m->load * STD_SPD / 4 / cpuspeed;
 	load /= num_online_cpus();
 	task_rq_unlock(rq, &flags);
-#endif
 	  /* It is ON PURPOSE that `acpuse' is not taken into account */
 	if(loadinfo[0].load < load)   /* should not happen, but ... */
 		load = loadinfo[0].load;
-#ifndef CONFIG_SSI
 	load_left += load;
-#endif
 
 	loadinfo[0].load -= load;
 #ifdef	CONFIG_MOSIX_DEBUG
@@ -1044,64 +1097,33 @@
 #endif
 
 	/* increase the receiver's-load */
-#ifdef CONFIG_SSI
-	i = whereto;
-	BUG_ON(i < 1 || i > NSC_MAX_NODE_VALUE);
-	if(loadinfo[i].node == whereto)
-#else
 	for(i = 1 ; i < INFO_WIN ; i++)
 	if(loadinfo[i].pe == whereto)
-#endif
 	{
 		/* add slightly more than 1 process worth of load */
 		loadinfo[i].load += (unsigned long)(MF) * 102 * STD_SPD/
 			(loadinfo[i].speed * loadinfo[i].ncpus * 100);
 		loadinfo[i].mem -= pages;
-#ifdef CONFIG_SSI_LOADINFO_RLOAD
-		loadinfo[i].rload += load;
-		loadinfo[0].rload = load;
-#endif
 #ifdef CONFIG_MOSIX_DEBUG
-#ifndef CONFIG_SSI
 		if(loadinfo[i].free_slots)
 			loadinfo[i].free_slots--;
-#endif /* !CONFIG_SSI */
 		if(ds_debug & (DSDEB_LOADS|DSDEB_CONSIDER))
 			printk("loadinfo[%d], pe=%d increased to %d due to "
 				"migration; mem decreased to %d\n",
 				i, whereto, (int)loadinfo[i].load,
 				(int)loadinfo[i].mem);
 #endif
-#ifndef CONFIG_SSI
 		break;
-#endif
 	}
-#ifndef CONFIG_SSI
 	write_unlock_bh(&loadinfo_lock);
-#else
-	spin_unlock(&loadinfo_lock);
-
-	spin_lock(&load_left_lock);
-	load_left += load;
-	spin_unlock(&load_left_lock);
-#endif /* CONFIG_SSI */
 #ifdef CONFIG_MOSIX_DEBUG
 	if((ds_debug & (DSDEB_LOADS|DSDEB_CONSIDER)) && i == INFO_WIN)
 		printk("release_migrations: Could not adjust machine #%d (not in list)\n", whereto);
 #endif /* CONFIG_MOSIX_DEBUG */
-#ifdef SSI_BALANCE_MEMORY
-	task_lock(p);
-	m->pages_i_bring = pages; /* discourage 'memory_badly_required' */
-	task_unlock(p);
-#else
 	m->pages_i_bring = -pages; /* discourage 'memory_badly_required' */
-#endif
-#ifdef CONFIG_SSI
-	unchoose_me(p);
-#else
 	unchoose_me();
-#endif
 }
+#endif /* !CONFIG_SSI */
 
 #ifndef CONFIG_SSI
 #if 0

Index: kernel.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/kernel.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- kernel.c	25 Oct 2010 05:50:41 -0000	1.12
+++ kernel.c	9 Nov 2010 02:31:01 -0000	1.13
@@ -669,9 +669,6 @@
 	if(p->pid == 1)
 		m->stay |= DSTAY_ITS_INIT;
 #ifdef CONFIG_SSI
-	/* SSI_XXX: m->dctime always zero. See ssi_do_decay() */
-	/* m->decay = DECAY_QUOTIENT; */
-	m->decay = DEFAULT_SLOW_ALPHA;
 	if(p->pid == 2 || parent->pid == 2)
 		m->stay |= DSTAY_ITS_DAEMON;
 	else


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