[SSI] openssi/kernel/cluster/ssi/mosixll balance.c, 1.11, 1.12 freemem.c, 1.8, 1.9 info.c, 1.8, 1.9 init.c, 1.4, 1.5 kernel.c, 1.8, 1.9 load.c, 1.6, 1.7

Roger Tsang <[email protected]>
Newsgroups gmane.linux.cluster.ssic.cvs
Message-ID <[email protected]>
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll
In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv16224/kernel/cluster/ssi/mosixll

Modified Files:
      Tag: OPENSSI-FC
	balance.c freemem.c info.c init.c kernel.c load.c 
Log Message:
Bug fixes and enhancements. See ChangeLog.


Index: init.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/init.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- init.c	25 Feb 2005 19:58:26 -0000	1.4
+++ init.c	27 Oct 2009 03:18:29 -0000	1.5
@@ -34,8 +34,13 @@
 
 #define	STD_LOOPS	9961472  /* loops per jiffy on standard processor */
 #ifdef CONFIG_SSI
-int calc_speed(int loops_per_jiffy) {
-	return (((int64_t)loops_per_jiffy) * STD_SPD /STD_LOOPS);
+unsigned long calc_speed(unsigned long cpupwr) {
+#if defined(__i386__) && !defined(CONFIG_USERMODE)
+	/* init_mosix() calculation */
+	return (((int64_t)cpupwr) * STD_SPD / STD_LOOPS) * 2;
+#else
+	return ((int64_t)cpupwr) * STD_SPD / STD_LOOPS;
+#endif
 }
 #endif
 

Index: load.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/load.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- load.c	20 Apr 2008 05:49:23 -0000	1.6
+++ load.c	27 Oct 2009 03:18:29 -0000	1.7
@@ -40,6 +40,24 @@
 #define DECAY   VV1/VV2         /* decay of load */
 #define NEWDATA (VV2-VV1)/VV2   /* weight of new load data */
 
+#ifdef CONFIG_SSI
+/* protect load_ticks, cpuse, load_addr */
+static __cacheline_aligned_in_smp DEFINE_SPINLOCK(snap_load_lock);
+
+unsigned long load_adder;    /* accumulator of `running' every clock tick */
+unsigned long load_ticks;    /* # of ticks included in load_adder */
+unsigned long cpuse;         /* # of ticks when CPU was not thrashing */
+
+__cacheline_aligned_in_smp DEFINE_RWLOCK(acpuse_lock); /* protect acpuse */
+unsigned long acpuse = MF;   /* long term non-trashing (start value = non-0) */
+
+DECLARE_MUTEX(load_left_lock); /* protect load_left */
+unsigned long load_left;     /* load of processes that just left */
+
+unsigned proc_ticks;    /* # of ticks included in for load leveler to run */
+/* SSI: export_load is protected by loadinfo_lock */
+unsigned long export_load;	/* load reported to other processors */
+#else
 unsigned load_adder;    /* accumulator of `running' every clock tick */
 unsigned load_ticks;    /* # of ticks included in load_adder */
 unsigned cpuse;         /* # of ticks when CPU was not thrashing */
@@ -47,11 +65,8 @@
 unsigned coming_in;     /* number of arriving processes */
 unsigned came_lately4;  /* processes that arrived lately (*4) */
 unsigned load_left;     /* load of processes that just left */
-#ifdef CONFIG_SSI
-unsigned proc_ticks;    /* # of ticks included in for load leveler to run */
-#endif
-
 int export_load;	/* load reported to other processors */
+#endif /* !CONFIG_SSI */
 int stable_export;	/* machine dependent stabilizing factor */
 
 int Tvis;
@@ -69,21 +84,26 @@
 unsigned int old_io_write;
 #endif /* CONFIG_MOSIX_RESEARCH */
 
-
 void
 mosix_calc_load(unsigned long unused)
 {
 #ifndef CONFIG_SSI
 	struct task_struct *p;
 	register struct mosix_task *m;
-#endif
 	register int ladd, cpu, ticks;
-	unsigned long newload;
 	int new_expload;
-	unsigned new_cpuse;
-	unsigned new_came;
 	static unsigned upper_load;    /* over estimated load */
 	static unsigned accload;       /* accumulated load (*128) */
+	unsigned new_cpuse;
+	unsigned new_came;
+#else
+	unsigned long ladd, cpu, ticks;
+	unsigned long new_expload, new_cpuse;
+	unsigned long flags;
+static unsigned long upper_load = 0;	/* over estimated load */
+static unsigned long accload = 0;	/* accumulated load (*128) */
+#endif /* CONFIG_SSI */
+	unsigned long newload;
 	static int display_counter = 0;
 #ifdef CONFIG_MOSIX_RESEARCH
 	unsigned int new_io_read;
@@ -92,14 +112,24 @@
 #endif /* CONFIG_MOSIX_RESEARCH */
 
 
+#ifdef CONFIG_SSI
+	/* SSI: mosix_calc_load() is no longer called from interrupt context
+	 * unlike openMosix.
+	 */
+	spin_lock_irqsave(&snap_load_lock, flags);
+#endif
 	ticks = load_ticks;
 	cpu = cpuse;
 	ladd = load_adder;
 	cpuse = load_adder = load_ticks = 0;
 
 #ifdef CONFIG_SSI
+	spin_unlock_irqrestore(&snap_load_lock, flags);
 	if (ticks == 0)
 		return;
+
+	/* Protect upper_load, accload */
+	down(&load_left_lock);
 #endif
 
 	ladd = ladd * ((long long)(MF * STD_SPD)) /
@@ -112,18 +142,35 @@
 		upper_load = ladd;
 	else				/* very slowly down */
 		upper_load = (upper_load * 7 + ladd) / 8;
+#ifdef CONFIG_SSI
+	write_lock(&acpuse_lock);
+#endif
 	new_cpuse = (acpuse * 3 + cpu * MF / ticks + 3) / 4;
+#ifdef CONFIG_SSI
+	acpuse = new_cpuse;
+	write_unlock(&acpuse_lock);
+#endif
 	newload = (accload+64) / 128;
+#ifdef CONFIG_SSI
+	/* SSI_ASSERT(came_lately4 == 0); */
+	new_expload = (upper_load + stable_export) *
+			MF * num_online_cpus() / new_cpuse;
+#else
 	new_expload = (upper_load + stable_export +
 		came_lately4 * MF * STD_SPD /
 			(4 * cpuspeed * num_online_cpus())) *
 			MF * num_online_cpus() / new_cpuse;
+#endif
 	if(newload < load_left)
 		newload = 0;
 	else
 		newload -= load_left;
 	newload = newload * MF * num_online_cpus() / new_cpuse;
+#ifdef CONFIG_SSI
+	/* SSI_ASSERT(came_lately4 == 0); */
+#else
 	new_came = came_lately4 * DECAY + coming_in * 4 * NEWDATA;
+#endif
 
 #ifndef CONFIG_SSI
 	/* For SSI we moved this into mosix_calc_process_loads(); */
@@ -144,24 +191,36 @@
 #endif
 
 	if(Tvis)
+#ifdef CONFIG_SSI
+		printk("\0337\033[22;55HL=%d,E=%d,R=%lu,U=%d  \0338",
+			(int)newload, (int)new_expload, nr_running(),
+			(int)new_cpuse);
+#else
 		printk("\0337\033[22;55HL=%d,E=%d,R=%d,U=%d  \0338",
-			(int)newload, new_expload, mosix_running,
-			new_cpuse);
+			(int)newload, (int)new_expload, mosix_running,
+			(int)new_cpuse);
+#endif
 	if(Tload) {
 		if (!(display_counter = (display_counter + 1) & 0xf))
 			printk("\naccload upper_load\tload_adder\tload_ticks\n");
 		printk("%7d\t%10d\t%10d\t%d\n",
-			accload, upper_load, ladd, ticks);
+			(int)accload, (int)upper_load, (int)ladd, (int)ticks);
 	}
 	write_lock(&loadinfo_lock);
