On Thu, Oct 20, 2016 at 11:04:16AM +0200, Peter Zijlstra wrote:
> On Thu, Oct 20, 2016 at 10:58:03AM +0200, Jiri Olsa wrote:
> 
> > @@ -8869,11 +8869,15 @@ void perf_pmu_unregister(struct pmu *pmu)
> >     free_percpu(pmu->pmu_disable_count);
> >     if (pmu->type >= PERF_TYPE_MAX)
> >             idr_remove(&pmu_idr, pmu->type);
> > -   if (pmu->nr_addr_filters)
> > -           device_remove_file(pmu->dev, &dev_attr_nr_addr_filters);
> > -   device_del(pmu->dev);
> > -   put_device(pmu->dev);
> > +   mutex_lock(&pmus_lock);
> > +   if (pmu_bus_running) {
> > +           if (pmu->nr_addr_filters)
> > +                   device_remove_file(pmu->dev, &dev_attr_nr_addr_filters);
> > +           device_del(pmu->dev);
> > +           put_device(pmu->dev);
> > +   }
> >     free_pmu_context(pmu);
> > +   mutex_unlock(&pmus_lock);
> >  }
> >  EXPORT_SYMBOL_GPL(perf_pmu_unregister);
> 
> I think that is still racy..
> 
> 
> unregister:           sysfs_init:
> 
> mutex_lock(&pmus_lock);
> list_del_rcu(&pmu->entry);
> mutex_unlock(&pmus_lock);
> 
> synchronize_*rcu();
> 
>                       mutex_lock(&pmus_lock);
>                       list_for_each_entry(pmu, &pmus, entry) {
>                               /* add device muck */

ah, I thought this part would add the device back.. but it's
already out of the pmu list.. right :-\

thanks,
jirka

>                               /* will _NOT_ see our PMU */
>                       }
>                       pmus_bus_running = 1;
>                       mutex_unlock(&pmus_lock);
> 
> mutex_lock(&pmus_lock);
> if (pmu_bus_running) {
>       device_del() /* OOPS */
> 
> 
> What you want is to read pmu_bus_running in the same pmus_lock section
> as we do the list_del, and then use that local copy later.

Reply via email to