[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v15 11/21] x86/VPMU: Interface for setting PMU mode and flags
>>> On 17.11.14 at 00:07, <boris.ostrovsky@xxxxxxxxxx> wrote: > @@ -278,3 +290,139 @@ void vpmu_dump(struct vcpu *v) > vpmu->arch_vpmu_ops->arch_vpmu_dump(v); > } > > +static s_time_t vpmu_start_ctxt_switch; Blank line here please. > +static long vpmu_sched_checkin(void *arg) > +{ > + int cpu = cpumask_next(smp_processor_id(), &cpu_online_map); unsigned int. > + int ret; > + > + /* Mode change shouldn't take more than a few (say, 5) seconds. */ > + if ( NOW() > vpmu_start_ctxt_switch + SECONDS(5) ) > + { > + ret = -EBUSY; > + goto fail; > + } So what does this guard against? Holding xenpmu_mode_lock for 5 seconds is not a problem, plus I don't think you actually need a lock at all. Just using a global, atomically updated flag ought to be sufficient (the way you use the lock is really nothing else afaict). > + > + if ( cpu < nr_cpu_ids ) > + { > + ret = continue_hypercall_on_cpu(cpu, vpmu_sched_checkin, arg); > + if ( ret ) > + goto fail; > + } > + else > + vpmu_start_ctxt_switch = 0; > + > + return 0; > + > + fail: > + vpmu_mode = (uint64_t)arg; Even if we don't support x86-32 anymore, please avoid giving bad examples: Casts between pointers and integers should always use (unsigned) long on the integer side. > + vpmu_start_ctxt_switch = 0; > + return ret; > +} > + > +static int vpmu_force_context_switch(uint64_t old_mode) Same comment as above regarding the type. > +{ > + int ret; > + > + vpmu_start_ctxt_switch = NOW(); > + > + ret = continue_hypercall_on_cpu(cpumask_first(&cpu_online_map), > + vpmu_sched_checkin, (void *)old_mode); > + if ( ret ) > + vpmu_start_ctxt_switch = 0; > + > + return ret; > +} I don't think it is guaranteed (independent of implementation details of continue_hypercall_on_cpu()) that this way you went through the context switch path once on each CPU if cpumask_first(&cpu_online_map) == smp_processor_id() here. In particular it looks like there being a problem calling vcpu_sleep_sync() in the tasklet handler when v == current (which would be the case if you started on the "correct" CPU and the tasklet softirq got handled before the scheduler one). I think you instead want to use cpumask_cycle() here and above, and finish the whole operation once you're back on the CPU you started on (the single-pCPU case may need some extra consideration). I realize that you simply follow what microcode_update() does, but I think we should rather correct that one than copy the latent issue it has elsewhere. > +long do_xenpmu_op(int op, XEN_GUEST_HANDLE_PARAM(xen_pmu_params_t) arg) > +{ > + int ret; > + struct xen_pmu_params pmu_params; > + > + ret = xsm_pmu_op(XSM_OTHER, current->domain, op); > + if ( ret ) > + return ret; > + > + switch ( op ) > + { > + case XENPMU_mode_set: > + { > + uint64_t old_mode; Irrespective of the earlier comments I don't see why this isn't just unsigned int (or typeof(vpmu_mode)). Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |