[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v13 for-xen-4.5 11/21] x86/VPMU: Interface for setting PMU mode and flags
>>> On 03.10.14 at 23:40, <boris.ostrovsky@xxxxxxxxxx> wrote: > @@ -274,3 +292,176 @@ void vpmu_dump(struct vcpu *v) > vpmu->arch_vpmu_ops->arch_vpmu_dump(v); > } > > +static atomic_t vpmu_sched_counter; > + > +static void vpmu_sched_checkin(unsigned long unused) > +{ > + atomic_inc(&vpmu_sched_counter); > +} > + > +static int vpmu_force_context_switch(void) > +{ > + unsigned i, numcpus, mycpu; > + s_time_t start; > + static DEFINE_PER_CPU(struct tasklet *, sync_task); > + int ret = 0; > + > + numcpus = num_online_cpus(); > + mycpu = smp_processor_id(); > + > + for ( i = 0; i < numcpus; i++ ) for_each_online_cpu() would have saved you from running into ... > + { > + if ( i == mycpu ) > + continue; > + > + per_cpu(sync_task, i) = xmalloc(struct tasklet); ... a crash here when some CPU other than the highest numbered one got offlined. > + if ( per_cpu(sync_task, i) == NULL ) > + { > + printk(XENLOG_WARNING "vpmu_force_context_switch: out of > memory\n"); > + ret = -ENOMEM; > + goto out; > + } > + tasklet_init(per_cpu(sync_task, i), vpmu_sched_checkin, 0); > + } > + > + /* First count is for self */ > + atomic_set(&vpmu_sched_counter, 1); > + > + for_each_online_cpu( i ) And oddly enough you use it here (albeit with malformed style - either you drop the two blanks inside the parentheses or you add another before the opening one)... > + { > + if ( i != mycpu ) > + tasklet_schedule_on_cpu(per_cpu(sync_task, i), i); > + } > + > + vpmu_save(current); > + > + start = NOW(); > + > + /* > + * Note that we may fail here if a CPU is hot-plugged while we are > + * waiting. We will then time out. > + */ > + while ( atomic_read(&vpmu_sched_counter) != numcpus ) > + { > + s_time_t now; > + > + cpu_relax(); > + > + now = NOW(); > + > + /* Give up after 5 seconds */ > + if ( now > start + SECONDS(5) ) > + { > + printk(XENLOG_WARNING > + "vpmu_force_context_switch: failed to sync\n"); > + ret = -EBUSY; > + break; > + } > + > + /* Or after (arbitrarily chosen) 2ms if need to be preempted */ > + if ( (now > start + MILLISECS(2)) && hypercall_preempt_check() ) > + { > + ret = -EAGAIN; > + break; > + } > + } So this time round you don't retain any state between retries at all. How is this process expected to ever complete on a large and loaded enough system? > + case XENPMU_feature_get: > + memset(&pmu_params, 0, sizeof(pmu_params)); > + pmu_params.val = vpmu_features; > + if ( copy_to_guest(arg, &pmu_params, 1) ) Other than for XENPMU_mode_get this could be had easier without memset() if you used copy_field_to_guest(). > +/* Parameters structure for HYPERVISOR_xenpmu_op call */ > +struct xen_pmu_params { > + /* IN/OUT parameters */ > + struct { > + uint32_t maj; > + uint32_t min; > + } version; > + uint64_t val; > + > + /* IN parameters */ > + uint64_t vcpu; Why would we need 64 bits to represent a vCPU? Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |