[SSI] openssi/kernel/cluster/ssi/mosixll balance.c, 1.13, 1.14 info.c, 1.10, 1.11 load.c, 1.8, 1.9 service.c, 1.7, 1.8

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-serv10005/kernel/cluster/ssi/mosixll

Modified Files:
      Tag: OPENSSI-FC
	balance.c info.c load.c service.c 
Log Message:
MOSIX:
- Fix race over elements in mosix_task struct. Use task_lock() to protect mosix_task->dctime, pages_i_bring, etc.
- Code clean up: choose(), consider(), mosix_calc_load().
- Fix release_migrations() using wrong lock for mosix_task->load.
- Remove unused pagetime, migpages in struct mosix_task.
- run_over_dirty_pages() to hold down_read(&mmap_sem) to avoid possible race. (#ifdef SSI_BALANCE_MEMORY)

VPROC:
- Use BKL to protect tty_old_pgrp in VProc context. (#ifdef PPROC_SETCTTY_SIGLOCK)


Index: load.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/load.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- load.c	17 Nov 2009 06:09:02 -0000	1.8
+++ load.c	18 Nov 2009 06:16:53 -0000	1.9
@@ -86,55 +86,40 @@
 unsigned int old_io_write;
 #endif /* CONFIG_MOSIX_RESEARCH */
 
+#ifdef CONFIG_SSI
+/* Locking:
+ * spin_lock_irqsave(&snap_load_lock)
+ * down(&load_left_lock)
+ * -> write_lock(&acpuse_lock)
+ * -> write_lock_bh(&loadinfo_lock)
+ */
 void
 mosix_calc_load(unsigned long unused)
 {
-#ifndef CONFIG_SSI
-	struct task_struct *p;
-	register struct mosix_task *m;
-	register int ladd, cpu, ticks;
-	int new_expload;
-	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;
 #ifdef DEBUG
 	static int display_counter = 0;
 #endif
-#ifdef CONFIG_MOSIX_RESEARCH
-	unsigned int new_io_read;
-	unsigned int new_io_write;
-	int major,disk;
-#endif /* CONFIG_MOSIX_RESEARCH */
 
-
-#ifdef CONFIG_SSI
-	/* SSI: mosix_calc_load() is no longer called from interrupt context
-	 * unlike openMosix.
-	 */
+	/* Disable interrupt to prevent mosix_snap_load() */
 	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)) /
 		(ticks * cpuspeed * num_online_cpus());
@@ -146,65 +131,28 @@
 		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
+
+	newload = (accload+64) / 128;
 	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(); */
-	read_lock(&tasklist_lock);
-	for_each_process(p)
-	{
-		m = &p->mosix;
-		if(m->runstart)
-		{
-			m->ran += ticks + 1 - m->runstart;
-			m->runstart = 1;
-		}
-		m->load = m->load * DECAY + m->ran * MF * 4*NEWDATA/ticks;
-		m->ran = 0;
-		m->page_allocs >>= 1;	/* decay in time */
-	}
-	read_unlock(&tasklist_lock);
-#endif
 
 #ifdef DEBUG
 	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, (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");
@@ -212,10 +160,10 @@
 			(int)accload, (int)upper_load, (int)ladd, (int)ticks);
 	}
 #endif /* DEBUG */
+
 	write_lock_bh(&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;
@@ -223,43 +171,15 @@
 	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
-        new_io_read = new_io_write = 0;
-        for (major = 0; major < DK_MAX_MAJOR; major++) {
-                for (disk = 0; disk < DK_MAX_DISK; disk++) {
-			new_io_read += kstat.dk_drive_rblk[major][disk];                                new_io_write += kstat.dk_drive_wblk[major][disk];
-	}
-        }
-
-        /* the sectors are 512 bytes size */
-
-        new_io_read = new_io_read >> 1;
-        new_io_write = new_io_write >> 1;
-        io_read_rate  = (new_io_read - old_io_read);
-        io_write_rate = (new_io_write - old_io_write);
-        old_io_read  = new_io_read;
-        old_io_write = new_io_write;
-#endif /* CONFIG_MOSIX_RESEARCH */
-
 	write_unlock_bh(&loadinfo_lock);
 
-#ifdef CONFIG_SSI
 	up(&load_left_lock);
+
 	/* SSI_XXX: Need inc_decays() ? */
 	age_balancing();
-#else
-	if((p = (struct task_struct *)info_proc))
-		send_sig(SIGALRM, p, 1);
-#endif /* !CONFIG_SSI */
 }
 
-#ifdef CONFIG_SSI
 /* Following path in interrupt context:
  * do_timer, mosix_snap_load, mosix_calc_process_loads
  */
@@ -301,7 +221,123 @@
 	}
 #endif
 }
+
+#else /* !CONFIG_SSI */
+void
+mosix_calc_load(unsigned long unused)
+{
+	struct task_struct *p;
+	register struct mosix_task *m;
+	register int ladd, cpu, ticks;
+	int new_expload;
+	static unsigned upper_load;    /* over estimated load */
+	static unsigned accload;       /* accumulated load (*128) */
+	unsigned new_cpuse;
+	unsigned new_came;
+	unsigned long newload;
+#ifdef DEBUG
+	static int display_counter = 0;
 #endif
+#ifdef CONFIG_MOSIX_RESEARCH
+	unsigned int new_io_read;
+	unsigned int new_io_write;
+	int major,disk;
+#endif /* CONFIG_MOSIX_RESEARCH */
+
+	ticks = load_ticks;
+	cpu = cpuse;
+	ladd = load_adder;
+	cpuse = load_adder = load_ticks = 0;
+
+	ladd = ladd * ((long long)(MF * STD_SPD)) /
+		(ticks * cpuspeed * num_online_cpus());
+	if(ladd * 128 > accload)	/* slowly up */
+		accload = accload * DECAY + ladd * 128 * NEWDATA;
+	else				/* quickly down */
+		accload = ladd * 128;
+	if(ladd >= upper_load)		/* quickly up */
+		upper_load = ladd;
+	else				/* very slowly down */
+		upper_load = (upper_load * 7 + ladd) / 8;
+	new_cpuse = (acpuse * 3 + cpu * MF / ticks + 3) / 4;
+	newload = (accload+64) / 128;
+	new_expload = (upper_load + stable_export +
+		came_lately4 * MF * STD_SPD /
+			(4 * cpuspeed * num_online_cpus())) *
+			MF * num_online_cpus() / new_cpuse;
+	if(newload < load_left)
+		newload = 0;
+	else
+		newload -= load_left;
+	newload = newload * MF * num_online_cpus() / new_cpuse;
+	new_came = came_lately4 * DECAY + coming_in * 4 * NEWDATA;
+
+#ifndef CONFIG_SSI
+	/* For SSI we moved this into mosix_calc_process_loads(); */
+	read_lock(&tasklist_lock);
+	for_each_process(p)
+	{
+		m = &p->mosix;
+		if(m->runstart)
+		{
+			m->ran += ticks + 1 - m->runstart;
+			m->runstart = 1;
+		}
+		m->load = m->load * DECAY + m->ran * MF * 4*NEWDATA/ticks;
+		m->ran = 0;
+		m->page_allocs >>= 1;	/* decay in time */
+	}
+	read_unlock(&tasklist_lock);
+#endif
+
+#ifdef DEBUG
+	if(Tvis)
+		printk("\0337\033[22;55HL=%d,E=%d,R=%d,U=%d  \0338",
+			(int)newload, (int)new_expload, mosix_running,
+			(int)new_cpuse);
+	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",
+			(int)accload, (int)upper_load, (int)ladd, (int)ticks);
+	}
+#endif /* DEBUG */
+	write_lock_bh(&loadinfo_lock);
+#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;
+	acpuse = new_cpuse;
+	came_lately4 = new_came;
+	load_left = 0;
+
+#ifdef CONFIG_MOSIX_RESEARCH
+        new_io_read = new_io_write = 0;
+        for (major = 0; major < DK_MAX_MAJOR; major++) {
+                for (disk = 0; disk < DK_MAX_DISK; disk++) {
+			new_io_read += kstat.dk_drive_rblk[major][disk];                                new_io_write += kstat.dk_drive_wblk[major][disk];
+	}
+        }
+
+        /* the sectors are 512 bytes size */
+
+        new_io_read = new_io_read >> 1;
+        new_io_write = new_io_write >> 1;
+        io_read_rate  = (new_io_read - old_io_read);
+        io_write_rate = (new_io_write - old_io_write);
+        old_io_read  = new_io_read;
+        old_io_write = new_io_write;
+#endif /* CONFIG_MOSIX_RESEARCH */
+
+	write_unlock_bh(&loadinfo_lock);
+
+	if((p = (struct task_struct *)info_proc))
+		send_sig(SIGALRM, p, 1);
+}
+#endif /* !CONFIG_SSI */
 
 void
 mosix_load_init(void)
@@ -341,10 +377,15 @@
 }
 
 /* Called by timer interrupt */
-void
 #ifdef CONFIG_SSI
+/* Acquires
+ * spin_lock(&snap_load_lock)
+ * read_lock(&tasklist_lock)
+ */
+void
 mosix_snap_load(unsigned long ticks)
 #else
+void
 mosix_snap_load(int ticks)
 #endif
 {

Index: balance.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/balance.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- balance.c	17 Nov 2009 06:09:02 -0000	1.13
+++ balance.c	18 Nov 2009 06:16:53 -0000	1.14
@@ -69,8 +69,8 @@
 void ssi_do_decay(struct mosix_task *);
 #endif /* CONFIG_SSI */
 
-#ifdef CONFIG_MOSIX_DEBUG
 #ifndef CONFIG_SSI
+#ifdef CONFIG_MOSIX_DEBUG
 char *
 fformat(char *buf, double v)
 {
@@ -141,8 +141,8 @@
 	*p = '\0';
 	return(buf);
 }
-#endif /* !CONFIG_SSI */
 #endif /* CONFIG_MOSIX_DEBUG */
+#endif /* !CONFIG_SSI */
 
 void
 age_balancing(void)
@@ -161,6 +161,8 @@
 	spin_unlock_irq(&whereto_lock);
 }
 
+#ifndef CONFIG_SSI
+#if 0
 void
 mosix_clear_statistics(void)
 {
@@ -233,7 +235,6 @@
 #endif /* CONFIG_MOSIX_FS */
 #endif /* CONFIG_MOSIX_TOPOLOGY */
 
-#ifndef CONFIG_SSI
 int64_t
 #ifdef CONFIG_MOSIX_TOPOLOGY
 io_cost(struct mosix_task *m, struct opcost *costs, int with)
@@ -278,7 +279,6 @@
 				io_cost(m, remote_here_adjusted));
 #endif /* CONFIG_MOSIX_TOPOLOGY */
 }
-#endif /* !CONFIG_SSI */
 
 #ifdef CONFIG_MOSIX_FS
 
@@ -308,7 +308,6 @@
 }
 #endif /* CONFIG_MOSIX_FS */
 
-#ifndef CONFIG_SSI
 void
 add_statistics_to_ancesstor(struct task_struct *p, struct task_struct *pp)
 {
@@ -392,6 +391,7 @@
 #endif /* CONFIG_MOSIX_DFSA */
 		m->nsyscalls += EVENT_COUNTER_VALUE;
 }
+#endif /* 0 */
 #endif /* !CONFIG_SSI */
 
 /*
@@ -454,61 +454,44 @@
 #endif /* if 0 */
 #endif /* !CONFIG_SSI */
 
