[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 7/7] xen: sched_rt: print useful affinity info when dumping
Hi Dario, 2015-03-16 13:05 GMT-04:00 Dario Faggioli <dario.faggioli@xxxxxxxxxx>: > In fact, printing the cpupool's CPU online mask > for each vCPU is just redundant, as that is the > same for all the vCPUs of all the domains in the > same cpupool, while hard affinity is already part > of the output of dumping domains info. > > Instead, print the intersection between hard > affinity and online CPUs, which is --in case of this > scheduler-- the effective affinity always used for > the vCPUs. Agree. > > This change also takes the chance to add a scratch > cpumask, to avoid having to create one more > cpumask_var_t on the stack of the dumping routine. Actually, I have a question about the strength of this design. When we have a machine with many cpus, we will end up with allocating a cpumask for each cpu. Is this better than having a cpumask_var_t on the stack of the dumping routine, since the dumping routine is not in the hot path? > Such scratch area can be used to kill most of the > cpumasks_var_t local variables in other functions > in the file, but that is *NOT* done in this chage. > > Finally, convert the file to use keyhandler scratch, > instead of open coded string buffers. > > Signed-off-by: Dario Faggioli <dario.faggioli@xxxxxxxxxx> > Cc: George Dunlap <george.dunlap@xxxxxxxxxxxxx> > Cc: Meng Xu <xumengpanda@xxxxxxxxx> > Cc: Jan Beulich <JBeulich@xxxxxxxx> > Cc: Keir Fraser <keir@xxxxxxx> > --- > xen/common/sched_rt.c | 40 ++++++++++++++++++++++++++++++++-------- > 1 file changed, 32 insertions(+), 8 deletions(-) > > diff --git a/xen/common/sched_rt.c b/xen/common/sched_rt.c > index 167a484..7aa3ac8 100644 > --- a/xen/common/sched_rt.c > +++ b/xen/common/sched_rt.c > @@ -124,6 +124,12 @@ > #define TRC_RTDS_BUDGET_REPLENISH TRC_SCHED_CLASS_EVT(RTDS, 4) > #define TRC_RTDS_SCHED_TASKLET TRC_SCHED_CLASS_EVT(RTDS, 5) > > + /* > + * Useful to avoid too many cpumask_var_t on the stack. > + */ > +static cpumask_t **_cpumask_scratch; > +#define cpumask_scratch _cpumask_scratch[smp_processor_id()] > + > /* > * Systme-wide private data, include global RunQueue/DepletedQ > * Global lock is referenced by schedule_data.schedule_lock from all > @@ -218,7 +224,6 @@ __q_elem(struct list_head *elem) > static void > rt_dump_vcpu(const struct scheduler *ops, const struct rt_vcpu *svc) > { > - char cpustr[1024]; > cpumask_t *cpupool_mask; > > ASSERT(svc != NULL); > @@ -229,10 +234,22 @@ rt_dump_vcpu(const struct scheduler *ops, const struct > rt_vcpu *svc) > return; > } > > - cpumask_scnprintf(cpustr, sizeof(cpustr), svc->vcpu->cpu_hard_affinity); > + cpupool_mask = cpupool_scheduler_cpumask(svc->vcpu->domain->cpupool); > + /* > + * We can't just use 'cpumask_scratch' because the dumping can > + * happen from a pCPU outside of this scheduler's cpupool, and > + * hence it's not right to use the pCPU's scratch mask (which > + * may even not exist!). On the other hand, it is safe to use > + * svc->vcpu->processor's own scratch space, since we own the > + * runqueue lock. > + */ > + cpumask_and(_cpumask_scratch[svc->vcpu->processor], cpupool_mask, > + svc->vcpu->cpu_hard_affinity); > + cpulist_scnprintf(keyhandler_scratch, sizeof(keyhandler_scratch), > + _cpumask_scratch[svc->vcpu->processor]); > printk("[%5d.%-2u] cpu %u, (%"PRI_stime", %"PRI_stime")," > " cur_b=%"PRI_stime" cur_d=%"PRI_stime" last_start=%"PRI_stime"\n" > - " \t\t onQ=%d runnable=%d cpu_hard_affinity=%s ", > + " \t\t onQ=%d runnable=%d flags=%x effective hard_affinity=%s\n", > svc->vcpu->domain->domain_id, > svc->vcpu->vcpu_id, > svc->vcpu->processor, > @@ -243,11 +260,8 @@ rt_dump_vcpu(const struct scheduler *ops, const struct > rt_vcpu *svc) > svc->last_start, > __vcpu_on_q(svc), > vcpu_runnable(svc->vcpu), > - cpustr); > - memset(cpustr, 0, sizeof(cpustr)); > - cpupool_mask = cpupool_scheduler_cpumask(svc->vcpu->domain->cpupool); > - cpumask_scnprintf(cpustr, sizeof(cpustr), cpupool_mask); > - printk("cpupool=%s\n", cpustr); > + svc->flags, > + keyhandler_scratch); > } > > static void > @@ -409,6 +423,10 @@ rt_init(struct scheduler *ops) > if ( prv == NULL ) > return -ENOMEM; > > + _cpumask_scratch = xmalloc_array(cpumask_var_t, nr_cpu_ids); Is it better to use xzalloc_array? > + if ( _cpumask_scratch == NULL ) > + return -ENOMEM; > + > spin_lock_init(&prv->lock); > INIT_LIST_HEAD(&prv->sdom); > INIT_LIST_HEAD(&prv->runq); > @@ -426,6 +444,7 @@ rt_deinit(const struct scheduler *ops) > { > struct rt_private *prv = rt_priv(ops); > > + xfree(_cpumask_scratch); > xfree(prv); > } > > @@ -443,6 +462,9 @@ rt_alloc_pdata(const struct scheduler *ops, int cpu) > per_cpu(schedule_data, cpu).schedule_lock = &prv->lock; > spin_unlock_irqrestore(&prv->lock, flags); > > + if ( !alloc_cpumask_var(&_cpumask_scratch[cpu]) ) Is it better to use zalloc_cpumask_var() here? > + return NULL; > + > /* 1 indicates alloc. succeed in schedule.c */ > return (void *)1; > } > @@ -462,6 +484,8 @@ rt_free_pdata(const struct scheduler *ops, void *pcpu, > int cpu) > sd->schedule_lock = &sd->_lock; > > spin_unlock_irqrestore(&prv->lock, flags); > + > + free_cpumask_var(_cpumask_scratch[cpu]); > } > > static void * > Others look good to me! Thank you very much! :-) Best, Meng ----------- Meng Xu PhD Student in Computer and Information Science University of Pennsylvania _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |