@@ -11830,6 +11830,21 @@ static int pmu_dev_alloc(struct pmu *pmu)
11830
11830
static struct lock_class_key cpuctx_mutex ;
11831
11831
static struct lock_class_key cpuctx_lock ;
11832
11832
11833
+ static bool idr_cmpxchg (struct idr * idr , unsigned long id , void * old , void * new )
11834
+ {
11835
+ void * tmp , * val = idr_find (idr , id );
11836
+
11837
+ if (val != old )
11838
+ return false;
11839
+
11840
+ tmp = idr_replace (idr , new , id );
11841
+ if (IS_ERR (tmp ))
11842
+ return false;
11843
+
11844
+ WARN_ON_ONCE (tmp != val );
11845
+ return true;
11846
+ }
11847
+
11833
11848
int perf_pmu_register (struct pmu * pmu , const char * name , int type )
11834
11849
{
11835
11850
int cpu , ret , max = PERF_TYPE_MAX ;
@@ -11856,14 +11871,15 @@ int perf_pmu_register(struct pmu *pmu, const char *name, int type)
11856
11871
if (type >= 0 )
11857
11872
max = type ;
11858
11873
11859
- ret = idr_alloc (& pmu_idr , pmu , max , 0 , GFP_KERNEL );
11874
+ ret = idr_alloc (& pmu_idr , NULL , max , 0 , GFP_KERNEL );
11860
11875
if (ret < 0 )
11861
11876
goto free_pdc ;
11862
11877
11863
11878
WARN_ON (type >= 0 && ret != type );
11864
11879
11865
11880
type = ret ;
11866
11881
pmu -> type = type ;
11882
+ atomic_set (& pmu -> exclusive_cnt , 0 );
11867
11883
11868
11884
if (pmu_bus_running && !pmu -> dev ) {
11869
11885
ret = pmu_dev_alloc (pmu );
@@ -11912,14 +11928,22 @@ int perf_pmu_register(struct pmu *pmu, const char *name, int type)
11912
11928
if (!pmu -> event_idx )
11913
11929
pmu -> event_idx = perf_event_idx_default ;
11914
11930
11931
+ /*
11932
+ * Now that the PMU is complete, make it visible to perf_try_init_event().
11933
+ */
11934
+ if (!idr_cmpxchg (& pmu_idr , pmu -> type , NULL , pmu ))
11935
+ goto free_context ;
11915
11936
list_add_rcu (& pmu -> entry , & pmus );
11916
- atomic_set ( & pmu -> exclusive_cnt , 0 );
11937
+
11917
11938
ret = 0 ;
11918
11939
unlock :
11919
11940
mutex_unlock (& pmus_lock );
11920
11941
11921
11942
return ret ;
11922
11943
11944
+ free_context :
11945
+ free_percpu (pmu -> cpu_pmu_context );
11946
+
11923
11947
free_dev :
11924
11948
if (pmu -> dev && pmu -> dev != PMU_NULL_DEV ) {
11925
11949
device_del (pmu -> dev );
@@ -11939,6 +11963,8 @@ void perf_pmu_unregister(struct pmu *pmu)
11939
11963
{
11940
11964
mutex_lock (& pmus_lock );
11941
11965
list_del_rcu (& pmu -> entry );
11966
+ idr_remove (& pmu_idr , pmu -> type );
11967
+ mutex_unlock (& pmus_lock );
11942
11968
11943
11969
/*
11944
11970
* We dereference the pmu list under both SRCU and regular RCU, so
@@ -11948,15 +11974,13 @@ void perf_pmu_unregister(struct pmu *pmu)
11948
11974
synchronize_rcu ();
11949
11975
11950
11976
free_percpu (pmu -> pmu_disable_count );
11951
- idr_remove (& pmu_idr , pmu -> type );
11952
11977
if (pmu_bus_running && pmu -> dev && pmu -> dev != PMU_NULL_DEV ) {
11953
11978
if (pmu -> nr_addr_filters )
11954
11979
device_remove_file (pmu -> dev , & dev_attr_nr_addr_filters );
11955
11980
device_del (pmu -> dev );
11956
11981
put_device (pmu -> dev );
11957
11982
}
11958
11983
free_pmu_context (pmu );
11959
- mutex_unlock (& pmus_lock );
11960
11984
}
11961
11985
EXPORT_SYMBOL_GPL (perf_pmu_unregister );
11962
11986
0 commit comments