+#ifdef CONFIG_SSI
+/* Locking: this function may acquire ...
+ * read_lock(&acpuse_lock)
+ * read_lock(&tasklist_lock)
+ * -> sighand->siglock
+ * task_lock()
+ * spin_lock_irq(&whereto_lock)
+ */
 void
 choose(void)
 {
-	struct task_struct *p, *sel = NULL;
+	struct task_struct *t, *p, *sel = NULL;
 	register struct mosix_task *m;
-#ifdef CONFIG_SSI
+        unsigned long minload, load, bestload = 0;
         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;
+	unsigned int pri, bestpri, mintime, very_mintime;
 	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 */
+
+	very_mintime = mintime / 3;
+
 	read_lock(&tasklist_lock);
+
 	if(!chosen_for_balance)
 	for_each_process(p)
-#ifdef CONFIG_SSI
 	if (!((m = &p->mosix)->stay) && p != chosen_for_mdp && !p->execnode &&
 					is_loadlevelable(p, NULL))
-#else
-        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 */
         {
-#ifdef CONFIG_MOSIX_DIAG
-		if(LOGICAL_STATE(p) == TASK_ZOMBIE)
-		{
-			mosix_panic("ZOMBIE without DFINISHED");
-			continue;
-		}
-#endif /* CONFIG_MOSIX_DIAG */
-#ifdef CONFIG_SSI
+#ifdef SSI_SKIP
+		/* With VPROCS we already do all the user & child time
+		 * accounting
+		 */
+		priority = ticks_to_ms(p->utime + p->signal->utime + p->signal->cutime);
+#else
 		/* Following two blocks borrowed from Linux do_task_stat() */
 		utime = cutime = cputime_zero;
 		if (p->sighand) {
@@ -526,13 +509,110 @@
 			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
+
+		task_lock(p);
+
+		priority -= m->last_consider;
+		pri = (priority > 4*MILLION) ? 4*MILLION : priority; /*4 secs*/
+
+#ifdef DEBUG
+if(Tload)
+	printk("process=%d, load=%lu pri=%u bestpri=%u mload=%lu, bload=%lu \n",
+					p->pid, m->load, pri, bestpri, minload,
+					bestload);
+#endif /* DEBUG */
+
+		ssi_do_decay(m);
+
+                if(pri < bestpri)
+                {
+                        if(bestpri == mintime &&
+				/* (thrashing, or (m->load <= minload)) */
+				m->load > minload && pri >= very_mintime)
+                                pri = mintime;
+                        else
+			{
+				task_unlock(p);
+                                continue;
+			}
+                }
+                load = m->load;
+		task_unlock(p);
+
+                if(pri > bestpri || load > bestload)
+                {
+                        bestload = load;
+			if(sel)
+				put_task_struct(sel);
+			get_task_struct(p);
+                        sel = p;
+                        bestpri = pri;
+			lastpri = priority;
+                }
+        }
+	read_unlock(&tasklist_lock);
+
+        if(!sel)
+		return;
+
+	spin_lock_irq(&whereto_lock);
+
+	if(chosen_for_balance)
+	{
+		spin_unlock_irq(&whereto_lock);
+		put_task_struct(sel);
+		return;
+	}
+
+	task_lock(sel);
+        sel->mosix.last_consider += lastpri;
+	task_unlock(sel);
+
+	chosen_for_balance = sel;
+	load_balancing_counter = BALANCING_TIMEOUT;
+
+	mosix_do_add_to_whereto(sel, BALANCE);
+	/* whereto_lock unlocked */
+
+#ifdef	CONFIG_MOSIX_DEBUG
+	if(ds_debug & (DSDEB_LOAD|DSDEB_CONSIDER))
+		printk("selected %s for load-balancing, pri=%d, load=%lu, priority=%d\n",
+			desc_mostask(&sel->mosix), (int)bestpri, bestload, (int)lastpri);
+#endif /* CONFIG_MOSIX_DEBUG */
+}
+
+#else /* !CONFIG_SSI */
+void
+choose(void)
+{
+	struct task_struct *p, *sel = NULL;
+	register struct mosix_task *m;
+        int64_t priority, lastpri = 0;
+        register int load, bestload;
+	int pri, bestpri;
+        int mintime, very_mintime;
+	int minload;
+
+	mintime = ((MILLION * acpuse) / HZ) / (num_online_cpus() * MF) ;
+	very_mintime = mintime / 3;
+	minload = 2 * acpuse / num_online_cpus();	/* normally 4*MF */
+        bestpri = mintime;
+        bestload = -1;
+	read_lock(&tasklist_lock);
+	if(!chosen_for_balance)
+	for_each_process(p)
+        if(!((m = &p->mosix)->dflags & (DDEPUTY|DFINISHED|DPASSING)) &&
+		!m->stay && !m->whereto && p != chosen_for_mdp &&
+		(!mosadmin_mode_lstay || (m->dflags & DREMOTE)))
+        {
+#ifdef CONFIG_MOSIX_DIAG
+		if(LOGICAL_STATE(p) == TASK_ZOMBIE)
+		{
+			mosix_panic("ZOMBIE without DFINISHED");
+			continue;
+		}
+#endif /* CONFIG_MOSIX_DIAG */
 		priority = ticks_to_ms(p->utime + m->uttime) +
 								m->cutime;
 		/* (note: m->dctime deliberately not taken into account:
@@ -544,30 +624,18 @@
 #else
 			priority += io_cost(m, remote_here_adjusted);
 #endif /* CONFIG_MOSIX_TOPOLOGY */
-#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*/
 #ifdef DEBUG
 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
 #endif /* DEBUG */
-#ifdef CONFIG_SSI
-		ssi_do_decay(m);
-#endif
                 if(pri < bestpri)
                 {
                         if(bestpri == mintime &&
@@ -601,11 +669,6 @@
 	}
         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;
 	if(sel->mosix.whereto != BALANCE)
@@ -614,19 +677,14 @@
 		chosen_for_balance = NULL;
 	}
 	spin_unlock_irq(&whereto_lock);
-#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 */
 }
+#endif /* !CONFIG_SSI */
 
 /* Acquires read_lock_bh(&loadinfo_lock) */
 void
@@ -708,7 +766,13 @@
 			continue;
 		}
 #endif /* CONFIG_MOSIX_DIAG */
+#ifdef CONFIG_SSI
+		task_lock(p);
+#endif
 		dff = time_since(m->last_mconsider);
+#ifdef CONFIG_SSI
+		task_unlock(p);
+#endif
 		if(dff > MAX_MCHOOSE_AGAIN)
 			df = MAX_MCHOOSE_AGAIN;
 		else
@@ -740,8 +804,14 @@
 		spin_unlock_irq(&whereto_lock);
 		return;
 	}
