diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2014-02-14 16:38:00 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-02-14 16:38:00 -0500 |
commit | c128856b48b1a7132166c6b37a53b086d549fbde (patch) | |
tree | c4c1bb2baa1e25a436f09efb17a8304364bf7901 | |
parent | c80ef97ae4848c4592f0fac9c06d7f436862a28d (diff) | |
parent | 94cccde648d32abe61e2d0d1b18178f3027f1a78 (diff) |
Merge branch 'pci/msi' into next
* pci/msi:
vfio: Use pci_enable_msi_range() and pci_enable_msix_range()
ahci: Use pci_enable_msi_range() instead of pci_enable_msi_block()
ahci: Fix broken fallback to single MSI mode
PCI/MSI: Add pci_enable_msi_exact() and pci_enable_msix_exact()
PCI/MSI: Fix cut-and-paste errors in documentation
PCI/MSI: Add pci_enable_msi() documentation back
PCI/MSI: Fix pci_msix_vec_count() htmldocs failure
PCI/MSI: Fix leak of msi_attrs
PCI/MSI: Check kmalloc() return value, fix leak of name
-rw-r--r-- | Documentation/PCI/MSI-HOWTO.txt | 119 | ||||
-rw-r--r-- | drivers/ata/ahci.c | 18 | ||||
-rw-r--r-- | drivers/pci/msi.c | 10 | ||||
-rw-r--r-- | drivers/vfio/pci/vfio_pci_intrs.c | 12 | ||||
-rw-r--r-- | include/linux/pci.h | 20 |
5 files changed, 154 insertions, 25 deletions
diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt index a8d01005f480..10a93696e55a 100644 --- a/Documentation/PCI/MSI-HOWTO.txt +++ b/Documentation/PCI/MSI-HOWTO.txt | |||
@@ -82,7 +82,19 @@ Most of the hard work is done for the driver in the PCI layer. It simply | |||
82 | has to request that the PCI layer set up the MSI capability for this | 82 | has to request that the PCI layer set up the MSI capability for this |
83 | device. | 83 | device. |
84 | 84 | ||
85 | 4.2.1 pci_enable_msi_range | 85 | 4.2.1 pci_enable_msi |
86 | |||
87 | int pci_enable_msi(struct pci_dev *dev) | ||
88 | |||
89 | A successful call allocates ONE interrupt to the device, regardless | ||
90 | of how many MSIs the device supports. The device is switched from | ||
91 | pin-based interrupt mode to MSI mode. The dev->irq number is changed | ||
92 | to a new number which represents the message signaled interrupt; | ||
93 | consequently, this function should be called before the driver calls | ||
94 | request_irq(), because an MSI is delivered via a vector that is | ||
95 | different from the vector of a pin-based interrupt. | ||
96 | |||
97 | 4.2.2 pci_enable_msi_range | ||
86 | 98 | ||
87 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) | 99 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) |
88 | 100 | ||
@@ -147,6 +159,11 @@ static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec) | |||
147 | return pci_enable_msi_range(pdev, nvec, nvec); | 159 | return pci_enable_msi_range(pdev, nvec, nvec); |
148 | } | 160 | } |
149 | 161 | ||
162 | Note, unlike pci_enable_msi_exact() function, which could be also used to | ||
163 | enable a particular number of MSI-X interrupts, pci_enable_msi_range() | ||
164 | returns either a negative errno or 'nvec' (not negative errno or 0 - as | ||
165 | pci_enable_msi_exact() does). | ||
166 | |||
150 | 4.2.1.3 Single MSI mode | 167 | 4.2.1.3 Single MSI mode |
151 | 168 | ||
152 | The most notorious example of the request type described above is | 169 | The most notorious example of the request type described above is |
@@ -158,7 +175,27 @@ static int foo_driver_enable_single_msi(struct pci_dev *pdev) | |||
158 | return pci_enable_msi_range(pdev, 1, 1); | 175 | return pci_enable_msi_range(pdev, 1, 1); |
159 | } | 176 | } |
160 | 177 | ||
161 | 4.2.2 pci_disable_msi | 178 | Note, unlike pci_enable_msi() function, which could be also used to |
179 | enable the single MSI mode, pci_enable_msi_range() returns either a | ||
180 | negative errno or 1 (not negative errno or 0 - as pci_enable_msi() | ||
181 | does). | ||
182 | |||
183 | 4.2.3 pci_enable_msi_exact | ||
184 | |||
185 | int pci_enable_msi_exact(struct pci_dev *dev, int nvec) | ||
186 | |||
187 | This variation on pci_enable_msi_range() call allows a device driver to | ||
188 | request exactly 'nvec' MSIs. | ||
189 | |||
190 | If this function returns a negative number, it indicates an error and | ||
191 | the driver should not attempt to request any more MSI interrupts for | ||
192 | this device. | ||
193 | |||
194 | By contrast with pci_enable_msi_range() function, pci_enable_msi_exact() | ||
195 | returns zero in case of success, which indicates MSI interrupts have been | ||
196 | successfully allocated. | ||
197 | |||
198 | 4.2.4 pci_disable_msi | ||
162 | 199 | ||
163 | void pci_disable_msi(struct pci_dev *dev) | 200 | void pci_disable_msi(struct pci_dev *dev) |
164 | 201 | ||
@@ -172,7 +209,7 @@ on any interrupt for which it previously called request_irq(). | |||
172 | Failure to do so results in a BUG_ON(), leaving the device with | 209 | Failure to do so results in a BUG_ON(), leaving the device with |
173 | MSI enabled and thus leaking its vector. | 210 | MSI enabled and thus leaking its vector. |
174 | 211 | ||
175 | 4.2.3 pci_msi_vec_count | 212 | 4.2.4 pci_msi_vec_count |
176 | 213 | ||
177 | int pci_msi_vec_count(struct pci_dev *dev) | 214 | int pci_msi_vec_count(struct pci_dev *dev) |
178 | 215 | ||
@@ -257,8 +294,8 @@ possible, likely up to the limit returned by pci_msix_vec_count() function: | |||
257 | 294 | ||
258 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) | 295 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) |
259 | { | 296 | { |
260 | return pci_enable_msi_range(adapter->pdev, adapter->msix_entries, | 297 | return pci_enable_msix_range(adapter->pdev, adapter->msix_entries, |
261 | 1, nvec); | 298 | 1, nvec); |
262 | } | 299 | } |
263 | 300 | ||
264 | Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive, | 301 | Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive, |
@@ -269,8 +306,8 @@ In this case the function could look like this: | |||
269 | 306 | ||
270 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) | 307 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) |
271 | { | 308 | { |
272 | return pci_enable_msi_range(adapter->pdev, adapter->msix_entries, | 309 | return pci_enable_msix_range(adapter->pdev, adapter->msix_entries, |
273 | FOO_DRIVER_MINIMUM_NVEC, nvec); | 310 | FOO_DRIVER_MINIMUM_NVEC, nvec); |
274 | } | 311 | } |
275 | 312 | ||
276 | 4.3.1.2 Exact number of MSI-X interrupts | 313 | 4.3.1.2 Exact number of MSI-X interrupts |
@@ -282,10 +319,15 @@ parameters: | |||
282 | 319 | ||
283 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) | 320 | static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) |
284 | { | 321 | { |
285 | return pci_enable_msi_range(adapter->pdev, adapter->msix_entries, | 322 | return pci_enable_msix_range(adapter->pdev, adapter->msix_entries, |
286 | nvec, nvec); | 323 | nvec, nvec); |
287 | } | 324 | } |
288 | 325 | ||
326 | Note, unlike pci_enable_msix_exact() function, which could be also used to | ||
327 | enable a particular number of MSI-X interrupts, pci_enable_msix_range() | ||
328 | returns either a negative errno or 'nvec' (not negative errno or 0 - as | ||
329 | pci_enable_msix_exact() does). | ||
330 | |||
289 | 4.3.1.3 Specific requirements to the number of MSI-X interrupts | 331 | 4.3.1.3 Specific requirements to the number of MSI-X interrupts |
290 | 332 | ||
291 | As noted above, there could be devices that can not operate with just any | 333 | As noted above, there could be devices that can not operate with just any |
@@ -332,7 +374,64 @@ Note how pci_enable_msix_range() return value is analized for a fallback - | |||
332 | any error code other than -ENOSPC indicates a fatal error and should not | 374 | any error code other than -ENOSPC indicates a fatal error and should not |
333 | be retried. | 375 | be retried. |
334 | 376 | ||
335 | 4.3.2 pci_disable_msix | 377 | 4.3.2 pci_enable_msix_exact |
378 | |||
379 | int pci_enable_msix_exact(struct pci_dev *dev, | ||
380 | struct msix_entry *entries, int nvec) | ||
381 | |||
382 | This variation on pci_enable_msix_range() call allows a device driver to | ||
383 | request exactly 'nvec' MSI-Xs. | ||
384 | |||
385 | If this function returns a negative number, it indicates an error and | ||
386 | the driver should not attempt to allocate any more MSI-X interrupts for | ||
387 | this device. | ||
388 | |||
389 | By contrast with pci_enable_msix_range() function, pci_enable_msix_exact() | ||
390 | returns zero in case of success, which indicates MSI-X interrupts have been | ||
391 | successfully allocated. | ||
392 | |||
393 | Another version of a routine that enables MSI-X mode for a device with | ||
394 | specific requirements described in chapter 4.3.1.3 might look like this: | ||
395 | |||
396 | /* | ||
397 | * Assume 'minvec' and 'maxvec' are non-zero | ||
398 | */ | ||
399 | static int foo_driver_enable_msix(struct foo_adapter *adapter, | ||
400 | int minvec, int maxvec) | ||
401 | { | ||
402 | int rc; | ||
403 | |||
404 | minvec = roundup_pow_of_two(minvec); | ||
405 | maxvec = rounddown_pow_of_two(maxvec); | ||
406 | |||
407 | if (minvec > maxvec) | ||
408 | return -ERANGE; | ||
409 | |||
410 | retry: | ||
411 | rc = pci_enable_msix_exact(adapter->pdev, | ||
412 | adapter->msix_entries, maxvec); | ||
413 | |||
414 | /* | ||
415 | * -ENOSPC is the only error code allowed to be analyzed | ||
416 | */ | ||
417 | if (rc == -ENOSPC) { | ||
418 | if (maxvec == 1) | ||
419 | return -ENOSPC; | ||
420 | |||
421 | maxvec /= 2; | ||
422 | |||
423 | if (minvec > maxvec) | ||
424 | return -ENOSPC; | ||
425 | |||
426 | goto retry; | ||
427 | } else if (rc < 0) { | ||
428 | return rc; | ||
429 | } | ||
430 | |||
431 | return maxvec; | ||
432 | } | ||
433 | |||
434 | 4.3.3 pci_disable_msix | ||
336 | 435 | ||
337 | void pci_disable_msix(struct pci_dev *dev) | 436 | void pci_disable_msix(struct pci_dev *dev) |
338 | 437 | ||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index dc2756fb6f33..023710905289 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -1151,13 +1151,13 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) | |||
1151 | static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, | 1151 | static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, |
1152 | struct ahci_host_priv *hpriv) | 1152 | struct ahci_host_priv *hpriv) |
1153 | { | 1153 | { |
1154 | int rc, nvec; | 1154 | int nvec; |
1155 | 1155 | ||
1156 | if (hpriv->flags & AHCI_HFLAG_NO_MSI) | 1156 | if (hpriv->flags & AHCI_HFLAG_NO_MSI) |
1157 | goto intx; | 1157 | goto intx; |
1158 | 1158 | ||
1159 | rc = pci_msi_vec_count(pdev); | 1159 | nvec = pci_msi_vec_count(pdev); |
1160 | if (rc < 0) | 1160 | if (nvec < 0) |
1161 | goto intx; | 1161 | goto intx; |
1162 | 1162 | ||
1163 | /* | 1163 | /* |
@@ -1165,19 +1165,19 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, | |||
1165 | * Message mode could be enforced. In this case assume that advantage | 1165 | * Message mode could be enforced. In this case assume that advantage |
1166 | * of multipe MSIs is negated and use single MSI mode instead. | 1166 | * of multipe MSIs is negated and use single MSI mode instead. |
1167 | */ | 1167 | */ |
1168 | if (rc < n_ports) | 1168 | if (nvec < n_ports) |
1169 | goto single_msi; | 1169 | goto single_msi; |
1170 | 1170 | ||
1171 | nvec = rc; | 1171 | nvec = pci_enable_msi_range(pdev, nvec, nvec); |
1172 | rc = pci_enable_msi_block(pdev, nvec); | 1172 | if (nvec == -ENOSPC) |
1173 | if (rc) | 1173 | goto single_msi; |
1174 | else if (nvec < 0) | ||
1174 | goto intx; | 1175 | goto intx; |
1175 | 1176 | ||
1176 | return nvec; | 1177 | return nvec; |
1177 | 1178 | ||
1178 | single_msi: | 1179 | single_msi: |
1179 | rc = pci_enable_msi(pdev); | 1180 | if (pci_enable_msi(pdev)) |
1180 | if (rc) | ||
1181 | goto intx; | 1181 | goto intx; |
1182 | return 1; | 1182 | return 1; |
1183 | 1183 | ||
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 7a0fec6ce571..955ab7990c5b 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -545,9 +545,15 @@ static int populate_msi_sysfs(struct pci_dev *pdev) | |||
545 | return -ENOMEM; | 545 | return -ENOMEM; |
546 | list_for_each_entry(entry, &pdev->msi_list, list) { | 546 | list_for_each_entry(entry, &pdev->msi_list, list) { |
547 | char *name = kmalloc(20, GFP_KERNEL); | 547 | char *name = kmalloc(20, GFP_KERNEL); |
548 | if (!name) | ||
549 | goto error_attrs; | ||
550 | |||
548 | msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL); | 551 | msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL); |
549 | if (!msi_dev_attr) | 552 | if (!msi_dev_attr) { |
553 | kfree(name); | ||
550 | goto error_attrs; | 554 | goto error_attrs; |
555 | } | ||
556 | |||
551 | sprintf(name, "%d", entry->irq); | 557 | sprintf(name, "%d", entry->irq); |
552 | sysfs_attr_init(&msi_dev_attr->attr); | 558 | sysfs_attr_init(&msi_dev_attr->attr); |
553 | msi_dev_attr->attr.name = name; | 559 | msi_dev_attr->attr.name = name; |
@@ -589,6 +595,7 @@ error_attrs: | |||
589 | ++count; | 595 | ++count; |
590 | msi_attr = msi_attrs[count]; | 596 | msi_attr = msi_attrs[count]; |
591 | } | 597 | } |
598 | kfree(msi_attrs); | ||
592 | return ret; | 599 | return ret; |
593 | } | 600 | } |
594 | 601 | ||
@@ -959,7 +966,6 @@ EXPORT_SYMBOL(pci_disable_msi); | |||
959 | /** | 966 | /** |
960 | * pci_msix_vec_count - return the number of device's MSI-X table entries | 967 | * pci_msix_vec_count - return the number of device's MSI-X table entries |
961 | * @dev: pointer to the pci_dev data structure of MSI-X device function | 968 | * @dev: pointer to the pci_dev data structure of MSI-X device function |
962 | |||
963 | * This function returns the number of device's MSI-X table entries and | 969 | * This function returns the number of device's MSI-X table entries and |
964 | * therefore the number of MSI-X vectors device is capable of sending. | 970 | * therefore the number of MSI-X vectors device is capable of sending. |
965 | * It returns a negative errno if the device is not capable of sending MSI-X | 971 | * It returns a negative errno if the device is not capable of sending MSI-X |
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c index 210357691dc0..9dd49c9839ac 100644 --- a/drivers/vfio/pci/vfio_pci_intrs.c +++ b/drivers/vfio/pci/vfio_pci_intrs.c | |||
@@ -482,15 +482,19 @@ static int vfio_msi_enable(struct vfio_pci_device *vdev, int nvec, bool msix) | |||
482 | for (i = 0; i < nvec; i++) | 482 | for (i = 0; i < nvec; i++) |
483 | vdev->msix[i].entry = i; | 483 | vdev->msix[i].entry = i; |
484 | 484 | ||
485 | ret = pci_enable_msix(pdev, vdev->msix, nvec); | 485 | ret = pci_enable_msix_range(pdev, vdev->msix, 1, nvec); |
486 | if (ret) { | 486 | if (ret < nvec) { |
487 | if (ret > 0) | ||
488 | pci_disable_msix(pdev); | ||
487 | kfree(vdev->msix); | 489 | kfree(vdev->msix); |
488 | kfree(vdev->ctx); | 490 | kfree(vdev->ctx); |
489 | return ret; | 491 | return ret; |
490 | } | 492 | } |
491 | } else { | 493 | } else { |
492 | ret = pci_enable_msi_block(pdev, nvec); | 494 | ret = pci_enable_msi_range(pdev, 1, nvec); |
493 | if (ret) { | 495 | if (ret < nvec) { |
496 | if (ret > 0) | ||
497 | pci_disable_msi(pdev); | ||
494 | kfree(vdev->ctx); | 498 | kfree(vdev->ctx); |
495 | return ret; | 499 | return ret; |
496 | } | 500 | } |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 60ab8d782f8c..1e26fc602adc 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -1171,8 +1171,23 @@ void msi_remove_pci_irq_vectors(struct pci_dev *dev); | |||
1171 | void pci_restore_msi_state(struct pci_dev *dev); | 1171 | void pci_restore_msi_state(struct pci_dev *dev); |
1172 | int pci_msi_enabled(void); | 1172 | int pci_msi_enabled(void); |
1173 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); | 1173 | int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); |
1174 | static inline int pci_enable_msi_exact(struct pci_dev *dev, int nvec) | ||
1175 | { | ||
1176 | int rc = pci_enable_msi_range(dev, nvec, nvec); | ||
1177 | if (rc < 0) | ||
1178 | return rc; | ||
1179 | return 0; | ||
1180 | } | ||
1174 | int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, | 1181 | int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, |
1175 | int minvec, int maxvec); | 1182 | int minvec, int maxvec); |
1183 | static inline int pci_enable_msix_exact(struct pci_dev *dev, | ||
1184 | struct msix_entry *entries, int nvec) | ||
1185 | { | ||
1186 | int rc = pci_enable_msix_range(dev, entries, nvec, nvec); | ||
1187 | if (rc < 0) | ||
1188 | return rc; | ||
1189 | return 0; | ||
1190 | } | ||
1176 | #else | 1191 | #else |
1177 | static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; } | 1192 | static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; } |
1178 | static inline int pci_enable_msi_block(struct pci_dev *dev, int nvec) | 1193 | static inline int pci_enable_msi_block(struct pci_dev *dev, int nvec) |
@@ -1191,9 +1206,14 @@ static inline int pci_msi_enabled(void) { return 0; } | |||
1191 | static inline int pci_enable_msi_range(struct pci_dev *dev, int minvec, | 1206 | static inline int pci_enable_msi_range(struct pci_dev *dev, int minvec, |
1192 | int maxvec) | 1207 | int maxvec) |
1193 | { return -ENOSYS; } | 1208 | { return -ENOSYS; } |
1209 | static inline int pci_enable_msi_exact(struct pci_dev *dev, int nvec) | ||
1210 | { return -ENOSYS; } | ||
1194 | static inline int pci_enable_msix_range(struct pci_dev *dev, | 1211 | static inline int pci_enable_msix_range(struct pci_dev *dev, |
1195 | struct msix_entry *entries, int minvec, int maxvec) | 1212 | struct msix_entry *entries, int minvec, int maxvec) |
1196 | { return -ENOSYS; } | 1213 | { return -ENOSYS; } |
1214 | static inline int pci_enable_msix_exact(struct pci_dev *dev, | ||
1215 | struct msix_entry *entries, int nvec) | ||
1216 | { return -ENOSYS; } | ||
1197 | #endif | 1217 | #endif |
1198 | 1218 | ||
1199 | #ifdef CONFIG_PCIEPORTBUS | 1219 | #ifdef CONFIG_PCIEPORTBUS |