diff options
author | Changbin Du <changbin.du@gmail.com> | 2019-05-14 10:47:27 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2019-05-30 18:54:32 -0400 |
commit | 3b9bae029b60ee0fa6d6205e0debfad4482434a7 (patch) | |
tree | 298cc6bf3eada4b29ec7cb3504ec48fe1a9aa60d /Documentation/PCI | |
parent | 4d2c729c62328d6841111d98396374476367ae83 (diff) |
Documentation: PCI: convert MSI-HOWTO.txt to reST
Convert plain text documentation to reStructuredText format and add it to
Sphinx TOC tree. No essential content change.
Signed-off-by: Changbin Du <changbin.du@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'Documentation/PCI')
-rw-r--r-- | Documentation/PCI/index.rst | 1 | ||||
-rw-r--r-- | Documentation/PCI/msi-howto.rst (renamed from Documentation/PCI/MSI-HOWTO.txt) | 85 |
2 files changed, 52 insertions, 34 deletions
diff --git a/Documentation/PCI/index.rst b/Documentation/PCI/index.rst index 0d9390298c4a..458354daac47 100644 --- a/Documentation/PCI/index.rst +++ b/Documentation/PCI/index.rst | |||
@@ -11,3 +11,4 @@ Linux PCI Bus Subsystem | |||
11 | pci | 11 | pci |
12 | picebus-howto | 12 | picebus-howto |
13 | pci-iov-howto | 13 | pci-iov-howto |
14 | msi-howto | ||
diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/msi-howto.rst index 618e13d5e276..994cbb660ade 100644 --- a/Documentation/PCI/MSI-HOWTO.txt +++ b/Documentation/PCI/msi-howto.rst | |||
@@ -1,13 +1,16 @@ | |||
1 | The MSI Driver Guide HOWTO | 1 | .. SPDX-License-Identifier: GPL-2.0 |
2 | Tom L Nguyen tom.l.nguyen@intel.com | 2 | .. include:: <isonum.txt> |
3 | 10/03/2003 | ||
4 | Revised Feb 12, 2004 by Martine Silbermann | ||
5 | email: Martine.Silbermann@hp.com | ||
6 | Revised Jun 25, 2004 by Tom L Nguyen | ||
7 | Revised Jul 9, 2008 by Matthew Wilcox <willy@linux.intel.com> | ||
8 | Copyright 2003, 2008 Intel Corporation | ||
9 | 3 | ||
10 | 1. About this guide | 4 | ========================== |
5 | The MSI Driver Guide HOWTO | ||
6 | ========================== | ||
7 | |||
8 | :Authors: Tom L Nguyen; Martine Silbermann; Matthew Wilcox | ||
9 | |||
10 | :Copyright: 2003, 2008 Intel Corporation | ||
11 | |||
12 | About this guide | ||
13 | ================ | ||
11 | 14 | ||
12 | This guide describes the basics of Message Signaled Interrupts (MSIs), | 15 | This guide describes the basics of Message Signaled Interrupts (MSIs), |
13 | the advantages of using MSI over traditional interrupt mechanisms, how | 16 | the advantages of using MSI over traditional interrupt mechanisms, how |
@@ -15,7 +18,8 @@ to change your driver to use MSI or MSI-X and some basic diagnostics to | |||
15 | try if a device doesn't support MSIs. | 18 | try if a device doesn't support MSIs. |
16 | 19 | ||
17 | 20 | ||
18 | 2. What are MSIs? | 21 | What are MSIs? |
22 | ============== | ||
19 | 23 | ||
20 | A Message Signaled Interrupt is a write from the device to a special | 24 | A Message Signaled Interrupt is a write from the device to a special |
21 | address which causes an interrupt to be received by the CPU. | 25 | address which causes an interrupt to be received by the CPU. |
@@ -29,7 +33,8 @@ Devices may support both MSI and MSI-X, but only one can be enabled at | |||
29 | a time. | 33 | a time. |
30 | 34 | ||
31 | 35 | ||
32 | 3. Why use MSIs? | 36 | Why use MSIs? |
37 | ============= | ||
33 | 38 | ||
34 | There are three reasons why using MSIs can give an advantage over | 39 | There are three reasons why using MSIs can give an advantage over |
35 | traditional pin-based interrupts. | 40 | traditional pin-based interrupts. |
@@ -61,14 +66,16 @@ Other possible designs include giving one interrupt to each packet queue | |||
61 | in a network card or each port in a storage controller. | 66 | in a network card or each port in a storage controller. |
62 | 67 | ||
63 | 68 | ||
64 | 4. How to use MSIs | 69 | How to use MSIs |
70 | =============== | ||
65 | 71 | ||
66 | PCI devices are initialised to use pin-based interrupts. The device | 72 | PCI devices are initialised to use pin-based interrupts. The device |
67 | driver has to set up the device to use MSI or MSI-X. Not all machines | 73 | driver has to set up the device to use MSI or MSI-X. Not all machines |
68 | support MSIs correctly, and for those machines, the APIs described below | 74 | support MSIs correctly, and for those machines, the APIs described below |
69 | will simply fail and the device will continue to use pin-based interrupts. | 75 | will simply fail and the device will continue to use pin-based interrupts. |
70 | 76 | ||
71 | 4.1 Include kernel support for MSIs | 77 | Include kernel support for MSIs |
78 | ------------------------------- | ||
72 | 79 | ||
73 | To support MSI or MSI-X, the kernel must be built with the CONFIG_PCI_MSI | 80 | To support MSI or MSI-X, the kernel must be built with the CONFIG_PCI_MSI |
74 | option enabled. This option is only available on some architectures, | 81 | option enabled. This option is only available on some architectures, |
@@ -76,14 +83,15 @@ and it may depend on some other options also being set. For example, | |||
76 | on x86, you must also enable X86_UP_APIC or SMP in order to see the | 83 | on x86, you must also enable X86_UP_APIC or SMP in order to see the |
77 | CONFIG_PCI_MSI option. | 84 | CONFIG_PCI_MSI option. |
78 | 85 | ||
79 | 4.2 Using MSI | 86 | Using MSI |
87 | --------- | ||
80 | 88 | ||
81 | Most of the hard work is done for the driver in the PCI layer. The driver | 89 | Most of the hard work is done for the driver in the PCI layer. The driver |
82 | simply has to request that the PCI layer set up the MSI capability for this | 90 | simply has to request that the PCI layer set up the MSI capability for this |
83 | device. | 91 | device. |
84 | 92 | ||
85 | To automatically use MSI or MSI-X interrupt vectors, use the following | 93 | To automatically use MSI or MSI-X interrupt vectors, use the following |
86 | function: | 94 | function:: |
87 | 95 | ||
88 | int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, | 96 | int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, |
89 | unsigned int max_vecs, unsigned int flags); | 97 | unsigned int max_vecs, unsigned int flags); |
@@ -101,12 +109,12 @@ any possible kind of interrupt. If the PCI_IRQ_AFFINITY flag is set, | |||
101 | pci_alloc_irq_vectors() will spread the interrupts around the available CPUs. | 109 | pci_alloc_irq_vectors() will spread the interrupts around the available CPUs. |
102 | 110 | ||
103 | To get the Linux IRQ numbers passed to request_irq() and free_irq() and the | 111 | To get the Linux IRQ numbers passed to request_irq() and free_irq() and the |
104 | vectors, use the following function: | 112 | vectors, use the following function:: |
105 | 113 | ||
106 | int pci_irq_vector(struct pci_dev *dev, unsigned int nr); | 114 | int pci_irq_vector(struct pci_dev *dev, unsigned int nr); |
107 | 115 | ||
108 | Any allocated resources should be freed before removing the device using | 116 | Any allocated resources should be freed before removing the device using |
109 | the following function: | 117 | the following function:: |
110 | 118 | ||
111 | void pci_free_irq_vectors(struct pci_dev *dev); | 119 | void pci_free_irq_vectors(struct pci_dev *dev); |
112 | 120 | ||
@@ -126,7 +134,7 @@ The typical usage of MSI or MSI-X interrupts is to allocate as many vectors | |||
126 | as possible, likely up to the limit supported by the device. If nvec is | 134 | as possible, likely up to the limit supported by the device. If nvec is |
127 | larger than the number supported by the device it will automatically be | 135 | larger than the number supported by the device it will automatically be |
128 | capped to the supported limit, so there is no need to query the number of | 136 | capped to the supported limit, so there is no need to query the number of |
129 | vectors supported beforehand: | 137 | vectors supported beforehand:: |
130 | 138 | ||
131 | nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_ALL_TYPES) | 139 | nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_ALL_TYPES) |
132 | if (nvec < 0) | 140 | if (nvec < 0) |
@@ -135,7 +143,7 @@ vectors supported beforehand: | |||
135 | If a driver is unable or unwilling to deal with a variable number of MSI | 143 | If a driver is unable or unwilling to deal with a variable number of MSI |
136 | interrupts it can request a particular number of interrupts by passing that | 144 | interrupts it can request a particular number of interrupts by passing that |
137 | number to pci_alloc_irq_vectors() function as both 'min_vecs' and | 145 | number to pci_alloc_irq_vectors() function as both 'min_vecs' and |
138 | 'max_vecs' parameters: | 146 | 'max_vecs' parameters:: |
139 | 147 | ||
140 | ret = pci_alloc_irq_vectors(pdev, nvec, nvec, PCI_IRQ_ALL_TYPES); | 148 | ret = pci_alloc_irq_vectors(pdev, nvec, nvec, PCI_IRQ_ALL_TYPES); |
141 | if (ret < 0) | 149 | if (ret < 0) |
@@ -143,23 +151,24 @@ number to pci_alloc_irq_vectors() function as both 'min_vecs' and | |||
143 | 151 | ||
144 | The most notorious example of the request type described above is enabling | 152 | The most notorious example of the request type described above is enabling |
145 | the single MSI mode for a device. It could be done by passing two 1s as | 153 | the single MSI mode for a device. It could be done by passing two 1s as |
146 | 'min_vecs' and 'max_vecs': | 154 | 'min_vecs' and 'max_vecs':: |
147 | 155 | ||
148 | ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); | 156 | ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); |
149 | if (ret < 0) | 157 | if (ret < 0) |
150 | goto out_err; | 158 | goto out_err; |
151 | 159 | ||
152 | Some devices might not support using legacy line interrupts, in which case | 160 | Some devices might not support using legacy line interrupts, in which case |
153 | the driver can specify that only MSI or MSI-X is acceptable: | 161 | the driver can specify that only MSI or MSI-X is acceptable:: |
154 | 162 | ||
155 | nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_MSI | PCI_IRQ_MSIX); | 163 | nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_MSI | PCI_IRQ_MSIX); |
156 | if (nvec < 0) | 164 | if (nvec < 0) |
157 | goto out_err; | 165 | goto out_err; |
158 | 166 | ||
159 | 4.3 Legacy APIs | 167 | Legacy APIs |
168 | ----------- | ||
160 | 169 | ||
161 | The following old APIs to enable and disable MSI or MSI-X interrupts should | 170 | The following old APIs to enable and disable MSI or MSI-X interrupts should |
162 | not be used in new code: | 171 | not be used in new code:: |
163 | 172 | ||
164 | pci_enable_msi() /* deprecated */ | 173 | pci_enable_msi() /* deprecated */ |
165 | pci_disable_msi() /* deprecated */ | 174 | pci_disable_msi() /* deprecated */ |
@@ -174,9 +183,11 @@ number of vectors. If you have a legitimate special use case for the count | |||
174 | of vectors we might have to revisit that decision and add a | 183 | of vectors we might have to revisit that decision and add a |
175 | pci_nr_irq_vectors() helper that handles MSI and MSI-X transparently. | 184 | pci_nr_irq_vectors() helper that handles MSI and MSI-X transparently. |
176 | 185 | ||
177 | 4.4 Considerations when using MSIs | 186 | Considerations when using MSIs |
187 | ------------------------------ | ||
178 | 188 | ||
179 | 4.4.1 Spinlocks | 189 | Spinlocks |
190 | ~~~~~~~~~ | ||
180 | 191 | ||
181 | Most device drivers have a per-device spinlock which is taken in the | 192 | Most device drivers have a per-device spinlock which is taken in the |
182 | interrupt handler. With pin-based interrupts or a single MSI, it is not | 193 | interrupt handler. With pin-based interrupts or a single MSI, it is not |
@@ -188,7 +199,8 @@ acquire the spinlock. Such deadlocks can be avoided by using | |||
188 | spin_lock_irqsave() or spin_lock_irq() which disable local interrupts | 199 | spin_lock_irqsave() or spin_lock_irq() which disable local interrupts |
189 | and acquire the lock (see Documentation/kernel-hacking/locking.rst). | 200 | and acquire the lock (see Documentation/kernel-hacking/locking.rst). |
190 | 201 | ||
191 | 4.5 How to tell whether MSI/MSI-X is enabled on a device | 202 | How to tell whether MSI/MSI-X is enabled on a device |
203 | ---------------------------------------------------- | ||
192 | 204 | ||
193 | Using 'lspci -v' (as root) may show some devices with "MSI", "Message | 205 | Using 'lspci -v' (as root) may show some devices with "MSI", "Message |
194 | Signalled Interrupts" or "MSI-X" capabilities. Each of these capabilities | 206 | Signalled Interrupts" or "MSI-X" capabilities. Each of these capabilities |
@@ -196,7 +208,8 @@ has an 'Enable' flag which is followed with either "+" (enabled) | |||
196 | or "-" (disabled). | 208 | or "-" (disabled). |
197 | 209 | ||
198 | 210 | ||
199 | 5. MSI quirks | 211 | MSI quirks |
212 | ========== | ||
200 | 213 | ||
201 | Several PCI chipsets or devices are known not to support MSIs. | 214 | Several PCI chipsets or devices are known not to support MSIs. |
202 | The PCI stack provides three ways to disable MSIs: | 215 | The PCI stack provides three ways to disable MSIs: |
@@ -205,7 +218,8 @@ The PCI stack provides three ways to disable MSIs: | |||
205 | 2. on all devices behind a specific bridge | 218 | 2. on all devices behind a specific bridge |
206 | 3. on a single device | 219 | 3. on a single device |
207 | 220 | ||
208 | 5.1. Disabling MSIs globally | 221 | Disabling MSIs globally |
222 | ----------------------- | ||
209 | 223 | ||
210 | Some host chipsets simply don't support MSIs properly. If we're | 224 | Some host chipsets simply don't support MSIs properly. If we're |
211 | lucky, the manufacturer knows this and has indicated it in the ACPI | 225 | lucky, the manufacturer knows this and has indicated it in the ACPI |
@@ -219,7 +233,8 @@ on the kernel command line to disable MSIs on all devices. It would be | |||
219 | in your best interests to report the problem to linux-pci@vger.kernel.org | 233 | in your best interests to report the problem to linux-pci@vger.kernel.org |
220 | including a full 'lspci -v' so we can add the quirks to the kernel. | 234 | including a full 'lspci -v' so we can add the quirks to the kernel. |
221 | 235 | ||
222 | 5.2. Disabling MSIs below a bridge | 236 | Disabling MSIs below a bridge |
237 | ----------------------------- | ||
223 | 238 | ||
224 | Some PCI bridges are not able to route MSIs between busses properly. | 239 | Some PCI bridges are not able to route MSIs between busses properly. |
225 | In this case, MSIs must be disabled on all devices behind the bridge. | 240 | In this case, MSIs must be disabled on all devices behind the bridge. |
@@ -230,7 +245,7 @@ as the nVidia nForce and Serverworks HT2000). As with host chipsets, | |||
230 | Linux mostly knows about them and automatically enables MSIs if it can. | 245 | Linux mostly knows about them and automatically enables MSIs if it can. |
231 | If you have a bridge unknown to Linux, you can enable | 246 | If you have a bridge unknown to Linux, you can enable |
232 | MSIs in configuration space using whatever method you know works, then | 247 | MSIs in configuration space using whatever method you know works, then |
233 | enable MSIs on that bridge by doing: | 248 | enable MSIs on that bridge by doing:: |
234 | 249 | ||
235 | echo 1 > /sys/bus/pci/devices/$bridge/msi_bus | 250 | echo 1 > /sys/bus/pci/devices/$bridge/msi_bus |
236 | 251 | ||
@@ -244,7 +259,8 @@ below this bridge. | |||
244 | Again, please notify linux-pci@vger.kernel.org of any bridges that need | 259 | Again, please notify linux-pci@vger.kernel.org of any bridges that need |
245 | special handling. | 260 | special handling. |
246 | 261 | ||
247 | 5.3. Disabling MSIs on a single device | 262 | Disabling MSIs on a single device |
263 | --------------------------------- | ||
248 | 264 | ||
249 | Some devices are known to have faulty MSI implementations. Usually this | 265 | Some devices are known to have faulty MSI implementations. Usually this |
250 | is handled in the individual device driver, but occasionally it's necessary | 266 | is handled in the individual device driver, but occasionally it's necessary |
@@ -252,7 +268,8 @@ to handle this with a quirk. Some drivers have an option to disable use | |||
252 | of MSI. While this is a convenient workaround for the driver author, | 268 | of MSI. While this is a convenient workaround for the driver author, |
253 | it is not good practice, and should not be emulated. | 269 | it is not good practice, and should not be emulated. |
254 | 270 | ||
255 | 5.4. Finding why MSIs are disabled on a device | 271 | Finding why MSIs are disabled on a device |
272 | ----------------------------------------- | ||
256 | 273 | ||
257 | From the above three sections, you can see that there are many reasons | 274 | From the above three sections, you can see that there are many reasons |
258 | why MSIs may not be enabled for a given device. Your first step should | 275 | why MSIs may not be enabled for a given device. Your first step should |
@@ -260,8 +277,8 @@ be to examine your dmesg carefully to determine whether MSIs are enabled | |||
260 | for your machine. You should also check your .config to be sure you | 277 | for your machine. You should also check your .config to be sure you |
261 | have enabled CONFIG_PCI_MSI. | 278 | have enabled CONFIG_PCI_MSI. |
262 | 279 | ||
263 | Then, 'lspci -t' gives the list of bridges above a device. Reading | 280 | Then, 'lspci -t' gives the list of bridges above a device. Reading |
264 | /sys/bus/pci/devices/*/msi_bus will tell you whether MSIs are enabled (1) | 281 | `/sys/bus/pci/devices/*/msi_bus` will tell you whether MSIs are enabled (1) |
265 | or disabled (0). If 0 is found in any of the msi_bus files belonging | 282 | or disabled (0). If 0 is found in any of the msi_bus files belonging |
266 | to bridges between the PCI root and the device, MSIs are disabled. | 283 | to bridges between the PCI root and the device, MSIs are disabled. |
267 | 284 | ||