+#ifdef CONFIG_SSI
+	task_lock(sel);
+#endif
 	sel->mosix.page_allocs = 0;
 	sel->mosix.last_mconsider = time_now();
+#ifdef CONFIG_SSI
+	task_unlock(sel);
+#endif
 	chosen_for_mdp = sel;
 #ifdef CONFIG_SSI
 	memory_balancing_counter = BALANCING_TIMEOUT;
@@ -835,8 +905,6 @@
 	if(where)
 		comm_free(head);
 }
-#endif /* if 0 */
-#endif /* !CONFIG_SSI */
 
 struct sonstats
 {
@@ -852,16 +920,21 @@
 	struct mfs_stats mfs;
 #endif /* CONFIG_MOSIX_FS */
 };
+#endif /* if 0 */
+#endif /* !CONFIG_SSI */
 
 #ifdef CONFIG_SSI
 /* Locking: this function may acquire ...
  * read_lock_bh(&loadinfo_lock)
  * read_lock(&tasklist_lock)
  * -> sighand->siglock
+ * task_lock()
  */
 /* Locking: called functions may acquire...
+ * down_read(&mm->mmap_sem)
+ * -> spin_lock(&mm->page_table_lock)
  * write_lock_bh(&loadinfo_lock)
- * -> task_rq_lock()
+ * -> task_lock()
  * down(&load_left_lock)
  * spin_lock_irq(&whereto_lock)
  * read_lock_bh(&loadinfo_lock)
@@ -869,11 +942,154 @@
  * task_lock()
  */
 void
-consider(int reason, struct sonstats *sons, clusternode_t *node)
-#else
+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 *t, *p = current;
+	struct mosix_task *m = &p->mosix;
+	cputime_t utime, cutime;
+	clusternode_t mach[MAX_CONSIDERED];
+	long long tim, costs[MAX_CONSIDERED];
+	unsigned long migpages, aload[MAX_CONSIDERED];
+	int64_t ms;
+	int i, n = 0, j, k;
+	int depmach = -1;
+	int remote = (m->dflags & DREMOTE) ? 1 : 0;
+
+	if ((m->stay & DSTAY) || !PE || mosadmin_mode_quiet)
+		goto out;
+	if (reason && m->stay)
+		goto out;
+
+	migpages = run_over_dirty_pages(NULL, 0);
+
+	read_lock_bh(&loadinfo_lock);
+	for(i = 0 ; i < INFO_WIN ; i++)
+	if(loadinfo[i].node && loadinfo[i].speed && loadinfo[i].node != depmach
+		&& (i == 0 || (loadinfo[i].mem >= migpages)))
+	{
+		aload[n] = altload(loadinfo[i].load, loadinfo[i].speed,
+				loadinfo[i].ncpus);
+		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;
+		}
+		n++;
+	}
+	read_unlock_bh(&loadinfo_lock);
+
+	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
+
+	/* 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);
+
+	task_lock(p);
+	/* ms = (ticks_to_ms(p->utime+p->stime) - m->dctime) / HZ; */
+	ms = cputime_to_msecs(cputime_add(cutime, utime)) - 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;
+	}
+
+#ifndef CONFIG_USERMODE
+	kernel_fpu_end();
+#endif
+	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;
+	}
+out:
+	unchoose_me(p);
+}
+
+#else /* !CONFIG_SSI */
 void
 consider(int reason, struct sonstats *sons)