+#ifdef CONFIG_SSI
+	loadinfo[0].mem = latest_free_mem;
+#endif
 #ifdef CONFIG_SSI_LOADINFO_RLOAD
+	/* SSI_XXX: newload already factored in load_left - aka. rload */
 	loadinfo[0].load = newload - loadinfo[0].rload;
 #else
 	loadinfo[0].load = newload;
 #endif
 	export_load = new_expload;
+#ifndef CONFIG_SSI
 	acpuse = new_cpuse;
 	came_lately4 = new_came;
+#endif
 	load_left = 0;
 
 #ifdef CONFIG_MOSIX_RESEARCH
@@ -185,7 +244,8 @@
 	write_unlock(&loadinfo_lock);
 
 #ifdef CONFIG_SSI
-	loadinfo[0].mem = latest_free_mem;
+	up(&load_left_lock);
+	/* SSI_XXX: Need inc_decays() ? */
 	age_balancing();
 #else
 	if((p = (struct task_struct *)info_proc))
@@ -194,6 +254,9 @@
 }
 
 #ifdef CONFIG_SSI
+/* Following path in interrupt context:
+ * do_timer, mosix_snap_load, mosix_calc_process_loads
+ */
 void
 mosix_calc_process_loads(int ticks)
 {
@@ -205,6 +268,9 @@
 	for_each_process(p)
 	{
 		m = &p->mosix;
+		if (!spin_trylock(&p->alloc_lock))
+			continue;
+		/* Got task_lock(p) */
 		if(m->runstart)
 		{
 			m->ran += ticks + 1 - m->runstart;
@@ -213,65 +279,100 @@
 		m->load = m->load * DECAY + m->ran * MF * 4*NEWDATA/ticks;
 		m->ran = 0;
 		m->page_allocs >>= 1;	/* decay in time */
+		task_unlock(p);
 	}
 	read_unlock(&tasklist_lock);
 
-	if (load_cnt > 1 && loadlevel_on) {
-		int error = 0;
-
-		error = nsc_async_queue(nsc_generic_async_queue,
-					(void *)load_balance,
-					NULL, 0, 0);
-		if (error) {
+#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");
-		}
 	}
+#endif
 }
 #endif
 
 void
 mosix_load_init(void)
 {
+#ifdef CONFIG_SSI
+	cpuse = acpuse = MF * num_online_cpus();
+	load_ticks = MF;	/* fake it to begin with (must be non-zero) */
+	load_adder = nr_running() * MF;
+#else
 	acpuse = MF * num_online_cpus();
 	load_ticks = MF;	/* fake it to begin with (must be non-zero) */
 	cpuse = MF * num_online_cpus();
 	load_adder = mosix_running * MF;
+#endif
 	mosix_calc_load(0);
 
 #ifdef CONFIG_SSI
 	loadinfo[0].node = PE = this_node;
+#ifdef SSI_SKIP
+	/* SSI_XXX: error div by zero in path ...,
+	 * loadinfo_received, load_balance, altload [OOPS].
+	 * loadinfo[i].speed is zero / not yet initialized
+	 * because im_ready == FALSE.
+	 */
+	/* This is moved to update_load_info() */
 	if (this_node != clms_master_node)
+#ifdef REXEC_LOADTABLE_RACE_FIX
+		atomic_inc(&load_cnt);
+#else
 		load_cnt++;
+#endif
+#endif /* SSI_SKIP */
 #endif /* CONFIG_SSI */
 #ifdef CONFIG_MOSIX_RESEARCH
 	io_read_rate = io_write_rate = old_io_read = old_io_write = 0;
 #endif /* CONFIG_MOSIX_RESEARCH */
 }
 
+/* Called by timer interrupt */
 void
+#ifdef CONFIG_SSI
+mosix_snap_load(unsigned long ticks)
+#else
 mosix_snap_load(int ticks)
+#endif
 {
 #ifdef CONFIG_SSI
-	int active_cpus = 0;
-	int i;
+	int n, active_cpus = 0;
 
+#ifdef SSI_SKIP
+	/* SSI_XXX: Could race with mosix_calc_load() */
 	load_adder += nr_running() + nr_uninterruptible();
-	for (i=0; i < num_online_cpus(); i++)
-		active_cpus += active_cpu_list[i];
+	for (n=0; n < num_online_cpus(); n++)
+		active_cpus += active_cpu_list[n];
 
 	if(nr_running() <= active_cpus)
+#endif
+	for_each_online_cpu(n) {
+		if (!idle_cpu(n))
+			active_cpus++;
+	}
+
+	if(nr_running() <= active_cpus) {
+		spin_lock(&snap_load_lock);
 #else
 	load_adder += mosix_running;
-	if(mosix_running <= active_cpus)
+	if(mosix_running <= active_cpus) {
 #endif
 		cpuse += ticks * num_online_cpus();
-	else
-	{
+	} else {
 		/* a possible race between the time of making a process runable
 		 * and actual picking up by a processor: so count runable
 		 * processes as if already occupying a processor:
 		 */
+#ifndef CONFIG_SSI
 		int n;
+#endif
 		register struct task_struct *p;
 
 		read_lock(&tasklist_lock);
@@ -284,14 +385,21 @@
 			}
 		}
 		read_unlock(&tasklist_lock);
+#ifdef CONFIG_SSI
+		spin_lock(&snap_load_lock);
+#endif
 		cpuse += ticks * n;
 	}
-	load_ticks += ticks;
 #ifdef CONFIG_SSI
+	load_adder += nr_running() + nr_uninterruptible();
+	load_ticks += ticks;
+	spin_unlock(&snap_load_lock);
+
 	proc_ticks += ticks;
-	if(proc_ticks >= MF && loadlevel_on)
+	if(proc_ticks >= MF && atomic_read(&loadlevel_on))
 		mosix_calc_process_loads(proc_ticks);
 #else
+	load_ticks += ticks;
 	if(load_ticks >= MF)
 		mosix_calc_load(0);
 #endif

Index: balance.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/balance.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- balance.c	20 Apr 2008 05:49:22 -0000	1.11
+++ balance.c	27 Oct 2009 03:18:29 -0000	1.12
@@ -22,6 +22,7 @@
 #include <cluster/ssi/mosixll/debug.h>
 #include <cluster/ssi/mosixll/balance.h>
 #include <cluster/ssi/load_level.h>
+#include <cluster/async.h>
 #else
 #include <linux/mosctl.h>
 #include <mos/defs.h>
@@ -61,7 +62,7 @@
 int mosadmin_mode_quiet;
 int mosadmin_mode_nomfs;
 int mosadmin_gateways;
-void ssi_do_decay(void);
+void ssi_do_decay(struct mosix_task *);
 #endif /* CONFIG_SSI */
 
 #ifdef CONFIG_MOSIX_DEBUG
@@ -404,6 +405,19 @@
  *	With the extra process, they will need L units of time to complete.
  * the loss is therefore (N*L-1)*(L-(N*L-1)/N) = (N*L-1)*(L-L+1/N) = L - 1/N.
  */
+#ifdef CONFIG_SSI
+inline unsigned long
+altload(unsigned long load, unsigned long speed, int ncpus)
+{
+	unsigned long threshold = ((unsigned long)(MF * STD_SPD)) / speed;
+
+	if(load <= threshold)
+		return(threshold);
+	if(load <= threshold + threshold/ncpus)
+		return(threshold + ncpus * load * (load-threshold) / threshold);
+	return(2 * load - threshold / ncpus);
+}
+#else
 inline int
 altload(int load, int speed, int ncpus)
 {
@@ -415,8 +429,10 @@
 		return(threshold + ncpus * load * (load-threshold) / threshold);
 	return(2 * load - threshold / ncpus);
 }
+#endif /* !CONFIG_SSI */
 
 #ifndef CONFIG_SSI
+#if 0
 int
 send_local_aload(int type)
 {
@@ -431,24 +447,44 @@
 #endif /* CONFIG_MOSIX_TOPOLOGY */
 	return(comm_send(type, &a, sizeof(a), NULL, 0, 0));
 }
+#endif /* if 0 */
 #endif /* !CONFIG_SSI */
 
 void
 choose(void)
 {
-        int64_t priority, lastpri = 0;
-	int pri, bestpri;
-        register int load, bestload;
 	struct task_struct *p, *sel = NULL;
 	register struct mosix_task *m;
+#ifdef CONFIG_SSI
+        unsigned int priority, lastpri = 0;
+	struct task_struct *t;
+        unsigned long load, bestload = 0;
+	unsigned int pri, bestpri;
+        unsigned int mintime, very_mintime;
+	unsigned long minload;
+	cputime_t utime, cutime;
+#else
+        int64_t priority, lastpri = 0;
+        register int load, bestload;
+	int pri, bestpri;
         int mintime, very_mintime;
 	int minload;
+#endif
 
+#ifdef CONFIG_SSI
+	read_lock(&acpuse_lock);
+	bestpri = mintime = jiffies_to_msecs(acpuse) / (num_online_cpus() * MF) ;
+#else
 	mintime = ((MILLION * acpuse) / HZ) / (num_online_cpus() * MF) ;
+#endif
 	very_mintime = mintime / 3;
 	minload = 2 * acpuse / num_online_cpus();	/* normally 4*MF */
+#ifdef CONFIG_SSI
+	read_unlock(&acpuse_lock);
+#else
         bestpri = mintime;
         bestload = -1;
+#endif /* !CONFIG_SSI */
 	read_lock(&tasklist_lock);
 	if(!chosen_for_balance)
 	for_each_process(p)
@@ -459,7 +495,7 @@
         if(!((m = &p->mosix)->dflags & (DDEPUTY|DFINISHED|DPASSING)) &&
 		!m->stay && !m->whereto && p != chosen_for_mdp &&
 		(!mosadmin_mode_lstay || (m->dflags & DREMOTE)))
-#endif /* CONFIG_SSI */
+#endif /* !CONFIG_SSI */
         {
 #ifdef CONFIG_MOSIX_DIAG
 		if(LOGICAL_STATE(p) == TASK_ZOMBIE)
@@ -469,10 +505,29 @@
 		}
 #endif /* CONFIG_MOSIX_DIAG */
 #ifdef CONFIG_SSI
+		/* Following two blocks borrowed from Linux do_task_stat() */
+		utime = cutime = cputime_zero;
+		if (p->sighand) {
+			spin_lock_irq(&p->sighand->siglock);
+			/* add up live thread stats at the group level */
+			t = p;
+			do {
+				utime = cputime_add(utime, t->utime);
+				t = next_thread(t);
+			} while (t != p);
+			spin_unlock_irq(&p->sighand->siglock);
+		}
+		if (p->signal) {
+			cutime = p->signal->cutime;
+			utime = cputime_add(utime, p->signal->utime);
+		}
+		priority = cputime_to_msecs(cputime_add(cutime, utime));
+#if 0
 		/* With VPROCS we already do all the user & child time
 		 * accounting
 		 */
 		priority = ticks_to_ms(p->utime + p->signal->utime + p->signal->cutime);
+#endif
 #else
 		priority = ticks_to_ms(p->utime + m->uttime) +
 								m->cutime;
@@ -485,19 +540,27 @@
 #else
 			priority += io_cost(m, remote_here_adjusted);
 #endif /* CONFIG_MOSIX_TOPOLOGY */
-#endif /* CONFIG_SSI */
+#endif /* !CONFIG_SSI */
 		priority -= m->last_consider;
+#ifndef CONFIG_SSI
 		if(priority < 0)
 		/* it "should not" happen, but some operating systems (BSDI)
 		   can have user-time go back due to rounding... */
 			continue;
+#endif
 		pri = (priority > 4*MILLION) ? 4*MILLION : priority; /*4 secs*/
 if(Tload)
+#ifdef CONFIG_SSI
+	printk("process=%d, load=%lu pri=%u bestpri=%u mload=%lu, bload=%lu \n",
+					p->pid, m->load, pri, bestpri, minload,
+					bestload);
+#else
 	printk("process=%d, load=%d pri=%d bestpri=%d mload=%d, bload=%d \n",
 					p->pid, m->load, pri, bestpri, minload,
 					bestload);
+#endif
 #ifdef CONFIG_SSI
-		(void)ssi_do_decay();
+		ssi_do_decay(m);
 #endif
                 if(pri < bestpri)
                 {
@@ -532,9 +595,13 @@
 	}
         sel->mosix.last_consider += lastpri;
 	chosen_for_balance = sel;
+#ifdef CONFIG_SSI
+	load_balancing_counter = BALANCING_TIMEOUT;
+	mosix_do_add_to_whereto(sel, BALANCE);
+	/* whereto_lock unlocked */
+#else
 	mosix_do_add_to_whereto(sel, BALANCE);
 	load_balancing_counter = BALANCING_TIMEOUT;
-#ifndef CONFIG_SSI
 	if(sel->mosix.whereto != BALANCE)
 	{
 		put_task_struct(chosen_for_balance);
@@ -544,16 +611,25 @@
 #endif /* !CONFIG_SSI */
 #ifdef	CONFIG_MOSIX_DEBUG
 	if(ds_debug & (DSDEB_LOAD|DSDEB_CONSIDER))
+#ifdef CONFIG_SSI
+		printk("selected %s for load-balancing, pri=%d, load=%lu, priority=%d\n",
+			desc_mostask(&sel->mosix), (int)bestpri, bestload, (int)lastpri);
+#else
 		printk("selected %s for load-balancing, pri=%d, load=%d, priority=%d\n",
 			desc_mostask(&sel->mosix), (int)bestpri, bestload,
 			(int)lastpri);
+#endif
 #endif /* CONFIG_MOSIX_DEBUG */
 }
 
 void
 load_balance(void)
 {
+#ifdef CONFIG_SSI
+	unsigned long load;
+#else
 	register int load;
+#endif
 	register struct loadinfo *l;
 	int doit = 0;
 
@@ -564,8 +640,7 @@
 	load = altload(loadinfo[0].load, loadinfo[0].speed, loadinfo[0].ncpus);
 	for(l = &loadinfo[1]; l < &loadinfo[INFO_WIN] ; l++)
 #ifdef CONFIG_SSI
-	if(l->node && l->mem > 0 && l->speed &&
-				altload(l->load, l->speed, l->ncpus) < load)
+	if(l->node && l->mem && altload(l->load, l->speed, l->ncpus) <= load)
 #else
 	if(l->pe && l->mem > 0 && altload(l->load, l->speed, l->ncpus) <= load)
 #endif
@@ -576,18 +651,31 @@
 	}
 	read_unlock_bh(&loadinfo_lock);
 	if(doit)
+#ifdef CONFIG_SSI
+		/* Avoid stack overflow due to unchoose_me() recursion */
+		if (nsc_async_queue(nsc_generic_async_queue,
+					(void *)choose, NULL, 0, 0))
+			printk(KERN_WARNING "Failed to queue choose\n");
+#else
 		choose();
+#endif
 }
 
 void
 #ifdef SSI_BALANCE_MEMORY
-mchoose(unsigned long need)
+mchoose(void *arg)
 #else
 mchoose(int need)
 #endif
 {
+#ifdef SSI_BALANCE_MEMORY
+	unsigned long *need = (unsigned long *)arg;
+	unsigned long quality, bestquality = 0;
+	now_t df, diff = MIN_MCHOOSE_AGAIN;
+#else
 	int quality, bestquality = 0;
 	int df, diff = MIN_MCHOOSE_AGAIN;
+#endif
 	now_t dff;
 	struct task_struct *p, *sel = NULL;
 	register struct mosix_task *m;
@@ -602,7 +690,7 @@
         if(!((m = &p->mosix)->dflags & (DDEPUTY|DFINISHED|DPASSING)) &&
 		!m->stay && !m->whereto && p != chosen_for_balance &&
 		(!mosadmin_mode_lstay || (m->dflags & DREMOTE)))
-#endif /* CONFIG_SSI */
+#endif /* !CONFIG_SSI */
 	{
 #ifdef CONFIG_MOSIX_DIAG
 		if(LOGICAL_STATE(p) == TASK_ZOMBIE)
@@ -618,7 +706,11 @@
 			df = dff;
 		if(df < diff)
 			continue;
+#ifdef SSI_BALANCE_MEMORY
+		quality = memory_relief_quality(p, *need);
+#else
 		quality = memory_relief_quality(p, need);
+#endif
 		if(quality > bestquality || (quality > 0 && df > diff))
                 {
 			if(sel)
@@ -642,9 +734,13 @@
 	sel->mosix.page_allocs = 0;
 	sel->mosix.last_mconsider = time_now();
 	chosen_for_mdp = sel;
+#ifdef CONFIG_SSI
+	memory_balancing_counter = BALANCING_TIMEOUT;
+	mosix_do_add_to_whereto(sel, MEMBALANCE);
+	/* whereto_lock unlocked */
+#else
 	mosix_do_add_to_whereto(sel, MEMBALANCE);
 	memory_balancing_counter = BALANCING_TIMEOUT;
-#ifndef CONFIG_SSI
 	if(sel->mosix.whereto != MEMBALANCE)
 	{
 		put_task_struct(chosen_for_mdp);
@@ -655,7 +751,7 @@
 #ifdef	CONFIG_MOSIX_DEBUG
 	if(ds_debug & DSDEB_CONSIDER)
 		printk("selected %s for memory-balancing, quality=%d\n",
-			desc_mostask(&sel->mosix), bestquality);
+			desc_mostask(&sel->mosix), (int)bestquality);
 #endif
 }
 
@@ -670,36 +766,53 @@
 #endif
 	int doit = 0;
 
-	if(mosadmin_mode_stay || mosadmin_mode_quiet
 #ifdef SSI_BALANCE_MEMORY
-	   || !memory_badly_required(&need))
+	if(mosadmin_mode_stay || mosadmin_mode_quiet ||
+	   !memory_badly_required(&need))
+		return;
 #else
+	if(mosadmin_mode_stay || mosadmin_mode_quiet
 	   || (need = memory_badly_required()) <= 0)
-#endif
 		return;
+#endif
 	read_lock_bh(&loadinfo_lock);
 	for(l = &loadinfo[1]; l < &loadinfo[INFO_WIN] ; l++)
 #ifdef CONFIG_SSI
 	if(l->node && (l->mem > MIN_EXPECTED_PROC_SIZE))
 #else
 	if(l->pe && l->mem > MIN_EXPECTED_PROC_SIZE)
-#endif /* CONFIG_SSI */
+#endif /* !CONFIG_SSI */
 	{
 		doit = 1;
 		break;
 	}
 	read_unlock_bh(&loadinfo_lock);
+#ifdef CONFIG_SSI
+	if(doit) {
+		unsigned long *arg;
+
+		arg = kmalloc_nofail(sizeof(*arg));
+		*arg = need;
+		/* Avoid stack overflow due to unchoose_me() recursion */
+		if (nsc_async_queue(nsc_generic_async_queue,
+				(void *)mchoose, arg, sizeof(*arg),
+				NSC_ASYNC_ARGS_FREE))
+			printk(KERN_WARNING "Failed to queue mchoose\n");
+	}
+#else
 	if(doit)
 		mchoose(need);
+#endif
 }
 
+#ifndef CONFIG_SSI
+#if 0
 void
 changed_my_mind_and_staying(void)
 {
 	current->mosix.pages_i_bring = 0;
 }
 
-#ifndef CONFIG_SSI
 void
 ask_deputy_to_goto(int where)
 {
@@ -712,6 +825,7 @@
 	if(where)
 		comm_free(head);
 }
+#endif /* if 0 */
 #endif /* !CONFIG_SSI */
 
 struct sonstats
@@ -743,7 +857,14 @@
 #endif /*MAX_CONSIDERED*/
 	struct task_struct *p = current;
 	register struct mosix_task *m = &p->mosix;
+#ifdef CONFIG_SSI
+	struct task_struct *t;
+	cputime_t utime, cutime;
+	clusternode_t mach[MAX_CONSIDERED];
+	unsigned long aload[MAX_CONSIDERED];
+#else
 	int mach[MAX_CONSIDERED], aload[MAX_CONSIDERED];
+#endif
 #ifdef CONFIG_MOSIX_TOPOLOGY
 	struct costinfo
 	{
@@ -807,7 +928,7 @@
 	m->migpages = run_over_dirty_pages(NULL, 0);
 #else
 	m->migpages = count_migrating_pages();
-#endif /* CONFIG_SSI */
+#endif
 #ifdef CONFIG_MOSIX_FS
 	if(sons && sons->mfs.nnodes)
 	{
@@ -822,6 +943,7 @@
 		printk("Aloads: ");
 #endif /* CONFIG_MOSIX_DEBUG */
 #ifndef CONFIG_SSI
+#if 0
 	if(remote)
 	{
 		if(remote_request(REM_GETALOAD, NULL, 0, NULL, 0, 0,
@@ -845,6 +967,7 @@
 #endif /* CONFIG_MOSIX_FS && CONFIG_MOSIX_TOPOLOGY */
 		mach[n++] = GOBACKHOME;
 	}
+#endif /* if 0 */
 #endif /* !CONFIG_SSI */
 	read_lock_bh(&loadinfo_lock);
 	for(i = 0 ; i < INFO_WIN ; i++)
@@ -856,8 +979,8 @@
 		&& (i == 0 || (loadinfo[i].mem >= m->migpages)))
 #else
 	if(loadinfo[i].pe && loadinfo[i].pe != depmach
-#endif /* CONFIG_SSI */
-#endif /* CONFIG_MOSIX_CHEAT_MIGSELF */
+#endif /* !CONFIG_SSI */
+#endif /* !CONFIG_MOSIX_CHEAT_MIGSELF */
 #ifndef CONFIG_SSI
 		&& (i == 0 || (loadinfo[i].mem >= m->migpages &&
 						loadinfo[i].free_slots)))
@@ -897,10 +1020,11 @@
 		if(ds_debug & DSDEB_CONSIDER)
 #ifdef CONFIG_SSI
 			printk("%u=%d==>%d, ", loadinfo[i].node,
-#else /* CONFIG_SSI */
+					(int)loadinfo[i].load, (int)aload[n]);
+#else
 			printk("%d=%d==>%d, ", loadinfo[i].pe,
-#endif /* !CONFIG_SSI */
 					(int)loadinfo[i].load, aload[n]);
+#endif /* !CONFIG_SSI */
 #endif /* CONFIG_MOSIX_DEBUG */
 		n++;
 	}
@@ -978,13 +1102,32 @@
 	kernel_fpu_begin();
 #endif
 #ifdef CONFIG_SSI
-	ms = (ticks_to_ms(p->utime+p->stime) - m->dctime) / HZ;
-	if (!ms)
-		ms = 2;
-	tim = ms * cpuspeed / STD_SPD;
+	/* Following two blocks borrowed from Linux do_task_stat() */
+	utime = cutime = cputime_zero;
+	read_lock(&tasklist_lock);
+	if (p->sighand) {
+		spin_lock_irq(&p->sighand->siglock);
+		/* add up live thread stats at the group level */
+		t = p;
+		do {
+			utime = cputime_add(utime, t->utime);
+			t = next_thread(t);
+		} while (t != p);
+		spin_unlock_irq(&p->sighand->siglock);
+	}
+	if (p->signal) {
+		cutime = p->signal->cutime;
+		utime = cputime_add(utime, p->signal->utime);
+	}
+	read_unlock(&tasklist_lock);
+	/* ms = (ticks_to_ms(p->utime+p->stime) - m->dctime) / HZ; */
+	ms = cputime_to_msecs(cputime_add(cutime, utime)) - m->dctime;
+	tim = (ms ? : 2) * cpuspeed / STD_SPD;
+#ifdef CONFIG_MOSIX_DEBUG
 	if (ds_debug & DSDEB_CONSIDER)
-		printk("tim=%lld ms=%lld cpuspd=%d STD=%d HZ=%d\n",
+		printk("tim=%lld ms=%lld cpuspd=%ld STD=%d HZ=%d\n",
 			tim, ms, cpuspeed, STD_SPD, HZ);
+#endif /* CONFIG_MOSIX_DEBUG */
 #else
 	ms = ticks_to_ms(p->utime+m->uttime) + m->cutime - m->dctime;
 	if(sons)
@@ -997,7 +1140,7 @@
 	/* Currently not doing MEMBALANCE for OpenSSI */
 	if(reason == MEMBALANCE)
 		tim += (m->pagetime + (sons ? sons->pagetime : 0)) / DMILLION;
-#endif /* CONFIG_SSI */
+#endif /* !CONFIG_SSI */
 #ifdef CONFIG_MOSIX_DEBUG
 	if (ds_debug & DSDEB_CONSIDER)
 		printk("tim=%lld\n",  tim);
@@ -1065,7 +1208,6 @@
 		m->copyinbytes -= sons->copyinbytes;
 		unlock_mosix();
 	}
-#endif /* !CONFIG_SSI */
 #ifdef CONFIG_MOSIX_FS
 	if(!mfs_tot)
 		goto skip_comm;
@@ -1105,18 +1247,28 @@
 #endif /* CONFIG_MOSIX_DEBUG */
 	skip_comm:
 #endif /* CONFIG_MOSIX_FS */
+#endif /* !CONFIG_SSI */
 	if (reason != MEMBALANCE)
 	{
 		/* migration cost: */
+#ifdef CONFIG_SSI
+		/* SSI_XXX: fudge costs for now */
+		/* MIGRATION_BASIC + m->migpages * MIGRATION_PER_PAGE */
+		tim = HZ + m->migpages * HZ / 20;
+
+		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);
+		}
+#else
 		double decay_factor;
 
 		if(m->dctime > 0)	/* decay occured */
 		{
-#ifdef CONFIG_SSI
-			ms = ticks_to_ms(p->utime);
-#else
 			ms = ticks_to_ms(p->utime + m->uttime);
-#endif /* CONFIG_SSI */
 			if(ms)
 				decay_factor = ((double)(ms - m->dctime)) / ms;
 			else
@@ -1130,6 +1282,7 @@
 		else
 			decay_factor = 1.0;
 		decay_factor /= DMILLION; /* to save multiple divisions later */
+#endif /* !CONFIG_SSI */
 #ifdef CONFIG_MOSIX_TOPOLOGY
 		for(i = 0 ; i < n ; i++)
 		if(i != remote)
@@ -1140,7 +1293,11 @@
 				m->migpages * mosix_cost[j].MIGRATION_PER_PAGE);
 		}
 #else
-#ifndef CONFIG_SSI
+#ifdef CONFIG_SSI
+		for(i = 0 ; i < n ; i++)
+		if(i != remote)
+			costs[i] += tim;
+#else
 		tim = decay_factor * (mosix_cost[0].MIGRATION_BASIC +
 			m->migpages * mosix_cost[0].MIGRATION_PER_PAGE);
 		for(i = 0 ; i < n ; i++)
@@ -1264,15 +1421,14 @@
 		m = 1;
 	}
 	spin_unlock_irq(&whereto_lock);
-#ifndef CONFIG_SSI
 	if(l)
 		load_balance();
 	else if(m)
 		memory_balance();
-#endif
 }
 
 #ifndef CONFIG_SSI
+#if 0
 int
 mosix_forkmigrate(void)
 {
@@ -1421,6 +1577,7 @@
 	info_someone_came_in();
 	return(1);
 }
+#endif /* if 0 */
 #endif /* !CONFIG_SSI */
 
 #ifdef CONFIG_SSI
@@ -1449,7 +1606,23 @@
 void
 migrate_process_now(struct task_struct *p)
 {
+#ifdef TASK_HOLD_VPROC
+	struct vproc *vp;
+
+	/* Silently fail if a kernel daemon. */
+	if (p->mm == NULL)
+		return;
+
+	vp = p->p_vproc;
+	if (!VPROC_HOLD_AND_CHECK(vp, "migrate_process_now"))
+		return;
+
+	if (vproc_migrate_local(vp, CLUSTERNODE_BEST) < 0)
+		unchoose_me(p);
+	VPROC_RELE(vp, "migrate_process_now");
+#else
 	proc_migrate(p, CLUSTERNODE_BEST);
+#endif
 }
 
 void cleanup_load(clusternode_t node)
@@ -1463,13 +1636,14 @@
 #endif
 }
 
-void ssi_do_decay(void)
+void ssi_do_decay(struct mosix_task *m)
 {
-	register struct mosix_task *m = &current->mosix;
+	/* register struct mosix_task *m = &current->mosix; */
 	int d = m->decay;
 	int64_t ms;
 
-	ms = ticks_to_ms(current->utime) - m->dctime;
+	/* ms = ticks_to_ms(current->utime) - m->dctime; */
+	ms = cputime_to_msecs(current->utime) - m->dctime;
 #ifdef CONFIG_MOSIX_DEBUG
 	if(ds_debug & DSDEB_DECAY)
 		printk("decaying %s by adding %d/%d of %d to %d\n",

Index: freemem.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/freemem.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- freemem.c	10 Oct 2008 08:10:32 -0000	1.8
+++ freemem.c	27 Oct 2009 03:18:29 -0000	1.9
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <asm/pgtable.h>
 #ifdef CONFIG_SSI
+#include <asm/tlbflush.h>
 #include <cluster/ssi/mosixll/routines.h>
 #include <cluster/ssi/mosixll/debug.h>
 #include <cluster/ssi/mosixll/defs.h>
@@ -38,8 +39,7 @@
 
 #ifdef SSI_BALANCE_MEMORY
 unsigned long pages_to_keep_free;
-unsigned long latest_free_mem;
-static unsigned long marker;
+volatile unsigned long latest_free_mem;
 #else
 int pages_to_keep_free;
 int latest_free_mem;
@@ -47,15 +47,19 @@
 #endif
 static int sort_age_maxchunk;
 
-#ifndef SSI_BALANCE_MEMORY
-static inline int
-#else
+#ifdef SSI_BALANCE_MEMORY
 static inline unsigned long 
-#endif
+current_free_mem(void)
+{
+	return latest_free_mem;
+}
+#else
+static inline int
 current_free_mem(void)
 {
 	return(latest_free_mem);
 }
+#endif /* !SSI_BALANCE_MEMORY */
 
 #ifndef CONFIG_SSI
 int
@@ -84,13 +88,13 @@
 #endif
 {
 #ifdef SSI_BALANCE_MEMORY
-	unsigned long n, b = 0, s = 0;
+	unsigned long n, b = 0;
 	char do_need = 0;
 #else
 	register int n, s = 0;
+	struct mm_struct *mm;
 #endif
 	struct task_struct *p;
-	struct mm_struct *mm;
 
 #ifdef SSI_BALANCE_MEMORY
 	/* Free minus pages migrating to this node minus swap */
@@ -104,24 +108,23 @@
 	n = current_free_mem() - pages_to_keep_free;
 #endif
 	write_lock_irq(&tasklist_lock);
+#ifndef SSI_BALANCE_MEMORY
 	++marker;
+#endif
 	for_each_process(p)
 	{
-#ifndef SSI_BALANCE_MEMORY
-		n -= p->mosix.pages_i_bring;
-#endif
 #ifdef CONFIG_SSI
 #ifdef SSI_BALANCE_MEMORY
+		/* SSI: mosix.pages_i_bring is +ve. See release_migrations() */
 		b += p->mosix.pages_i_bring;
 #endif
 
 		if (p->mosix.stay)
 			continue;
 #else
-#ifdef SSI_BALANCE_MEMORY
 		n -= p->mosix.pages_i_bring;
-#endif
-#endif
+#endif /* !CONFIG_SSI */
+#ifndef SSI_BALANCE_MEMORY
 		task_lock(p);
 		if((mm = p->mm) && mm->mark != marker && mm->last_memsort)
 		{
@@ -129,6 +132,7 @@
 			mm->mark = marker;
 		}
 		task_unlock(p);
+#endif /* !SSI_BALANCE_MEMORY */
 	}
 	write_unlock_irq(&tasklist_lock);
 #ifdef SSI_BALANCE_MEMORY
@@ -138,11 +142,13 @@
 		else
 			n = b - n;
 			
-		if(n > 0 && n < MIN_EXPECTED_PROC_SIZE)
-			n = (long)MIN_EXPECTED_PROC_SIZE;
-		if(n > 0)
-			n += s;
-
+		if(n > 0) {
+			if (n < MIN_EXPECTED_PROC_SIZE)
+				n = (long)MIN_EXPECTED_PROC_SIZE;
+			else
+				/* n += s; */
+				n += nr_swap_pages;
+		}
 		*need = n;
 		return 1;
 	}
@@ -159,39 +165,58 @@
 #define	MDP_HIGHEST_QUALITY	(MIN_EXPECTED_PROC_SIZE * 10)
 
 /* "memory_relief_quality" is called with tasklist_lock read-locked */
-int
 #ifdef SSI_BALANCE_MEMORY
+unsigned long
 memory_relief_quality(struct task_struct *p, unsigned long need)
 #else
+int
 memory_relief_quality(struct task_struct *p, int need)
 #endif
 {
-	int q = 0;
 #ifdef SSI_BALANCE_MEMORY
-	unsigned long used, unused, swapped;	/* (dirty pages only) */
+	unsigned long q = 0;
+	unsigned long used, swapped;	/* (dirty pages only) */
 #else
+	int q = 0;
 	int used, unused, swapped;	/* (dirty pages only) */
 #endif
 	struct mm_struct *mm;
 
+#ifndef SSI_BALANCE_MEMORY
 	read_lock(&tasklist_lock);
+#endif
 	task_lock(p);
 	if(!(mm = p->mm) || !mm->last_memsort)
 	{
 		task_unlock(p);
+#ifndef SSI_BALANCE_MEMORY
 		read_unlock(&tasklist_lock);
+#endif
 		return(0);
 	}
 	used = mm->used;
+#ifndef SSI_BALANCE_MEMORY
 	unused = mm->unused;
+#endif
 	swapped = mm->swapped;
 	task_unlock(p);
+#ifndef SSI_BALANCE_MEMORY
 	read_unlock(&tasklist_lock);
+#endif
+#ifdef SSI_BALANCE_MEMORY
+	if (used >= need) {
+		if (used < 2 * need)
+			q = MDP_HIGHEST_QUALITY * (150 - used * 50 / need) / 100;
+		else
+			q = MDP_HIGHEST_QUALITY * need / (1 + used - need);
+	} else
+#else
 	if (used >= need && used < 2 * need)
 		q = MDP_HIGHEST_QUALITY * (150 - used * 50 / need) / 100;
 	else if(used >= need)
 		q = MDP_HIGHEST_QUALITY * need / (1 + used - need);
 	else if (used < need)
+#endif /* !SSI_BALANCE_MEMORY */
 	{
 		if(need > MDP_HIGHEST_QUALITY/2)
 			q = MDP_HIGHEST_QUALITY / 2 * used / need;
@@ -204,8 +229,8 @@
 #ifdef CONFIG_MOSIX_DEBUG
 	if(ds_debug & DSDEB_MEM)
 #ifdef SSI_BALANCE_MEMORY
-		printk("relief_quality(need=%lu,used=%lu,unused=%lu,swapped=%lu)"
-			"=%d\n", need, used, unused, swapped, q);
+		printk("relief_quality(need=%lu,used=%lu,swapped=%lu)"
+			"=%lu\n", need, used, swapped, q);
 #else
 		printk("relief_quality(need=%d,used=%d,unused=%d,swapped=%d)"
 			"=%d\n", need, used, unused, swapped, q);
@@ -226,16 +251,22 @@
 compute_freemem(void)
 {
 	static int trouble_time;
-#ifdef SSI_BALANCE_MEMORY
-	unsigned long count, buffered, kernel, inactive, cached, tasked,
-			active, free;
-#else
+#ifndef SSI_BALANCE_MEMORY
 	int count;
 	int buffered, kernel, inactive, cached, tasked;
+#else
+	unsigned long count;
 #endif
 
+#ifdef CONFIG_SSI
+	read_lock(&acpuse_lock);
+#endif
 	if(acpuse < MF * num_online_cpus() * UTIL_TOLLERANCE)
 		trouble_time = 11;
+#ifdef CONFIG_SSI
+	read_unlock(&acpuse_lock);
+#endif
+#ifndef SSI_BALANCE_MEMORY
 	tasked = 0;
 	if(trouble_time && --trouble_time > 0)
 		buffered = kernel = inactive = cached = 0;
@@ -244,18 +275,9 @@
 		struct task_struct *p;
 		struct mm_struct *mm;
 #ifdef CONFIG_SSI
-#ifdef SSI_BALANCE_MEMORY
-		struct sysinfo i;
-
-		si_meminfo(&i);
-		buffered = i.bufferram;
-		free = i.freeram;
-#else
-		/* SSI_XXX: buffermem_pages no longer exists
-		 * For now setting buffered to 0, until proper variable determined
-		 */
-		buffered = 0;
-#endif /* !SSI_BALANCE_MEMORY */
+		/* Refer meminfo_read_proc() */
+		//si_meminfo(&i);
+		buffered = nr_blockdev_pages();
 #else
 		buffered = atomic_read(&buffermem_pages);
 #endif /* !CONFIG_SSI */
@@ -263,17 +285,8 @@
 			  inodes_stat.nr_unused * sizeof(struct inode))
 			  >> PAGE_SHIFT;
 #ifdef CONFIG_SSI
-#ifndef SSI_BALANCE_MEMORY
-		/* SSI_XXX: nr_inactive_pages no longer exists
-		 * For now setting inactive and cached to 0, 
-		 * until proper variables are determined
-		 */
-		inactive = 0;
-		cached = 0;
-#else
 		get_zone_counts(&active, &inactive, &free);
 		cached = get_page_cache_size()-total_swapcache_pages-i.bufferram;
-#endif /* SSI_BALANCE_MEMORY */
 #else
 		inactive = nr_inactive_clean_pages() +
 			nr_inactive_dirty_pages();
@@ -294,9 +307,6 @@
 		}
 		read_unlock(&tasklist_lock);
 	}
-#ifdef SSI_BALANCE_MEMORY
-	count = free + buffered + kernel + inactive + cached + tasked;
-#else
 	count = nr_free_pages() + buffered + kernel + inactive + cached +
 									tasked;
 #ifdef CONFIG_MOSIX_DEBUG
@@ -305,23 +315,66 @@
 			"count=%d/%lu\n", nr_free_pages(), buffered, kernel,
 			inactive, cached, tasked, count, num_physpages);
 #endif /* CONFIG_MOSIX_DEBUG */
-#endif
 	if(count >= num_physpages)	/* whatever went wrong... */
 		count = num_physpages - 1;
 	if(count < 0)
 		count = 0;
 	latest_free_mem = count;
+#else /* SSI_BALANCE_MEMORY */
+	if (trouble_time && --trouble_time > 0) {
+		count = 0;
+	} else {
+		/* Taken from Linux-2.6.11 mm/mmap.c:__vm_enough_memory()
+		 * where sysctl_overcommit_memory == OVERCOMMIT_GUESS
+		 */
+		count = get_page_cache_size();
+		/* count += nr_swap_pages; */
+
+		/*
+		 * Any slabs which are created with the
+		 * SLAB_RECLAIM_ACCOUNT flag claim to have contents
+		 * which are reclaimable, under pressure.  The dentry
+		 * cache and most inode caches should fall into this
+		 */
+		/* count += atomic_read(&slab_reclaim_pages); */
+
+		/*
+		 * nr_free_pages() is very expensive on large systems,
+		 * only call if we're about to fail.
+		 */
+		count += nr_free_pages();
+
+		/*
+		 * Leave the last 3% for root
+		 */
+		count -= count / 32;
+	}
+	/* Avoid race with move_eligible_processes_off() */
+	if (atomic_read(&loadlevel_on))
+		set_mb(latest_free_mem, count);
+#endif /* SSI_BALANCE_MEMORY */
 }
 
 static inline int
 sort_interval(int initial)
 {
+#ifdef SSI_BALANCE_MEMORY
+	unsigned long free_mem = current_free_mem();
+
+	if(free_mem < pages_to_keep_free)
+		return(initial ? 0 : 3*HZ);
+	else if(free_mem < 2 * pages_to_keep_free)
+		return(initial ? 2*HZ : 4*HZ);
+	else if(free_mem < 4 * pages_to_keep_free)
+		return(initial ? 4*HZ : 8*HZ);
+#else
 	if(latest_free_mem < pages_to_keep_free)
 		return(initial ? 0 : 3*HZ);
 	else if(latest_free_mem < 2 * pages_to_keep_free)
 		return(initial ? 2*HZ : 4*HZ);
 	else if(latest_free_mem < 4 * pages_to_keep_free)
 		return(initial ? 4*HZ : 8*HZ);
+#endif
 	else
 		return(10*HZ);
 }
