@@ -11830,6 +11830,21 @@ static int pmu_dev_alloc(struct pmu *pmu)
1183011830static struct lock_class_key cpuctx_mutex ;
1183111831static struct lock_class_key cpuctx_lock ;
1183211832
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+
1183311848int perf_pmu_register (struct pmu * pmu , const char * name , int type )
1183411849{
1183511850 int cpu , ret , max = PERF_TYPE_MAX ;
@@ -11856,14 +11871,15 @@ int perf_pmu_register(struct pmu *pmu, const char *name, int type)
1185611871 if (type >= 0 )
1185711872 max = type ;
1185811873
11859- ret = idr_alloc (& pmu_idr , pmu , max , 0 , GFP_KERNEL );
11874+ ret = idr_alloc (& pmu_idr , NULL , max , 0 , GFP_KERNEL );
1186011875 if (ret < 0 )
1186111876 goto free_pdc ;
1186211877
1186311878 WARN_ON (type >= 0 && ret != type );
1186411879
1186511880 type = ret ;
1186611881 pmu -> type = type ;
11882+ atomic_set (& pmu -> exclusive_cnt , 0 );
1186711883
1186811884 if (pmu_bus_running && !pmu -> dev ) {
1186911885 ret = pmu_dev_alloc (pmu );
@@ -11912,14 +11928,22 @@ int perf_pmu_register(struct pmu *pmu, const char *name, int type)
1191211928 if (!pmu -> event_idx )
1191311929 pmu -> event_idx = perf_event_idx_default ;
1191411930
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 ;
1191511936 list_add_rcu (& pmu -> entry , & pmus );
11916- atomic_set ( & pmu -> exclusive_cnt , 0 );
11937+
1191711938 ret = 0 ;
1191811939unlock :
1191911940 mutex_unlock (& pmus_lock );
1192011941
1192111942 return ret ;
1192211943
11944+ free_context :
11945+ free_percpu (pmu -> cpu_pmu_context );
11946+
1192311947free_dev :
1192411948 if (pmu -> dev && pmu -> dev != PMU_NULL_DEV ) {
1192511949 device_del (pmu -> dev );
@@ -11939,6 +11963,8 @@ void perf_pmu_unregister(struct pmu *pmu)
1193911963{
1194011964 mutex_lock (& pmus_lock );
1194111965 list_del_rcu (& pmu -> entry );
11966+ idr_remove (& pmu_idr , pmu -> type );
11967+ mutex_unlock (& pmus_lock );
1194211968
1194311969 /*
1194411970 * We dereference the pmu list under both SRCU and regular RCU, so
@@ -11948,15 +11974,13 @@ void perf_pmu_unregister(struct pmu *pmu)
1194811974 synchronize_rcu ();
1194911975
1195011976 free_percpu (pmu -> pmu_disable_count );
11951- idr_remove (& pmu_idr , pmu -> type );
1195211977 if (pmu_bus_running && pmu -> dev && pmu -> dev != PMU_NULL_DEV ) {
1195311978 if (pmu -> nr_addr_filters )
1195411979 device_remove_file (pmu -> dev , & dev_attr_nr_addr_filters );
1195511980 device_del (pmu -> dev );
1195611981 put_device (pmu -> dev );
1195711982 }
1195811983 free_pmu_context (pmu );
11959- mutex_unlock (& pmus_lock );
1196011984}
1196111985EXPORT_SYMBOL_GPL (perf_pmu_unregister );
1196211986
0 commit comments