-#endif
 {
 #define	INFLOAD 0x8000000
 #define	MAX_CONSIDERED	(INFO_WIN+1+MAX_MFS_STATNODES)
@@ -882,14 +1098,7 @@
 #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
 	{
@@ -908,31 +1117,19 @@
 	register int i, n = 0, j, k;
 	int depmach = -1;
 	long long tim;
-#ifndef CONFIG_SSI
 	double dtim, rtim;
-#endif
 	int remote = (m->dflags & DREMOTE) ? 1 : 0;
 	int64_t ms;
-#ifndef CONFIG_SSI
 	struct aload_h a;
-#endif
 #ifdef CONFIG_MOSIX_DEBUG
-#ifndef CONFIG_SSI
 	char fbuf1[40];
 	char fbuf2[40];
-#endif
 #endif /* CONFIG_MOSIX_DEBUG */
 
-#ifdef CONFIG_SSI
-	if ((m->stay & DSTAY) || !PE || mosadmin_mode_quiet)
-		goto out;
-	if (reason && m->stay)
-#else
 	if((m->stay & DSTAY) || !PE || mosadmin_mode_quiet)
 		goto out;
 	if(reason && (m->stay || mosadmin_mode_stay ||
 		(mosadmin_mode_lstay && !(m->dflags & DREMOTE))))
-#endif /* !CONFIG_SSI */
 	{
 #ifdef CONFIG_MOSIX_DEBUG
 		if(ds_debug & (DSDEB_CONSIDER|DSDEB_MIG))
@@ -955,11 +1152,7 @@
 		goto out;
 	}
 #endif /* CONFIG_MOSIX_TOPOLOGY */
-#ifdef CONFIG_SSI
-	m->migpages = run_over_dirty_pages(NULL, 0);
-#else
 	m->migpages = count_migrating_pages();
-#endif
 #ifdef CONFIG_MOSIX_FS
 	if(sons && sons->mfs.nnodes)
 	{
@@ -973,8 +1166,6 @@
 	if(ds_debug & DSDEB_CONSIDER)
 		printk("Aloads: ");
 #endif /* CONFIG_MOSIX_DEBUG */
-#ifndef CONFIG_SSI
-#if 0
 	if(remote)
 	{
 		if(remote_request(REM_GETALOAD, NULL, 0, NULL, 0, 0,
@@ -998,24 +1189,17 @@
 #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++)
 #ifdef CONFIG_MOSIX_CHEAT_MIGSELF
 	if(loadinfo[i].pe && (!i || loadinfo[i].pe != depmach)
-#else
-#ifdef CONFIG_SSI
-	if(loadinfo[i].node && loadinfo[i].speed && loadinfo[i].node != depmach
-		&& (i == 0 || (loadinfo[i].mem >= m->migpages)))
+		&& (i == 0 || (loadinfo[i].mem >= m->migpages &&
+						loadinfo[i].free_slots)))
 #else
 	if(loadinfo[i].pe && loadinfo[i].pe != depmach
-#endif /* !CONFIG_SSI */
-#endif /* !CONFIG_MOSIX_CHEAT_MIGSELF */
-#ifndef CONFIG_SSI
 		&& (i == 0 || (loadinfo[i].mem >= m->migpages &&
 						loadinfo[i].free_slots)))
-#endif /* !CONFIG_SSI */
+#endif /* !CONFIG_MOSIX_CHEAT_MIGSELF */
 	{
 #ifdef CONFIG_MOSIX_TOPOLOGY
 		memcpy(costinfo[n].opcost, loadinfo[i].costs,
@@ -1028,11 +1212,7 @@
 		aload[n] = altload(loadinfo[i].load, loadinfo[i].speed,
 				loadinfo[i].ncpus);
 		if(i)
-#ifdef CONFIG_SSI
-			mach[n] = loadinfo[i].node;
-#else
 			mach[n] = loadinfo[i].pe;
-#endif /* !CONFIG_SSI */
 		else
 		{
 			mach[n] = 0;
@@ -1042,20 +1222,11 @@
 					continue;
 				aload[n] += INFLOAD;
 			}
-#ifdef CONFIG_SSI
-			if (!latest_free_mem)
-				aload[0] = INT_MAX;
-#endif
 		}
 #ifdef CONFIG_MOSIX_DEBUG
 		if(ds_debug & DSDEB_CONSIDER)
-#ifdef CONFIG_SSI
-			printk("%u=%d==>%d, ", loadinfo[i].node,
-					(int)loadinfo[i].load, (int)aload[n]);
-#else
 			printk("%d=%d==>%d, ", loadinfo[i].pe,
 					(int)loadinfo[i].load, aload[n]);
-#endif /* !CONFIG_SSI */
 #endif /* CONFIG_MOSIX_DEBUG */
 		n++;
 	}
@@ -1132,34 +1303,6 @@
 #ifndef CONFIG_USERMODE
 	kernel_fpu_begin();
 #endif
-#ifdef CONFIG_SSI
-	/* 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=%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)
 		ms += sons->utime;
@@ -1168,10 +1311,8 @@
 	else
 		/* secs on a std. machine */
 		tim = ms / DMILLION * cpuspeed / STD_SPD;
-	/* Currently not doing MEMBALANCE for OpenSSI */
 	if(reason == MEMBALANCE)
 		tim += (m->pagetime + (sons ? sons->pagetime : 0)) / DMILLION;
-#endif /* !CONFIG_SSI */
 #ifdef CONFIG_MOSIX_DEBUG
 	if (ds_debug & DSDEB_CONSIDER)
 		printk("tim=%lld\n",  tim);
@@ -1188,7 +1329,6 @@
 	}
 #endif
 
-#ifndef CONFIG_SSI
 	if((m->dpolicy & DADV_POLICY) == DADV_CPU)
 		goto skip_comm;
 	if(sons)	/* temporarily add */
@@ -1278,23 +1418,9 @@
 #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 */
@@ -1313,7 +1439,6 @@
 		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)
@@ -1324,17 +1449,11 @@
 				m->migpages * mosix_cost[j].MIGRATION_PER_PAGE);
 		}
 #else
-#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++)
 		if(i != remote)
 			costs[i] += tim;
-#endif /* !CONFIG_SSI */
 #endif /* CONFIG_MOSIX_TOPOLOGY */
 #ifdef	CONFIG_MOSIX_DEBUG
 		if(ds_debug & DSDEB_CONSIDER)
@@ -1370,22 +1489,11 @@
 		printk("\n");
 	}
 #endif
-#ifndef CONFIG_SSI
 	m->loadhere = aload[remote];
-#endif /* !CONFIG_SSI */
 	for(i = 0 ; i < n ; i++)
 	{
 		if((k = mach[i]) == 0)
 			goto out;
-#ifdef CONFIG_SSI
-		if (node) {
-			*node = k;
-			/* cleanup stuff */
-			release_migrations(k);
-			neutralize_my_load(1);
-		}
-		return;
-#else /* !CONFIG_SSI */
 		if(remote)
 		{
 #ifdef CONFIG_MOSIX_DEBUG
@@ -1401,7 +1509,6 @@
 		if(mosadmin_mode_quiet || (reason && (mosadmin_mode_stay ||
 			(mosadmin_mode_lstay && !(m->dflags & DREMOTE)))))
 			goto out;
-#endif /* !CONFIG_SSI */
 	}
 	out:
 #ifdef CONFIG_MOSIX_TOPOLOGY
@@ -1409,14 +1516,11 @@
 		kfree(costinfo);
 #endif /* CONFIG_MOSIX_TOPOLOGY */
 	m->migpages = 0;
-#ifdef CONFIG_SSI
-	unchoose_me(current);
-#else
 	unchoose_me();
 	if(m->dflags & DREMOTE)
 		ask_deputy_to_goto(0);
-#endif /* !CONFIG_SSI */
 }
+#endif /* !CONFIG_SSI */
 
 /* Acquires spin_lock_irq(&whereto_lock) */
 /* Called functions may acquire...
@@ -1436,7 +1540,7 @@
 	int l = 0, m = 0;
 
 #ifdef CONFIG_SSI
-	p->mosix.migpages = 0;
+	/* p->mosix.migpages = 0; */
 #ifdef CONFIG_MOSIX_DEBUG
 	if((ds_debug & DSDEB_CONSIDER) && (p != current))
 		printk("unchoose_me: %s state %ld\n",
@@ -1672,6 +1776,7 @@
 #endif
 }
 
+/* Called under read_lock(&tasklist_lock), task_lock() */
 void ssi_do_decay(struct mosix_task *m)
 {
 	/* register struct mosix_task *m = &current->mosix; */

Index: service.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/service.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- service.c	20 Apr 2008 05:49:23 -0000	1.7
+++ service.c	18 Nov 2009 06:16:53 -0000	1.8
@@ -215,6 +215,10 @@
 static int run_over_maxchunk;
 
 #ifdef SSI_BALANCE_MEMORY
+/* Locking:
+ * down_read(&mm->mmap_sem)
+ * -> spin_lock(&mm->page_table_lock)
+ */
 unsigned long
 #else
 int
@@ -275,6 +279,9 @@
 	addr = 0;
 	loop:
 	let_go = run_over_maxchunk;
+#ifdef SSI_BALANCE_MEMORY
+	down_read(&mm->mmap_sem);
+#endif
 	for(vma = mm->mmap ; vma != NULL ; vma = vma->vm_next)
 	if(addr < vma->vm_end)
 	{
@@ -287,6 +294,9 @@
 	    {
 		if(let_go-- == 0)
 		{
+#ifdef SSI_BALANCE_MEMORY
+			up_read(&mm->mmap_sem);
+#endif
 			yield();
 			goto loop;
 		}
@@ -323,6 +333,9 @@
 				count++;
 			if(func)
 			{
+#ifdef SSI_BALANCE_MEMORY
+				BUG();
+#endif
 				spin_unlock(&mm->page_table_lock);
 				if((err = (*func)(addr, PAGE_SIZE))) {
 					pte_unmap(pte_dir);
@@ -336,6 +349,9 @@
 		spin_unlock(&mm->page_table_lock);
 	    }
 	}
+#ifdef SSI_BALANCE_MEMORY
+	up_read(&mm->mmap_sem);
+#endif
 	return(count);
 }
 

Index: info.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/info.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- info.c	17 Nov 2009 06:09:02 -0000	1.10
+++ info.c	18 Nov 2009 06:16:53 -0000	1.11
@@ -970,7 +970,7 @@
  */
 /* Locking: will acquire...
  * write_lock_bh(&loadinfo_lock)
- * -> task_rq_lock()
+ * -> task_lock()
  * down(&load_left_lock)
  * spin_lock_irq(&whereto_lock)
  * task_lock()
@@ -981,17 +981,20 @@
  * read_lock(&tasklist_lock)
  */
 void
+#ifdef CONFIG_SSI
+release_migrations(int whereto, unsigned long pages)
+#else
 release_migrations(int whereto)
+#endif
 {
 	struct task_struct *p = current;
-	struct runqueue *rq;
-	unsigned long flags;
 	register struct mosix_task *m = &p->mosix;
 #ifdef CONFIG_SSI
-	register int i;
 	unsigned long load;
-	unsigned long pages = m->migpages ? : run_over_dirty_pages(NULL, 0);
+	int i;
 #else
+	struct runqueue *rq;
+	unsigned long flags;
 	register int load, i;
 	int pages = m->migpages ? : count_migrating_pages();
 
@@ -1002,10 +1005,18 @@
 	 * to avoid over-migration.
 	 */
 	write_lock_bh(&loadinfo_lock);
+#ifdef CONFIG_SSI
+	task_lock(p);
+	load = m->load * STD_SPD / 4 / cpuspeed;
+	task_unlock(p);
+
+	load /= num_online_cpus();
+#else
 	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;


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
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.