@@ -334,7 +387,7 @@
 sort_and_age_pages(struct mm_struct *mm)
 {
 #ifdef SSI_BALANCE_MEMORY
-	unsigned long used = 0, unused = 0, swapped = 0, private_unused = 0;
+	unsigned long used = 0, swapped = 0;
 #else
 	int used = 0, unused = 0, swapped = 0, private_unused = 0;
 #endif
@@ -413,7 +466,9 @@
 		}
 		if(PageLRU(page))
 		{
+#ifndef SSI_BALANCE_MEMORY
 			unused++;
+#endif
 			continue;
 		}
 		if(time_before(jiffies, page->last_young + OLD_SECONDS * HZ))
@@ -429,8 +484,10 @@
 			used++;
 			continue;
 		}
+#ifndef SSI_BALANCE_MEMORY
 		unused++;
 		private_unused++;
+#endif
 	}
 				pte_unmap(pte_dir);
 			}
@@ -441,16 +498,17 @@
 	spin_unlock(&mm->page_table_lock);
 	write_lock_irq(&tasklist_lock);
 	mm->used = used;
-	mm->unused = unused;
 	mm->swapped = swapped;
+#ifndef SSI_BALANCE_MEMORY
+	mm->unused = unused;
 	mm->private_unused = private_unused;
