Address some credit2 issues. This patch series, along with the recent changes to the cpupools interface, should address some of the strange credit2 instability. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
George Dunlap
2010-Oct-26 10:22 UTC
[Xen-devel] [PATCH 1 of 3] credit2: Make fake runq map initilization explicit
Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
diff -r 36a317494429 -r 861eb3d63f06 xen/common/sched_credit2.c
--- a/xen/common/sched_credit2.c Mon Oct 25 18:15:28 2010 +0100
+++ b/xen/common/sched_credit2.c Tue Oct 26 11:06:12 2010 +0100
@@ -1131,10 +1131,14 @@
static void
make_runq_map(struct csched_private *prv)
{
+ int i;
/* FIXME: Read pcpu layout and do this properly */
prv->runq_count = 1;
prv->rqd[0].cpu_min = 0;
prv->rqd[0].cpu_max = NR_CPUS;
+
+ for (i=0; i<NR_CPUS; i++)
+ prv->runq_map[i]=0;
}
static int
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
George Dunlap
2010-Oct-26 10:22 UTC
[Xen-devel] [PATCH 2 of 3] credit2: Fix runq_tickle to use idle, tickled masks
The previous code had a bug where, if a second vcpu woke up and ran runq_tickle
before the first vcpu had actually started running on a tickled processor, the
code would choose the same cpu to tickle, and the result would be a "missed
tickle" --
only one of the vcpus would run, despite having idle processors.
This change:
* Keeps a mask of idle cpus
* Keeps a mask of cpus which have been tickled, but not entered schedule yet.
The new tickle code first looks at the set of idle-but-not-tickled cpus; if
it''s
not empty, it tickles one.
If that doesn''t work, it looks at the set of not-idle-but-not-tickled
cpus,
finds the one with the lowest credit; if that''s lower than the waking
vcpu, it
tickles that one.
If any cpu is tickled, its bit in the tickled mask is set, and cleared when
schedule() is called.
Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
diff -r 861eb3d63f06 -r 9a3d5ed84604 xen/common/sched_credit2.c
--- a/xen/common/sched_credit2.c Tue Oct 26 11:06:12 2010 +0100
+++ b/xen/common/sched_credit2.c Tue Oct 26 11:06:14 2010 +0100
@@ -39,6 +39,7 @@
#define TRC_CSCHED2_CREDIT_BURN TRC_SCHED_CLASS + 3
#define TRC_CSCHED2_CREDIT_ADD TRC_SCHED_CLASS + 4
#define TRC_CSCHED2_TICKLE_CHECK TRC_SCHED_CLASS + 5
+#define TRC_CSCHED2_TICKLE TRC_SCHED_CLASS + 6
/*
* WARNING: This is still in an experimental phase. Status and work can be
found at the
@@ -169,6 +170,8 @@
struct list_head svc; /* List of all vcpus assigned to this runqueue */
int max_weight;
int cpu_min, cpu_max; /* Range of physical cpus this runqueue runs */
+ cpumask_t idle, /* Currently idle */
+ tickled; /* Another cpu in the queue is already targeted for
this one */
};
/*
@@ -328,7 +331,7 @@
int i, ipid=-1;
s_time_t lowest=(1<<30);
struct csched_runqueue_data *rqd = RQD(ops, cpu);
- cpumask_t *online;
+ cpumask_t *online, mask;
d2printk("rqt d%dv%d cd%dv%d\n",
new->vcpu->domain->domain_id,
@@ -337,61 +340,74 @@
current->vcpu_id);
online = CSCHED_CPUONLINE(per_cpu(cpupool, cpu));
- /* Find the cpu in this queue group that has the lowest credits */
- for ( i=rqd->cpu_min ; i < rqd->cpu_max ; i++ )
+
+ /* Get a mask of idle, but not tickled */
+ cpus_andnot(mask, rqd->idle, rqd->tickled);
+
+ /* If it''s not empty, choose one */
+ if ( !cpus_empty(mask) )
+ {
+ ipid=first_cpu(mask);
+ goto tickle;
+ }
+
+ /* Otherwise, look for the non-idle cpu with the lowest credit,
+ * skipping cpus which have been tickled but not scheduled yet */
+ cpus_andnot(mask, *online, rqd->idle);
+ cpus_andnot(mask, mask, rqd->tickled);
+
+ for_each_cpu_mask(i, mask)
{
struct csched_vcpu * cur;
- /* Skip cpus that aren''t online */
- if ( !cpu_isset(i, *online) )
- continue;
-
cur = CSCHED_VCPU(per_cpu(schedule_data, i).curr);
- /* FIXME: keep track of idlers, chose from the mask */
- if ( is_idle_vcpu(cur->vcpu) )
+ BUG_ON(is_idle_vcpu(cur->vcpu));
+
+ /* Update credits for current to see if we want to preempt */
+ burn_credits(rqd, cur, now);
+
+ if ( cur->credit < lowest )
{
ipid = i;
- lowest = CSCHED_IDLE_CREDIT;
- break;
+ lowest = cur->credit;
}
- else
- {
- /* Update credits for current to see if we want to preempt */
- burn_credits(rqd, cur, now);
- if ( cur->credit < lowest )
- {
- ipid = i;
- lowest = cur->credit;
- }
-
- /* TRACE */ {
- struct {
- unsigned dom:16,vcpu:16;
- unsigned credit;
- } d;
- d.dom = cur->vcpu->domain->domain_id;
- d.vcpu = cur->vcpu->vcpu_id;
- d.credit = cur->credit;
- trace_var(TRC_CSCHED2_TICKLE_CHECK, 1,
- sizeof(d),
- (unsigned char *)&d);
- }
+ /* TRACE */ {
+ struct {
+ unsigned dom:16,vcpu:16;
+ unsigned credit;
+ } d;
+ d.dom = cur->vcpu->domain->domain_id;
+ d.vcpu = cur->vcpu->vcpu_id;
+ d.credit = cur->credit;
+ trace_var(TRC_CSCHED2_TICKLE_CHECK, 0,
+ sizeof(d),
+ (unsigned char *)&d);
}
}
- if ( ipid != -1 )
- {
- int cdiff = lowest - new->credit;
+ /* At this point, if ipid is non-zero, see if the lowest is lower than new
*/
+ if ( ipid == -1 || lowest > new->credit )
+ goto no_tickle;
- if ( lowest == CSCHED_IDLE_CREDIT || cdiff < 0 ) {
- d2printk("si %d\n", ipid);
- cpu_raise_softirq(ipid, SCHEDULE_SOFTIRQ);
- }
- else
- /* FIXME: Wake up later? */;
+tickle:
+ BUG_ON(ipid == -1);
+
+ /* TRACE */ {
+ struct {
+ unsigned cpu:8;
+ } d;
+ d.cpu = ipid;
+ trace_var(TRC_CSCHED2_TICKLE, 0,
+ sizeof(d),
+ (unsigned char *)&d);
}
+ cpu_set(ipid, rqd->tickled);
+ cpu_raise_softirq(ipid, SCHEDULE_SOFTIRQ);
+
+no_tickle:
+ return;
}
/*
@@ -915,6 +931,10 @@
/* Protected by runqueue lock */
+ /* Clear "tickled" bit now that we''ve been scheduled */
+ if ( cpu_isset(cpu, rqd->tickled) )
+ cpu_clear(cpu, rqd->tickled);
+
/* Update credits */
burn_credits(rqd, scurr, now);
@@ -972,21 +992,19 @@
if ( !is_idle_vcpu(snext->vcpu) && snext->credit <=
CSCHED_CREDIT_RESET )
reset_credit(ops, cpu, now);
-#if 0
/*
* Update idlers mask if necessary. When we''re idling, other CPUs
* will tickle us when they get extra work.
*/
if ( is_idle_vcpu(snext->vcpu) )
{
- if ( !cpu_isset(cpu, csched_priv.idlers) )
- cpu_set(cpu, csched_priv.idlers);
+ if ( !cpu_isset(cpu, rqd->idle) )
+ cpu_set(cpu, rqd->idle);
}
- else if ( cpu_isset(cpu, csched_priv.idlers) )
+ else if ( cpu_isset(cpu, rqd->idle) )
{
- cpu_clear(cpu, csched_priv.idlers);
+ cpu_clear(cpu, rqd->idle);
}
-#endif
ret.migrated = 0;
@@ -1103,6 +1121,8 @@
spin_lock_irqsave(&prv->lock, flags);
prv->ncpus--;
+ cpu_clear(cpu, RQD(ops, cpu)->idle);
+ printk("Removing cpu %d to pool (%d total)\n", cpu,
prv->ncpus);
spin_unlock_irqrestore(&prv->lock, flags);
return;
@@ -1123,6 +1143,8 @@
spin_lock_irqsave(&prv->lock, flags);
prv->ncpus++;
+ cpu_set(cpu, RQD(ops, cpu)->idle);
+ printk("Adding cpu %d to pool (%d total)\n", cpu, prv->ncpus);
spin_unlock_irqrestore(&prv->lock, flags);
return (void *)1;
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
George Dunlap
2010-Oct-26 10:22 UTC
[Xen-devel] [PATCH 3 of 3] credit2: Trace and debug key tweaks
* Add traces for credit reset and scheduling a tasklet
* Remove tsc for traces which probably don''t need them
* Print domain info in the debug dump
Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
diff -r 9a3d5ed84604 -r e2eed64cf0d5 xen/common/sched_credit2.c
--- a/xen/common/sched_credit2.c Tue Oct 26 11:06:14 2010 +0100
+++ b/xen/common/sched_credit2.c Tue Oct 26 11:06:16 2010 +0100
@@ -40,6 +40,8 @@
#define TRC_CSCHED2_CREDIT_ADD TRC_SCHED_CLASS + 4
#define TRC_CSCHED2_TICKLE_CHECK TRC_SCHED_CLASS + 5
#define TRC_CSCHED2_TICKLE TRC_SCHED_CLASS + 6
+#define TRC_CSCHED2_CREDIT_RESET TRC_SCHED_CLASS + 7
+#define TRC_CSCHED2_SCHED_TASKLET TRC_SCHED_CLASS + 8
/*
* WARNING: This is still in an experimental phase. Status and work can be
found at the
@@ -306,7 +308,7 @@
d.dom = svc->vcpu->domain->domain_id;
d.vcpu = svc->vcpu->vcpu_id;
d.pos = pos;
- trace_var(TRC_CSCHED2_RUNQ_POS, 1,
+ trace_var(TRC_CSCHED2_RUNQ_POS, 0,
sizeof(d),
(unsigned char *)&d);
}
@@ -421,8 +423,12 @@
{
struct csched_vcpu * svc = list_entry(iter, struct csched_vcpu,
rqd_elem);
+ int start_credit;
+
BUG_ON( is_idle_vcpu(svc->vcpu) );
+ start_credit = svc->credit;
+
/* "Clip" credits to max carryover */
if ( svc->credit > CSCHED_CARRYOVER_MAX )
svc->credit = CSCHED_CARRYOVER_MAX;
@@ -430,7 +436,19 @@
svc->credit += CSCHED_CREDIT_INIT;
svc->start_time = now;
- /* FIXME: Trace credit */
+ /* TRACE */ {
+ struct {
+ unsigned dom:16,vcpu:16;
+ unsigned credit_start, credit_end;
+ } d;
+ d.dom = svc->vcpu->domain->domain_id;
+ d.vcpu = svc->vcpu->vcpu_id;
+ d.credit_start = start_credit;
+ d.credit_end = svc->credit;
+ trace_var(TRC_CSCHED2_CREDIT_RESET, 0,
+ sizeof(d),
+ (unsigned char *)&d);
+ }
}
/* No need to resort runqueue, as everyone''s order should be the
same. */
@@ -476,7 +494,7 @@
d.vcpu = svc->vcpu->vcpu_id;
d.credit = svc->credit;
d.delta = delta;
- trace_var(TRC_CSCHED2_CREDIT_BURN, 1,
+ trace_var(TRC_CSCHED2_CREDIT_BURN, 0,
sizeof(d),
(unsigned char *)&d);
}
@@ -961,16 +979,21 @@
else
snext = __runq_elem(runq->next);
+ if ( tasklet_work_scheduled )
+ trace_var(TRC_CSCHED2_SCHED_TASKLET, 0, 0, NULL);
+
if ( !is_idle_vcpu(current) && vcpu_runnable(current) )
{
/* If the current vcpu is runnable, and has higher credit
* than the next on the runqueue, and isn''t being preempted
* by a tasklet, run him again.
* Otherwise, set him for delayed runq add. */
+
if ( !tasklet_work_scheduled && scurr->credit >
snext->credit)
snext = scurr;
else
set_bit(__CSFLAG_delayed_runq_add, &scurr->flags);
+
}
if ( snext != scurr && !is_idle_vcpu(snext->vcpu) )
@@ -1095,13 +1118,18 @@
/* FIXME: Locking! */
- printk("active vcpus:\n");
+ printk("Domain info:\n");
loop = 0;
list_for_each( iter_sdom, &prv->sdom )
{
struct csched_dom *sdom;
sdom = list_entry(iter_sdom, struct csched_dom, sdom_elem);
+ printk("\tDomain: %d w %d v %d\n\t",
+ sdom->dom->domain_id,
+ sdom->weight,
+ sdom->nr_vcpus);
+
list_for_each( iter_svc, &sdom->vcpu )
{
struct csched_vcpu *svc;
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Apparently Analagous Threads
- [PATCH 0 of 3] xen: sched_credit: fix tickling and add some tracing
- [PATCH v2 1/2] credit2: Fix erronous ASSERT
- [PATCH] xen,credit1: Add variable timeslice
- [PATCH v2] xen: sched: introduce hard and soft affinity in credit 2 scheduler
- Problem with C&C Generals