@@ -104,8 +104,6 @@ struct arm_ni_cd {
104104 u16 id ;
105105 int num_units ;
106106 int irq ;
107- int cpu ;
108- struct hlist_node cpuhp_node ;
109107 struct pmu pmu ;
110108 struct arm_ni_unit * units ;
111109 struct perf_event * evcnt [NI_NUM_COUNTERS ];
@@ -117,13 +115,18 @@ struct arm_ni {
117115 void __iomem * base ;
118116 enum ni_part part ;
119117 int id ;
118+ int cpu ;
120119 int num_cds ;
120+ struct hlist_node cpuhp_node ;
121121 struct arm_ni_cd cds [] __counted_by (num_cds );
122122};
123123
124124#define cd_to_ni (cd ) container_of((cd), struct arm_ni, cds[(cd)->id])
125125#define pmu_to_cd (p ) container_of((p), struct arm_ni_cd, pmu)
126126
127+ #define ni_for_each_cd (n , c ) \
128+ for (struct arm_ni_cd *c = n->cds; c < n->cds + n->num_cds; c++) if (c->pmu_base)
129+
127130#define cd_for_each_unit (cd , u ) \
128131 for (struct arm_ni_unit *u = cd->units; u < cd->units + cd->num_units; u++)
129132
@@ -218,9 +221,9 @@ static const struct attribute_group arm_ni_format_attrs_group = {
218221static ssize_t arm_ni_cpumask_show (struct device * dev ,
219222 struct device_attribute * attr , char * buf )
220223{
221- struct arm_ni_cd * cd = pmu_to_cd (dev_get_drvdata (dev ));
224+ struct arm_ni * ni = cd_to_ni ( pmu_to_cd (dev_get_drvdata (dev ) ));
222225
223- return cpumap_print_to_pagebuf (true, buf , cpumask_of (cd -> cpu ));
226+ return cpumap_print_to_pagebuf (true, buf , cpumask_of (ni -> cpu ));
224227}
225228
226229static struct device_attribute arm_ni_cpumask_attr =
@@ -314,7 +317,7 @@ static int arm_ni_event_init(struct perf_event *event)
314317 if (is_sampling_event (event ))
315318 return - EINVAL ;
316319
317- event -> cpu = cd -> cpu ;
320+ event -> cpu = cd_to_ni ( cd ) -> cpu ;
318321 if (NI_EVENT_TYPE (event ) == NI_PMU )
319322 return arm_ni_validate_group (event );
320323
@@ -543,8 +546,7 @@ static int arm_ni_init_cd(struct arm_ni *ni, struct arm_ni_node *node, u64 res_s
543546 if (err )
544547 return err ;
545548
546- cd -> cpu = cpumask_local_spread (0 , dev_to_node (ni -> dev ));
547- irq_set_affinity (cd -> irq , cpumask_of (cd -> cpu ));
549+ irq_set_affinity (cd -> irq , cpumask_of (ni -> cpu ));
548550
549551 cd -> pmu = (struct pmu ) {
550552 .module = THIS_MODULE ,
@@ -566,32 +568,19 @@ static int arm_ni_init_cd(struct arm_ni *ni, struct arm_ni_node *node, u64 res_s
566568 if (!name )
567569 return - ENOMEM ;
568570
569- err = cpuhp_state_add_instance_nocalls (arm_ni_hp_state , & cd -> cpuhp_node );
570- if (err )
571- return err ;
572-
573- err = perf_pmu_register (& cd -> pmu , name , -1 );
574- if (err )
575- cpuhp_state_remove_instance_nocalls (arm_ni_hp_state , & cd -> cpuhp_node );
576-
577- return err ;
571+ return perf_pmu_register (& cd -> pmu , name , -1 );
578572}
579573
580574static void arm_ni_remove (struct platform_device * pdev )
581575{
582576 struct arm_ni * ni = platform_get_drvdata (pdev );
583577
584- for (int i = 0 ; i < ni -> num_cds ; i ++ ) {
585- struct arm_ni_cd * cd = ni -> cds + i ;
586-
587- if (!cd -> pmu_base )
588- continue ;
589-
578+ ni_for_each_cd (ni , cd ) {
590579 writel_relaxed (0 , cd -> pmu_base + NI_PMCR );
591580 writel_relaxed (U32_MAX , cd -> pmu_base + NI_PMINTENCLR );
592581 perf_pmu_unregister (& cd -> pmu );
593- cpuhp_state_remove_instance_nocalls (arm_ni_hp_state , & cd -> cpuhp_node );
594582 }
583+ cpuhp_state_remove_instance_nocalls (arm_ni_hp_state , & ni -> cpuhp_node );
595584}
596585
597586static void arm_ni_probe_domain (void __iomem * base , struct arm_ni_node * node )
@@ -611,7 +600,7 @@ static int arm_ni_probe(struct platform_device *pdev)
611600 struct resource * res ;
612601 void __iomem * base ;
613602 static atomic_t id ;
614- int num_cds ;
603+ int ret , num_cds ;
615604 u32 reg , part ;
616605
617606 /*
@@ -662,17 +651,20 @@ static int arm_ni_probe(struct platform_device *pdev)
662651 ni -> num_cds = num_cds ;
663652 ni -> part = part ;
664653 ni -> id = atomic_fetch_inc (& id );
654+ ni -> cpu = cpumask_local_spread (0 , dev_to_node (ni -> dev ));
665655 platform_set_drvdata (pdev , ni );
666656
657+ ret = cpuhp_state_add_instance_nocalls (arm_ni_hp_state , & ni -> cpuhp_node );
658+ if (ret )
659+ return ret ;
660+
667661 for (int v = 0 ; v < cfg .num_components ; v ++ ) {
668662 reg = readl_relaxed (cfg .base + NI_CHILD_PTR (v ));
669663 arm_ni_probe_domain (base + reg , & vd );
670664 for (int p = 0 ; p < vd .num_components ; p ++ ) {
671665 reg = readl_relaxed (vd .base + NI_CHILD_PTR (p ));
672666 arm_ni_probe_domain (base + reg , & pd );
673667 for (int c = 0 ; c < pd .num_components ; c ++ ) {
674- int ret ;
675-
676668 reg = readl_relaxed (pd .base + NI_CHILD_PTR (c ));
677669 arm_ni_probe_domain (base + reg , & cd );
678670 ret = arm_ni_init_cd (ni , & cd , res -> start );
@@ -715,42 +707,44 @@ static struct platform_driver arm_ni_driver = {
715707 .remove = arm_ni_remove ,
716708};
717709
718- static void arm_ni_pmu_migrate (struct arm_ni_cd * cd , unsigned int cpu )
710+ static void arm_ni_pmu_migrate (struct arm_ni * ni , unsigned int cpu )
719711{
720- perf_pmu_migrate_context (& cd -> pmu , cd -> cpu , cpu );
721- irq_set_affinity (cd -> irq , cpumask_of (cpu ));
722- cd -> cpu = cpu ;
712+ ni_for_each_cd (ni , cd ) {
713+ perf_pmu_migrate_context (& cd -> pmu , ni -> cpu , cpu );
714+ irq_set_affinity (cd -> irq , cpumask_of (cpu ));
715+ }
716+ ni -> cpu = cpu ;
723717}
724718
725719static int arm_ni_pmu_online_cpu (unsigned int cpu , struct hlist_node * cpuhp_node )
726720{
727- struct arm_ni_cd * cd ;
721+ struct arm_ni * ni ;
728722 int node ;
729723
730- cd = hlist_entry_safe (cpuhp_node , struct arm_ni_cd , cpuhp_node );
731- node = dev_to_node (cd_to_ni ( cd ) -> dev );
732- if (cpu_to_node (cd -> cpu ) != node && cpu_to_node (cpu ) == node )
733- arm_ni_pmu_migrate (cd , cpu );
724+ ni = hlist_entry_safe (cpuhp_node , struct arm_ni , cpuhp_node );
725+ node = dev_to_node (ni -> dev );
726+ if (cpu_to_node (ni -> cpu ) != node && cpu_to_node (cpu ) == node )
727+ arm_ni_pmu_migrate (ni , cpu );
734728 return 0 ;
735729}
736730
737731static int arm_ni_pmu_offline_cpu (unsigned int cpu , struct hlist_node * cpuhp_node )
738732{
739- struct arm_ni_cd * cd ;
733+ struct arm_ni * ni ;
740734 unsigned int target ;
741735 int node ;
742736
743- cd = hlist_entry_safe (cpuhp_node , struct arm_ni_cd , cpuhp_node );
744- if (cpu != cd -> cpu )
737+ ni = hlist_entry_safe (cpuhp_node , struct arm_ni , cpuhp_node );
738+ if (cpu != ni -> cpu )
745739 return 0 ;
746740
747- node = dev_to_node (cd_to_ni ( cd ) -> dev );
741+ node = dev_to_node (ni -> dev );
748742 target = cpumask_any_and_but (cpumask_of_node (node ), cpu_online_mask , cpu );
749743 if (target >= nr_cpu_ids )
750744 target = cpumask_any_but (cpu_online_mask , cpu );
751745
752746 if (target < nr_cpu_ids )
753- arm_ni_pmu_migrate (cd , target );
747+ arm_ni_pmu_migrate (ni , target );
754748 return 0 ;
755749}
756750
0 commit comments