+#endif
 	mm->last_memsort = jiffies ? : 1;
 	write_unlock_irq(&tasklist_lock);
 #ifdef CONFIG_MOSIX_DEBUG
 	if(ds_debug & DSDEB_SUPERMEM)
 #ifdef SSI_BALANCE_MEMORY
-		printk("memory: used=%lu, unused=%lu (%lu private), swapped=%lu\n",
-					used, unused, private_unused, swapped);
+		printk("memory: used=%lu, swapped=%lu\n", used, swapped);
 #else
 		printk("memory: used=%d, unused=%d (%d private), swapped=%d\n",
 					used, unused, private_unused, swapped);
@@ -467,8 +525,10 @@
 	struct mm_struct *mm;
 	struct mm_struct **mms, **newmms;
 #ifdef SSI_BALANCE_MEMORY
+#ifdef SSI_SKIP
 	struct zone *zone;
 #endif
+#endif
 	int i, n, mmno = 100, need_increase = 0;
 	int interval;
 
@@ -507,7 +567,7 @@
                 if (!PE)
 #ifdef CONFIG_SSI
 			continue;
-		if (!loadlevel_on && !latest_free_mem)
+		if (!atomic_read(&loadlevel_on) && !latest_free_mem)
 			continue;
 #else
 			wait_for_mosix_configuration(NULL);
