|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 1 of 1] sched: rework locking for dump debugkey.
On Wed, 2012-01-18 at 16:24 +0000, Dario Faggioli wrote:
> As in all other paths, locking should be dealt with in the
> specific schedulers, not in schedule.c.
I think this looks right. But you should probably add a comment at the
top of credit1 and sedf to say that now the locking order must be
private -> schedule, to avoid deadlock.
(Before I don't think there was an ordering.)
Thanks,
-George
>
> Signed-off-by: Dario Faggioli <dario.faggioli@xxxxxxxxxx>
>
> diff -r 15ab61865ecb xen/common/sched_credit.c
> --- a/xen/common/sched_credit.c Tue Jan 17 12:40:52 2012 +0000
> +++ b/xen/common/sched_credit.c Wed Jan 18 15:02:30 2012 +0000
> @@ -1451,11 +1451,16 @@ static void
> csched_dump_pcpu(const struct scheduler *ops, int cpu)
> {
> struct list_head *runq, *iter;
> + struct csched_private *prv = CSCHED_PRIV(ops);
> struct csched_pcpu *spc;
> struct csched_vcpu *svc;
> + unsigned long flags;
> int loop;
> #define cpustr keyhandler_scratch
>
> + /* Domains' parameters are changed under csched_priv lock */
> + spin_lock_irqsave(&prv->lock, flags);
> +
> spc = CSCHED_PCPU(cpu);
> runq = &spc->runq;
>
> @@ -1464,6 +1469,12 @@ csched_dump_pcpu(const struct scheduler
> cpumask_scnprintf(cpustr, sizeof(cpustr), per_cpu(cpu_core_mask, cpu));
> printk("core=%s\n", cpustr);
>
> + /*
> + * We need runq lock as well, and as there's one runq per CPU,
> + * this is the correct one to take for this CPU/runq.
> + */
> + pcpu_schedule_lock(cpu);
> +
> /* current VCPU */
> svc = CSCHED_VCPU(per_cpu(schedule_data, cpu).curr);
> if ( svc )
> @@ -1482,6 +1493,9 @@ csched_dump_pcpu(const struct scheduler
> csched_dump_vcpu(svc);
> }
> }
> +
> + pcpu_schedule_unlock(cpu);
> + spin_unlock_irqrestore(&prv->lock, flags);
> #undef cpustr
> }
>
> @@ -1493,7 +1507,7 @@ csched_dump(const struct scheduler *ops)
> int loop;
> unsigned long flags;
>
> - spin_lock_irqsave(&(prv->lock), flags);
> + spin_lock_irqsave(&prv->lock, flags);
>
> #define idlers_buf keyhandler_scratch
>
> @@ -1537,12 +1551,14 @@ csched_dump(const struct scheduler *ops)
> svc = list_entry(iter_svc, struct csched_vcpu, active_vcpu_elem);
>
> printk("\t%3d: ", ++loop);
> + vcpu_schedule_lock(svc->vcpu);
> csched_dump_vcpu(svc);
> + vcpu_schedule_unlock(svc->vcpu);
> }
> }
> #undef idlers_buf
>
> - spin_unlock_irqrestore(&(prv->lock), flags);
> + spin_unlock_irqrestore(&prv->lock, flags);
> }
>
> static int
> diff -r 15ab61865ecb xen/common/sched_credit2.c
> --- a/xen/common/sched_credit2.c Tue Jan 17 12:40:52 2012 +0000
> +++ b/xen/common/sched_credit2.c Wed Jan 18 15:02:30 2012 +0000
> @@ -53,8 +53,6 @@
> * credit2 wiki page:
> * http://wiki.xen.org/wiki/Credit2_Scheduler_Development
> * TODO:
> - * + Immediate bug-fixes
> - * - Do per-runqueue, grab proper lock for dump debugkey
> * + Multiple sockets
> * - Detect cpu layout and make runqueue map, one per L2 (make_runq_map())
> * - Simple load balancer / runqueue assignment
> @@ -1759,12 +1757,16 @@ csched_dump_vcpu(struct csched_vcpu *svc
> static void
> csched_dump_pcpu(const struct scheduler *ops, int cpu)
> {
> + struct csched_private *prv = CSCHED_PRIV(ops);
> struct list_head *runq, *iter;
> struct csched_vcpu *svc;
> + unsigned long flags;
> + spinlock_t *lock;
> int loop;
> char cpustr[100];
>
> - /* FIXME: Do locking properly for access to runqueue structures */
> + /* Domains' parameters are changed under csched_priv lock */
> + spin_lock_irqsave(&prv->lock, flags);
>
> runq = &RQD(ops, cpu)->runq;
>
> @@ -1773,6 +1775,13 @@ csched_dump_pcpu(const struct scheduler
> cpumask_scnprintf(cpustr, sizeof(cpustr), per_cpu(cpu_core_mask, cpu));
> printk("core=%s\n", cpustr);
>
> + /*
> + * We need runq lock as well, and here's how we get to it
> + * for the requested cpu.
> + */
> + lock = per_cpu(schedule_data, cpu).schedule_lock;
> + spin_lock(lock);
> +
> /* current VCPU */
> svc = CSCHED_VCPU(per_cpu(schedule_data, cpu).curr);
> if ( svc )
> @@ -1791,6 +1800,9 @@ csched_dump_pcpu(const struct scheduler
> csched_dump_vcpu(svc);
> }
> }
> +
> + spin_unlock(lock);
> + spin_unlock_irqrestore(&prv->lock, flags);
> }
>
> static void
> @@ -1798,8 +1810,11 @@ csched_dump(const struct scheduler *ops)
> {
> struct list_head *iter_sdom, *iter_svc;
> struct csched_private *prv = CSCHED_PRIV(ops);
> + unsigned long flags;
> int i, loop;
>
> + spin_lock_irqsave(&prv->lock, flags);
> +
> printk("Active queues: %d\n"
> "\tdefault-weight = %d\n",
> cpumask_weight(&prv->active_queues),
> @@ -1822,7 +1837,6 @@ csched_dump(const struct scheduler *ops)
> fraction);
>
> }
> - /* FIXME: Locking! */
>
> printk("Domain info:\n");
> loop = 0;
> @@ -1831,10 +1845,10 @@ csched_dump(const struct scheduler *ops)
> 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);
> + 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 )
> {
> @@ -1842,9 +1856,13 @@ csched_dump(const struct scheduler *ops)
> svc = list_entry(iter_svc, struct csched_vcpu, sdom_elem);
>
> printk("\t%3d: ", ++loop);
> + vcpu_schedule_lock(svc->vcpu);
> csched_dump_vcpu(svc);
> + vcpu_schedule_unlock(svc->vcpu);
> }
> }
> +
> + spin_unlock_irqrestore(&prv->lock, flags);
> }
>
> static void activate_runqueue(struct csched_private *prv, int rqi)
> diff -r 15ab61865ecb xen/common/sched_sedf.c
> --- a/xen/common/sched_sedf.c Tue Jan 17 12:40:52 2012 +0000
> +++ b/xen/common/sched_sedf.c Wed Jan 18 15:02:30 2012 +0000
> @@ -1219,13 +1219,25 @@ static void sedf_dump_domain(struct vcpu
> /* Dumps all domains on the specified cpu */
> static void sedf_dump_cpu_state(const struct scheduler *ops, int i)
> {
> + struct sedf_priv_info *prv = SEDF_PRIV(ops);
> struct list_head *list, *queue, *tmp;
> struct sedf_vcpu_info *d_inf;
> struct domain *d;
> struct vcpu *ed;
> + unsigned long flags;
> int loop = 0;
> +
> + /* Domains' parameters are changed under scheduler lock */
> + spin_lock_irqsave(&prv->lock, flags);
>
> printk("now=%"PRIu64"\n",NOW());
> +
> + /*
> + * We need runq lock as well, and as there's one runq per CPU,
> + * this is the correct one to take for this CPU/runq.
> + */
> + pcpu_schedule_lock(i);
> +
> queue = RUNQ(i);
> printk("RUNQ rq %lx n: %lx, p: %lx\n", (unsigned long)queue,
> (unsigned long) queue->next, (unsigned long) queue->prev);
> @@ -1288,6 +1300,9 @@ static void sedf_dump_cpu_state(const st
> }
> }
> rcu_read_unlock(&domlist_read_lock);
> +
> + pcpu_schedule_unlock(i);
> + spin_unlock_irqrestore(&prv->lock, flags);
> }
>
>
> diff -r 15ab61865ecb xen/common/schedule.c
> --- a/xen/common/schedule.c Tue Jan 17 12:40:52 2012 +0000
> +++ b/xen/common/schedule.c Wed Jan 18 15:02:30 2012 +0000
> @@ -1417,6 +1417,7 @@ void schedule_dump(struct cpupool *c)
> struct scheduler *sched;
> cpumask_t *cpus;
>
> + /* Proper locking is provided by each scheduler */
> sched = (c == NULL) ? &ops : c->sched;
> cpus = (c == NULL) ? &cpupool_free_cpus : c->cpu_valid;
> printk("Scheduler: %s (%s)\n", sched->name, sched->opt_name);
> @@ -1424,10 +1425,8 @@ void schedule_dump(struct cpupool *c)
>
> for_each_cpu (i, cpus)
> {
> - pcpu_schedule_lock(i);
> printk("CPU[%02d] ", i);
> SCHED_OP(sched, dump_cpu_state, i);
> - pcpu_schedule_unlock(i);
> }
> }
>
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |