[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 = ¤t->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