@@ -527,15 +587,22 @@
 		interval = sort_interval(0);
 		n = 0;
 		write_lock_irq(&tasklist_lock);
+#ifndef SSI_BALANCE_MEMORY
 		++marker;
+#endif
 		for_each_process(p)
 		if(!(p->mosix.stay & DSTAY_PER_MM))
 		{
 			task_lock(p);
 			mm = p->mm;
+#ifdef SSI_BALANCE_MEMORY
+			if((mm = p->mm) && mm != &init_mm &&
+			   time_before(mm->last_memsort + interval, jiffies))
+#else
 			if((mm = p->mm) && mm != &init_mm && mm->mark != marker
 				&& time_before(mm->last_memsort + interval,
 								jiffies))
+#endif
 			{
 				if(n >= mmno)
 					need_increase = 1;
@@ -543,7 +610,9 @@
 				{
 					atomic_inc(&mm->mm_users);
 					mms[n++] = mm;
+#ifndef SSI_BALANCE_MEMORY
 					mm->mark = marker;
+#endif
 				}
 			}
 			task_unlock(p);
@@ -552,7 +621,9 @@
 		for(i = 0 ; i < n ; i++)
 		{
 			mm = mms[i];
+#ifndef SSI_BALANCE_MEMORY
 			if(atomic_read(&mm->mm_realusers) > 0)
+#endif
 				sort_and_age_pages(mm);
 			mmput(mm);
 		}
@@ -575,8 +646,10 @@
 		 */
 		wake_up_interruptible(&kswapd_wait);
 #else
+#ifdef SSI_SKIP
 		for_each_zone(zone)
 			wakeup_kswapd(zone, 0);
+#endif
 #endif /* SSI_BALANCE_MEMORY */
 	}
 }

