2626
2727#include <asm/irq_regs.h>
2828
29- static int armpmu_count_irq_users (const int irq );
29+ static int armpmu_count_irq_users (const struct cpumask * affinity ,
30+ const int irq );
3031
3132struct pmu_irq_ops {
3233 void (* enable_pmuirq )(unsigned int irq );
@@ -64,7 +65,9 @@ static void armpmu_enable_percpu_pmuirq(unsigned int irq)
6465static void armpmu_free_percpu_pmuirq (unsigned int irq , int cpu ,
6566 void __percpu * devid )
6667{
67- if (armpmu_count_irq_users (irq ) == 1 )
68+ struct arm_pmu * armpmu = * per_cpu_ptr ((void * __percpu * )devid , cpu );
69+
70+ if (armpmu_count_irq_users (& armpmu -> supported_cpus , irq ) == 1 )
6871 free_percpu_irq (irq , devid );
6972}
7073
@@ -89,7 +92,9 @@ static void armpmu_disable_percpu_pmunmi(unsigned int irq)
8992static void armpmu_free_percpu_pmunmi (unsigned int irq , int cpu ,
9093 void __percpu * devid )
9194{
92- if (armpmu_count_irq_users (irq ) == 1 )
95+ struct arm_pmu * armpmu = * per_cpu_ptr ((void * __percpu * )devid , cpu );
96+
97+ if (armpmu_count_irq_users (& armpmu -> supported_cpus , irq ) == 1 )
9398 free_percpu_nmi (irq , devid );
9499}
95100
@@ -580,24 +585,25 @@ static const struct attribute_group armpmu_common_attr_group = {
580585 .attrs = armpmu_common_attrs ,
581586};
582587
583- static int armpmu_count_irq_users (const int irq )
588+ static int armpmu_count_irq_users (const struct cpumask * affinity , const int irq )
584589{
585590 int cpu , count = 0 ;
586591
587- for_each_possible_cpu (cpu ) {
592+ for_each_cpu (cpu , affinity ) {
588593 if (per_cpu (cpu_irq , cpu ) == irq )
589594 count ++ ;
590595 }
591596
592597 return count ;
593598}
594599
595- static const struct pmu_irq_ops * armpmu_find_irq_ops (int irq )
600+ static const struct pmu_irq_ops *
601+ armpmu_find_irq_ops (const struct cpumask * affinity , int irq )
596602{
597603 const struct pmu_irq_ops * ops = NULL ;
598604 int cpu ;
599605
600- for_each_possible_cpu (cpu ) {
606+ for_each_cpu (cpu , affinity ) {
601607 if (per_cpu (cpu_irq , cpu ) != irq )
602608 continue ;
603609
@@ -609,22 +615,25 @@ static const struct pmu_irq_ops *armpmu_find_irq_ops(int irq)
609615 return ops ;
610616}
611617
612- void armpmu_free_irq (int irq , int cpu )
618+ void armpmu_free_irq (struct arm_pmu * __percpu * armpmu , int irq , int cpu )
613619{
614620 if (per_cpu (cpu_irq , cpu ) == 0 )
615621 return ;
616622 if (WARN_ON (irq != per_cpu (cpu_irq , cpu )))
617623 return ;
618624
619- per_cpu (cpu_irq_ops , cpu )-> free_pmuirq (irq , cpu , & cpu_armpmu );
625+ per_cpu (cpu_irq_ops , cpu )-> free_pmuirq (irq , cpu , armpmu );
620626
621627 per_cpu (cpu_irq , cpu ) = 0 ;
622628 per_cpu (cpu_irq_ops , cpu ) = NULL ;
623629}
624630
625- int armpmu_request_irq (int irq , int cpu )
631+ int armpmu_request_irq (struct arm_pmu * __percpu * pcpu_armpmu , int irq , int cpu )
626632{
627633 int err = 0 ;
634+ struct arm_pmu * * armpmu = per_cpu_ptr (pcpu_armpmu , cpu );
635+ const struct cpumask * affinity = * armpmu ? & (* armpmu )-> supported_cpus :
636+ cpu_possible_mask ; /* ACPI */
628637 const irq_handler_t handler = armpmu_dispatch_irq ;
629638 const struct pmu_irq_ops * irq_ops ;
630639
@@ -646,33 +655,32 @@ int armpmu_request_irq(int irq, int cpu)
646655 IRQF_NOBALANCING | IRQF_NO_AUTOEN |
647656 IRQF_NO_THREAD ;
648657
649- err = request_nmi (irq , handler , irq_flags , "arm-pmu" ,
650- per_cpu_ptr (& cpu_armpmu , cpu ));
658+ err = request_nmi (irq , handler , irq_flags , "arm-pmu" , armpmu );
651659
652660 /* If cannot get an NMI, get a normal interrupt */
653661 if (err ) {
654662 err = request_irq (irq , handler , irq_flags , "arm-pmu" ,
655- per_cpu_ptr ( & cpu_armpmu , cpu ) );
663+ armpmu );
656664 irq_ops = & pmuirq_ops ;
657665 } else {
658666 has_nmi = true;
659667 irq_ops = & pmunmi_ops ;
660668 }
661- } else if (armpmu_count_irq_users (irq ) == 0 ) {
662- err = request_percpu_nmi (irq , handler , "arm-pmu" , NULL , & cpu_armpmu );
669+ } else if (armpmu_count_irq_users (affinity , irq ) == 0 ) {
670+ err = request_percpu_nmi (irq , handler , "arm-pmu" , affinity , pcpu_armpmu );
663671
664672 /* If cannot get an NMI, get a normal interrupt */
665673 if (err ) {
666- err = request_percpu_irq (irq , handler , "arm-pmu" ,
667- & cpu_armpmu );
674+ err = request_percpu_irq_affinity (irq , handler , "arm-pmu" ,
675+ affinity , pcpu_armpmu );
668676 irq_ops = & percpu_pmuirq_ops ;
669677 } else {
670678 has_nmi = true;
671679 irq_ops = & percpu_pmunmi_ops ;
672680 }
673681 } else {
674682 /* Per cpudevid irq was already requested by another CPU */
675- irq_ops = armpmu_find_irq_ops (irq );
683+ irq_ops = armpmu_find_irq_ops (affinity , irq );
676684
677685 if (WARN_ON (!irq_ops ))
678686 err = - EINVAL ;
0 commit comments