@@ -550,15 +550,23 @@ static int populate_msi_sysfs(struct pci_dev *pdev)
550
550
return ret ;
551
551
}
552
552
553
- static struct msi_desc * msi_setup_entry (struct pci_dev * dev , int nvec )
553
+ static struct msi_desc *
554
+ msi_setup_entry (struct pci_dev * dev , int nvec , bool affinity )
554
555
{
555
- u16 control ;
556
+ struct cpumask * masks = NULL ;
556
557
struct msi_desc * entry ;
558
+ u16 control ;
559
+
560
+ if (affinity ) {
561
+ masks = irq_create_affinity_masks (dev -> irq_affinity , nvec );
562
+ if (!masks )
563
+ pr_err ("Unable to allocate affinity masks, ignoring\n" );
564
+ }
557
565
558
566
/* MSI Entry Initialization */
559
- entry = alloc_msi_entry (& dev -> dev );
567
+ entry = alloc_msi_entry (& dev -> dev , nvec , masks );
560
568
if (!entry )
561
- return NULL ;
569
+ goto out ;
562
570
563
571
pci_read_config_word (dev , dev -> msi_cap + PCI_MSI_FLAGS , & control );
564
572
@@ -569,8 +577,6 @@ static struct msi_desc *msi_setup_entry(struct pci_dev *dev, int nvec)
569
577
entry -> msi_attrib .default_irq = dev -> irq ; /* Save IOAPIC IRQ */
570
578
entry -> msi_attrib .multi_cap = (control & PCI_MSI_FLAGS_QMASK ) >> 1 ;
571
579
entry -> msi_attrib .multiple = ilog2 (__roundup_pow_of_two (nvec ));
572
- entry -> nvec_used = nvec ;
573
- entry -> affinity = dev -> irq_affinity ;
574
580
575
581
if (control & PCI_MSI_FLAGS_64BIT )
576
582
entry -> mask_pos = dev -> msi_cap + PCI_MSI_MASK_64 ;
@@ -581,6 +587,8 @@ static struct msi_desc *msi_setup_entry(struct pci_dev *dev, int nvec)
581
587
if (entry -> msi_attrib .maskbit )
582
588
pci_read_config_dword (dev , entry -> mask_pos , & entry -> masked );
583
589
590
+ out :
591
+ kfree (masks );
584
592
return entry ;
585
593
}
586
594
@@ -609,15 +617,15 @@ static int msi_verify_entries(struct pci_dev *dev)
609
617
* an error, and a positive return value indicates the number of interrupts
610
618
* which could have been allocated.
611
619
*/
612
- static int msi_capability_init (struct pci_dev * dev , int nvec )
620
+ static int msi_capability_init (struct pci_dev * dev , int nvec , bool affinity )
613
621
{
614
622
struct msi_desc * entry ;
615
623
int ret ;
616
624
unsigned mask ;
617
625
618
626
pci_msi_set_enable (dev , 0 ); /* Disable MSI during set up */
619
627
620
- entry = msi_setup_entry (dev , nvec );
628
+ entry = msi_setup_entry (dev , nvec , affinity );
621
629
if (!entry )
622
630
return - ENOMEM ;
623
631
@@ -680,28 +688,29 @@ static void __iomem *msix_map_region(struct pci_dev *dev, unsigned nr_entries)
680
688
}
681
689
682
690
static int msix_setup_entries (struct pci_dev * dev , void __iomem * base ,
683
- struct msix_entry * entries , int nvec )
691
+ struct msix_entry * entries , int nvec ,
692
+ bool affinity )
684
693
{
685
- const struct cpumask * mask = NULL ;
694
+ struct cpumask * curmsk , * masks = NULL ;
686
695
struct msi_desc * entry ;
687
- int cpu = -1 , i ;
688
-
689
- for (i = 0 ; i < nvec ; i ++ ) {
690
- if (dev -> irq_affinity ) {
691
- cpu = cpumask_next (cpu , dev -> irq_affinity );
692
- if (cpu >= nr_cpu_ids )
693
- cpu = cpumask_first (dev -> irq_affinity );
694
- mask = cpumask_of (cpu );
695
- }
696
+ int ret , i ;
697
+
698
+ if (affinity ) {
699
+ masks = irq_create_affinity_masks (dev -> irq_affinity , nvec );
700
+ if (!masks )
701
+ pr_err ("Unable to allocate affinity masks, ignoring\n" );
702
+ }
696
703
697
- entry = alloc_msi_entry (& dev -> dev );
704
+ for (i = 0 , curmsk = masks ; i < nvec ; i ++ ) {
705
+ entry = alloc_msi_entry (& dev -> dev , 1 , curmsk );
698
706
if (!entry ) {
699
707
if (!i )
700
708
iounmap (base );
701
709
else
702
710
free_msi_irqs (dev );
703
711
/* No enough memory. Don't try again */
704
- return - ENOMEM ;
712
+ ret = - ENOMEM ;
713
+ goto out ;
705
714
}
706
715
707
716
entry -> msi_attrib .is_msix = 1 ;
@@ -712,12 +721,14 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base,
712
721
entry -> msi_attrib .entry_nr = i ;
713
722
entry -> msi_attrib .default_irq = dev -> irq ;
714
723
entry -> mask_base = base ;
715
- entry -> nvec_used = 1 ;
716
- entry -> affinity = mask ;
717
724
718
725
list_add_tail (& entry -> list , dev_to_msi_list (& dev -> dev ));
726
+ if (masks )
727
+ curmsk ++ ;
719
728
}
720
-
729
+ ret = 0 ;
730
+ out :
731
+ kfree (masks );
721
732
return 0 ;
722
733
}
723
734
@@ -746,8 +757,8 @@ static void msix_program_entries(struct pci_dev *dev,
746
757
* single MSI-X irq. A return of zero indicates the successful setup of
747
758
* requested MSI-X entries with allocated irqs or non-zero for otherwise.
748
759
**/
749
- static int msix_capability_init (struct pci_dev * dev ,
750
- struct msix_entry * entries , int nvec )
760
+ static int msix_capability_init (struct pci_dev * dev , struct msix_entry * entries ,
761
+ int nvec , bool affinity )
751
762
{
752
763
int ret ;
753
764
u16 control ;
@@ -762,7 +773,7 @@ static int msix_capability_init(struct pci_dev *dev,
762
773
if (!base )
763
774
return - ENOMEM ;
764
775
765
- ret = msix_setup_entries (dev , base , entries , nvec );
776
+ ret = msix_setup_entries (dev , base , entries , nvec , affinity );
766
777
if (ret )
767
778
return ret ;
768
779
@@ -942,22 +953,8 @@ int pci_msix_vec_count(struct pci_dev *dev)
942
953
}
943
954
EXPORT_SYMBOL (pci_msix_vec_count );
944
955
945
- /**
946
- * pci_enable_msix - configure device's MSI-X capability structure
947
- * @dev: pointer to the pci_dev data structure of MSI-X device function
948
- * @entries: pointer to an array of MSI-X entries (optional)
949
- * @nvec: number of MSI-X irqs requested for allocation by device driver
950
- *
951
- * Setup the MSI-X capability structure of device function with the number
952
- * of requested irqs upon its software driver call to request for
953
- * MSI-X mode enabled on its hardware device function. A return of zero
954
- * indicates the successful configuration of MSI-X capability structure
955
- * with new allocated MSI-X irqs. A return of < 0 indicates a failure.
956
- * Or a return of > 0 indicates that driver request is exceeding the number
957
- * of irqs or MSI-X vectors available. Driver should use the returned value to
958
- * re-send its request.
959
- **/
960
- int pci_enable_msix (struct pci_dev * dev , struct msix_entry * entries , int nvec )
956
+ static int __pci_enable_msix (struct pci_dev * dev , struct msix_entry * entries ,
957
+ int nvec , bool affinity )
961
958
{
962
959
int nr_entries ;
963
960
int i , j ;
@@ -989,7 +986,27 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
989
986
dev_info (& dev -> dev , "can't enable MSI-X (MSI IRQ already assigned)\n" );
990
987
return - EINVAL ;
991
988
}
992
- return msix_capability_init (dev , entries , nvec );
989
+ return msix_capability_init (dev , entries , nvec , affinity );
990
+ }
991
+
992
+ /**
993
+ * pci_enable_msix - configure device's MSI-X capability structure
994
+ * @dev: pointer to the pci_dev data structure of MSI-X device function
995
+ * @entries: pointer to an array of MSI-X entries (optional)
996
+ * @nvec: number of MSI-X irqs requested for allocation by device driver
997
+ *
998
+ * Setup the MSI-X capability structure of device function with the number
999
+ * of requested irqs upon its software driver call to request for
1000
+ * MSI-X mode enabled on its hardware device function. A return of zero
1001
+ * indicates the successful configuration of MSI-X capability structure
1002
+ * with new allocated MSI-X irqs. A return of < 0 indicates a failure.
1003
+ * Or a return of > 0 indicates that driver request is exceeding the number
1004
+ * of irqs or MSI-X vectors available. Driver should use the returned value to
1005
+ * re-send its request.
1006
+ **/
1007
+ int pci_enable_msix (struct pci_dev * dev , struct msix_entry * entries , int nvec )
1008
+ {
1009
+ return __pci_enable_msix (dev , entries , nvec , false);
993
1010
}
994
1011
EXPORT_SYMBOL (pci_enable_msix );
995
1012
@@ -1042,6 +1059,7 @@ EXPORT_SYMBOL(pci_msi_enabled);
1042
1059
static int __pci_enable_msi_range (struct pci_dev * dev , int minvec , int maxvec ,
1043
1060
unsigned int flags )
1044
1061
{
1062
+ bool affinity = flags & PCI_IRQ_AFFINITY ;
1045
1063
int nvec ;
1046
1064
int rc ;
1047
1065
@@ -1070,19 +1088,17 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
1070
1088
nvec = maxvec ;
1071
1089
1072
1090
for (;;) {
1073
- if (flags & PCI_IRQ_AFFINITY ) {
1074
- dev -> irq_affinity = irq_create_affinity_mask (& nvec );
1091
+ if (affinity ) {
1092
+ nvec = irq_calc_affinity_vectors (dev -> irq_affinity ,
1093
+ nvec );
1075
1094
if (nvec < minvec )
1076
1095
return - ENOSPC ;
1077
1096
}
1078
1097
1079
- rc = msi_capability_init (dev , nvec );
1098
+ rc = msi_capability_init (dev , nvec , affinity );
1080
1099
if (rc == 0 )
1081
1100
return nvec ;
1082
1101
1083
- kfree (dev -> irq_affinity );
1084
- dev -> irq_affinity = NULL ;
1085
-
1086
1102
if (rc < 0 )
1087
1103
return rc ;
1088
1104
if (rc < minvec )
@@ -1114,26 +1130,24 @@ static int __pci_enable_msix_range(struct pci_dev *dev,
1114
1130
struct msix_entry * entries , int minvec , int maxvec ,
1115
1131
unsigned int flags )
1116
1132
{
1117
- int nvec = maxvec ;
1118
- int rc ;
1133
+ bool affinity = flags & PCI_IRQ_AFFINITY ;
1134
+ int rc , nvec = maxvec ;
1119
1135
1120
1136
if (maxvec < minvec )
1121
1137
return - ERANGE ;
1122
1138
1123
1139
for (;;) {
1124
- if (flags & PCI_IRQ_AFFINITY ) {
1125
- dev -> irq_affinity = irq_create_affinity_mask (& nvec );
1140
+ if (affinity ) {
1141
+ nvec = irq_calc_affinity_vectors (dev -> irq_affinity ,
1142
+ nvec );
1126
1143
if (nvec < minvec )
1127
1144
return - ENOSPC ;
1128
1145
}
1129
1146
1130
- rc = pci_enable_msix (dev , entries , nvec );
1147
+ rc = __pci_enable_msix (dev , entries , nvec , affinity );
1131
1148
if (rc == 0 )
1132
1149
return nvec ;
1133
1150
1134
- kfree (dev -> irq_affinity );
1135
- dev -> irq_affinity = NULL ;
1136
-
1137
1151
if (rc < 0 )
1138
1152
return rc ;
1139
1153
if (rc < minvec )
@@ -1257,6 +1271,37 @@ int pci_irq_vector(struct pci_dev *dev, unsigned int nr)
1257
1271
}
1258
1272
EXPORT_SYMBOL (pci_irq_vector );
1259
1273
1274
+ /**
1275
+ * pci_irq_get_affinity - return the affinity of a particular msi vector
1276
+ * @dev: PCI device to operate on
1277
+ * @nr: device-relative interrupt vector index (0-based).
1278
+ */
1279
+ const struct cpumask * pci_irq_get_affinity (struct pci_dev * dev , int nr )
1280
+ {
1281
+ if (dev -> msix_enabled ) {
1282
+ struct msi_desc * entry ;
1283
+ int i = 0 ;
1284
+
1285
+ for_each_pci_msi_entry (entry , dev ) {
1286
+ if (i == nr )
1287
+ return entry -> affinity ;
1288
+ i ++ ;
1289
+ }
1290
+ WARN_ON_ONCE (1 );
1291
+ return NULL ;
1292
+ } else if (dev -> msi_enabled ) {
1293
+ struct msi_desc * entry = first_pci_msi_entry (dev );
1294
+
1295
+ if (WARN_ON_ONCE (!entry || nr >= entry -> nvec_used ))
1296
+ return NULL ;
1297
+
1298
+ return & entry -> affinity [nr ];
1299
+ } else {
1300
+ return cpu_possible_mask ;
1301
+ }
1302
+ }
1303
+ EXPORT_SYMBOL (pci_irq_get_affinity );
1304
+
1260
1305
struct pci_dev * msi_desc_to_pci_dev (struct msi_desc * desc )
1261
1306
{
1262
1307
return to_pci_dev (desc -> dev );
0 commit comments