Index: info.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/info.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- info.c	10 Oct 2008 08:10:32 -0000	1.8
+++ info.c	27 Oct 2009 03:18:29 -0000	1.9
@@ -23,7 +23,7 @@
 #include <mos/defs.h>
 #include <mos/routines.h>
 #include <mos/protocol.h>
-#endif /* CONFIG_SSI */
+#endif /* !CONFIG_SSI */
 #include <net/sock.h>
 #include <linux/mosix.h>
 #include <asm/uaccess.h>
@@ -39,10 +39,14 @@
 static int info_seed1, info_seed2;
 #endif /* !CONFIG_SSI */
 
-DEFINE_RWLOCK(loadinfo_lock); 
-DEFINE_SPINLOCK(uplist_lock);
+#ifdef CONFIG_SSI
+__cacheline_aligned_in_smp DEFINE_RWLOCK(loadinfo_lock);
 
-#ifndef CONFIG_SSI
+struct loadinfo *loadinfo;
+#else
+#if 0
+DEFINE_RWLOCK(loadinfo_lock);
+DEFINE_SPINLOCK(uplist_lock);
 struct uplist {
 	struct uplist *next;
 	unsigned short pe;
@@ -52,11 +56,9 @@
 static struct uplist uplist[MAXKNOWNUP];
 static struct uplist *uphead, *upfree;
 static int info_nup;		/* number of processes in uplist */
-#endif /* !CONFIG_SSI */
 
 struct loadinfo loadinfo[INFO_WIN];
 
-#ifndef CONFIG_SSI
 static int info_recv_message(struct infomsg *, int);
 static int info_send_message(int, struct infomsg *);
 static void update_uplist(struct loadinfo *);
@@ -321,12 +323,17 @@
 	memcpy(loadinfo[0].mfscosts, mfs_cost, sizeof(mfs_cost));
 #endif /* CONFIG_MOSIX_TOPOLOGY */
 }
