[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 = ¤t->mosix;
+ /* register struct mosix_task *m = ¤t->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