+#endif /* if 0 */
 #endif /* !CONFIG_SSI */
 
 void
 set_my_cpuspeed(void)
 {
+#ifdef CONFIG_SSI
+	unsigned long s = cpuspeed;
+#else
 	int s = cpuspeed;
+#endif
 
 	if(sizeof(loadinfo[0].speed) < 4 && s > 65535)
 	{
@@ -359,6 +366,7 @@
 }
 
 #ifndef CONFIG_SSI
+#if 0
 void
 info_startup(void)
 {
@@ -952,6 +960,7 @@
 	else
 		return((((info_seed2+1)*info_seed1+1) & 0x7fffffff) % modulo);
 }
+#endif /* if 0 */
 #endif /* !CONFIG_SSI */
 
 /*
@@ -966,10 +975,12 @@
 	struct runqueue *rq;
 	unsigned long flags;
 	register struct mosix_task *m = &p->mosix;
-	register int load, i;
 #ifdef CONFIG_SSI
+	register int i;
+	unsigned long load;
 	unsigned long pages = m->migpages ? : run_over_dirty_pages(NULL, 0);
 #else
+	register int load, i;
 	int pages = m->migpages ? : count_migrating_pages();
 
 	this_machine_is_favourite(whereto);
@@ -986,22 +997,24 @@
 	  /* 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
 	if(ds_debug & (DSDEB_LOADS|DSDEB_CONSIDER))
 		printk("local load down by %d to %d due to leaving (to %d)\n",
-					load, (int)loadinfo[0].load, whereto);
+					(int)load, (int)loadinfo[0].load, whereto);
 #endif
 
 	/* increase the receiver's-load */
 	for(i = 1 ; i < INFO_WIN ; i++)
 #ifdef CONFIG_SSI
 	if(loadinfo[i].node == whereto)
-#else /* CONFIG_SSI */
+#else
 	if(loadinfo[i].pe == whereto)
-#endif /* CONFIG_SSI */
+#endif
 	{
 		/* add slightly more than 1 process worth of load */
 		loadinfo[i].load += MF * 102 * STD_SPD/
@@ -1025,11 +1038,20 @@
 		break;
 	}
 	write_unlock_bh(&loadinfo_lock);
+#ifdef CONFIG_SSI
+	down(&load_left_lock);
+	load_left += load;
+	up(&load_left_lock);
+#endif
 #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
+	m->pages_i_bring = pages; /* discourage 'memory_badly_required' */
+#else
 	m->pages_i_bring = -pages; /* discourage 'memory_badly_required' */
+#endif
 #ifdef CONFIG_SSI
 	unchoose_me(current);
 #else
@@ -1037,6 +1059,8 @@
 #endif
 }
 
+#ifndef CONFIG_SSI
+#if 0
 void
 info_someone_came_in(void)
 {
@@ -1069,3 +1093,5 @@
 			coming_in, came_lately4);
 #endif
 }
+#endif /* if 0 */
+#endif /* !CONFIG_SSI */

Index: kernel.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/kernel.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- kernel.c	10 Oct 2008 08:10:32 -0000	1.8
+++ kernel.c	27 Oct 2009 03:18:29 -0000	1.9
@@ -47,16 +47,22 @@
 
 /************* some MOSIX global variables: *************/
 
+#if defined(CONFIG_MOSIX_DIAG) && defined(CONFIG_SMP)
 DEFINE_SPINLOCK(mosix_flag); 
-DEFINE_SPINLOCK(whereto_lock);
+#endif
 #ifdef CONFIG_SSI
+__cacheline_aligned_in_smp DEFINE_SPINLOCK(whereto_lock);
+#ifdef SSI_SKIP
 int active_cpu_list[NR_CPUS];
+#endif
+unsigned long cpuspeed = STD_SPD;
 #else
+DEFINE_SPINLOCK(whereto_lock);
 int active_cpus;
-#endif
+int mosix_running;
 int cpuspeed = STD_SPD;
+#endif
 int standard_speed = STD_SPD;
-int mosix_running;
 struct task_struct *chosen_for_balance, *chosen_for_mdp;
 
 #ifdef CONFIG_MOSIX_DEBUG
@@ -117,6 +123,7 @@
         /*NOTREACHED*/
 }
 
+/* Called with spin_lock_irq on whereto_lock */
 inline void
 mosix_do_add_to_whereto(struct task_struct *p, int w)
 {
@@ -133,6 +140,7 @@
 		spin_unlock_irq(&whereto_lock);
 		return;
 	}
+	/* Release whereto_lock for VProc context */
 	spin_unlock_irq(&whereto_lock);
 	wake_up_mosix(p);
 #else
@@ -157,6 +165,9 @@
 void
 mosix_add_to_whereto(struct task_struct *p, int w)
 {
+#ifdef CONFIG_SSI
+	panic("%s: function not supported", __FUNCTION__);
+#endif
 	spin_lock_irq(&whereto_lock);
 	mosix_do_add_to_whereto(p, w);
 	spin_unlock_irq(&whereto_lock);
@@ -238,7 +249,11 @@
 	task_lock(me);
 	me->mosix.stay |= reasons;
 	task_unlock(me);
+#ifdef SSI_BALANCE_MEMORY
+	if(atomic_read(&mm->mm_users) > 1)
+#else
 	if(atomic_read(&mm->mm_realusers) > 1)
+#endif
 	{
 		read_lock(&tasklist_lock);
 		for_each_process(p)
@@ -640,7 +655,9 @@
 	if(p->pid == 1)
 		m->stay |= DSTAY_ITS_INIT;
 #ifdef CONFIG_SSI
-	m->decay = DECAY_QUOTIENT;
+	/* 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
@@ -1117,6 +1134,7 @@
 #endif /* !CONFIG_SSI */
 }
 
+#ifndef CONFIG_SSI
 int
 mosix_pre_clone(void)
 {
@@ -1155,6 +1173,7 @@
 		read_unlock(&tasklist_lock);
 	}
 }
+#endif /* !CONFIG_SSI */
 
 /* 'run_on' and 'run_off' must be called with the runqueue_lock! */
 void
@@ -1162,7 +1181,9 @@
 {
 	if(!(p->mosix.dflags & DPAGEIN))
 	{
+#ifndef CONFIG_SSI
 		mosix_running++;
+#endif
 		p->mosix.runstart = load_ticks + 1;
 	}
 }
@@ -1172,10 +1193,11 @@
 {
 	if(!(p->mosix.dflags & DPAGEIN))
 	{
+#ifndef CONFIG_SSI
 		if (mosix_running > 0)
 			mosix_running--;
+#endif
 		p->mosix.ran += load_ticks + 1 - p->mosix.runstart;
-		mb();
 		p->mosix.runstart = 0;
 	}
 }


------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.