Skip to content

Commit 109c9ff

Browse files
committed
s390/pci: Allow allocation of more than 1 MSI interrupt
jira LE-2349 Rebuild_History Non-Buildable kernel-4.18.0-553.40.1.el8_10 commit-author Gerd Bayer <gbayer@linux.ibm.com> commit ab42fcb Empty-Commit: Cherry-Pick Conflicts during history rebuild. Will be included in final tarball splat. Ref for failed cherry-pick at: ciq/ciq_backports/kernel-4.18.0-553.40.1.el8_10/ab42fcb5.failed On a PCI adapter that provides up to 8 MSI interrupt sources the s390 implementation of PCI interrupts rejected to accommodate them, although the underlying hardware is able to support that. For MSI-X it is sufficient to allocate a single irq_desc per msi_desc, but for MSI multiple irq descriptors are attached to and controlled by a single msi descriptor. Add the appropriate loops to maintain multiple irq descriptors and tie/untie them to/from the appropriate AIBV bit, if a device driver allocates more than 1 MSI interrupt. Common PCI code passes on requests to allocate a number of interrupt vectors based on the device drivers' demand and the PCI functions' capabilities. However, the root-complex of s390 systems support just a limited number of interrupt vectors per PCI function. Produce a kernel log message to inform about any architecture-specific capping that might be done. With this change, we had a PCI adapter successfully raising interrupts to its device driver via all 8 sources. Fixes: a384c89 ("s390/PCI: Fix single MSI only check") Signed-off-by: Gerd Bayer <gbayer@linux.ibm.com> Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> (cherry picked from commit ab42fcb) Signed-off-by: Jonathan Maple <jmaple@ciq.com> # Conflicts: # arch/s390/pci/pci_irq.c
1 parent bae7ae0 commit 109c9ff

File tree

1 file changed

+172
-0
lines changed

1 file changed

+172
-0
lines changed
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
s390/pci: Allow allocation of more than 1 MSI interrupt
2+
3+
jira LE-2349
4+
Rebuild_History Non-Buildable kernel-4.18.0-553.40.1.el8_10
5+
commit-author Gerd Bayer <gbayer@linux.ibm.com>
6+
commit ab42fcb511fd9d241bbab7cc3ca04e34e9fc0666
7+
Empty-Commit: Cherry-Pick Conflicts during history rebuild.
8+
Will be included in final tarball splat. Ref for failed cherry-pick at:
9+
ciq/ciq_backports/kernel-4.18.0-553.40.1.el8_10/ab42fcb5.failed
10+
11+
On a PCI adapter that provides up to 8 MSI interrupt sources the s390
12+
implementation of PCI interrupts rejected to accommodate them, although
13+
the underlying hardware is able to support that.
14+
15+
For MSI-X it is sufficient to allocate a single irq_desc per msi_desc,
16+
but for MSI multiple irq descriptors are attached to and controlled by
17+
a single msi descriptor. Add the appropriate loops to maintain multiple
18+
irq descriptors and tie/untie them to/from the appropriate AIBV bit, if
19+
a device driver allocates more than 1 MSI interrupt.
20+
21+
Common PCI code passes on requests to allocate a number of interrupt
22+
vectors based on the device drivers' demand and the PCI functions'
23+
capabilities. However, the root-complex of s390 systems support just a
24+
limited number of interrupt vectors per PCI function.
25+
Produce a kernel log message to inform about any architecture-specific
26+
capping that might be done.
27+
28+
With this change, we had a PCI adapter successfully raising
29+
interrupts to its device driver via all 8 sources.
30+
31+
Fixes: a384c8924a8b ("s390/PCI: Fix single MSI only check")
32+
Signed-off-by: Gerd Bayer <gbayer@linux.ibm.com>
33+
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
34+
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
35+
(cherry picked from commit ab42fcb511fd9d241bbab7cc3ca04e34e9fc0666)
36+
Signed-off-by: Jonathan Maple <jmaple@ciq.com>
37+
38+
# Conflicts:
39+
# arch/s390/pci/pci_irq.c
40+
diff --cc arch/s390/pci/pci_irq.c
41+
index 192f3b104ae4,84482a921332..000000000000
42+
--- a/arch/s390/pci/pci_irq.c
43+
+++ b/arch/s390/pci/pci_irq.c
44+
@@@ -302,34 -289,81 +302,83 @@@ int arch_setup_msi_irqs(struct pci_dev
45+
return -ENOMEM;
46+
47+
/* Wire up shortcut pointer */
48+
- zpci_ibv[*bit] = zdev->aibv;
49+
+ zpci_ibv[bit] = zdev->aibv;
50+
/* Each function has its own interrupt vector */
51+
- *bit = 0;
52+
+ bit = 0;
53+
}
54+
++<<<<<<< HEAD
55+
++=======
56+
+ return 0;
57+
+ }
58+
+
59+
+ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
60+
+ {
61+
+ unsigned int hwirq, msi_vecs, irqs_per_msi, i, cpu;
62+
+ struct zpci_dev *zdev = to_zpci(pdev);
63+
+ struct msi_desc *msi;
64+
+ struct msi_msg msg;
65+
+ unsigned long bit;
66+
+ int cpu_addr;
67+
+ int rc, irq;
68+
+
69+
+ zdev->aisb = -1UL;
70+
+ zdev->msi_first_bit = -1U;
71+
+
72+
+ msi_vecs = min_t(unsigned int, nvec, zdev->max_msi);
73+
+ if (msi_vecs < nvec) {
74+
+ pr_info("%s requested %d irqs, allocate system limit of %d",
75+
+ pci_name(pdev), nvec, zdev->max_msi);
76+
+ }
77+
78+
- /* Request MSI interrupts */
79+
+ rc = __alloc_airq(zdev, msi_vecs, &bit);
80+
+ if (rc < 0)
81+
+ return rc;
82+
++>>>>>>> ab42fcb511fd (s390/pci: Allow allocation of more than 1 MSI interrupt)
83+
+
84+
+ /*
85+
+ * Request MSI interrupts:
86+
+ * When using MSI, nvec_used interrupt sources and their irq
87+
+ * descriptors are controlled through one msi descriptor.
88+
+ * Thus the outer loop over msi descriptors shall run only once,
89+
+ * while two inner loops iterate over the interrupt vectors.
90+
+ * When using MSI-X, each interrupt vector/irq descriptor
91+
+ * is bound to exactly one msi descriptor (nvec_used is one).
92+
+ * So the inner loops are executed once, while the outer iterates
93+
+ * over the MSI-X descriptors.
94+
+ */
95+
hwirq = bit;
96+
++<<<<<<< HEAD
97+
+ for_each_pci_msi_entry(msi, pdev) {
98+
+ rc = -EIO;
99+
++=======
100+
+ msi_for_each_desc(msi, &pdev->dev, MSI_DESC_NOTASSOCIATED) {
101+
++>>>>>>> ab42fcb511fd (s390/pci: Allow allocation of more than 1 MSI interrupt)
102+
if (hwirq - bit >= msi_vecs)
103+
break;
104+
- irq = __irq_alloc_descs(-1, 0, 1, 0, THIS_MODULE,
105+
- (irq_delivery == DIRECTED) ?
106+
- msi->affinity : NULL);
107+
+ irqs_per_msi = min_t(unsigned int, msi_vecs, msi->nvec_used);
108+
+ irq = __irq_alloc_descs(-1, 0, irqs_per_msi, 0, THIS_MODULE,
109+
+ (irq_delivery == DIRECTED) ?
110+
+ msi->affinity : NULL);
111+
if (irq < 0)
112+
return -ENOMEM;
113+
- rc = irq_set_msi_desc(irq, msi);
114+
- if (rc)
115+
- return rc;
116+
- irq_set_chip_and_handler(irq, &zpci_irq_chip,
117+
- handle_percpu_irq);
118+
+
119+
+ for (i = 0; i < irqs_per_msi; i++) {
120+
+ rc = irq_set_msi_desc_off(irq, i, msi);
121+
+ if (rc)
122+
+ return rc;
123+
+ irq_set_chip_and_handler(irq + i, &zpci_irq_chip,
124+
+ handle_percpu_irq);
125+
+ }
126+
+
127+
msg.data = hwirq - bit;
128+
if (irq_delivery == DIRECTED) {
129+
- if (msi->affinity)
130+
- cpu = cpumask_first(&msi->affinity->mask);
131+
- else
132+
- cpu = 0;
133+
- cpu_addr = smp_cpu_get_cpu_address(cpu);
134+
-
135+
msg.address_lo = zdev->msi_addr & 0xff0000ff;
136+
- msg.address_lo |= (cpu_addr << 8);
137+
-
138+
+ msg.address_lo |= msi->affinity ?
139+
+ (cpumask_first(&msi->affinity->mask) << 8) : 0;
140+
for_each_possible_cpu(cpu) {
141+
- airq_iv_set_data(zpci_ibv[cpu], hwirq, irq);
142+
+ for (i = 0; i < irqs_per_msi; i++)
143+
+ airq_iv_set_data(zpci_ibv[cpu],
144+
+ hwirq + i, irq + i);
145+
}
146+
} else {
147+
msg.address_lo = zdev->msi_addr & 0xffffffff;
148+
@@@ -362,15 -398,11 +413,23 @@@ void arch_teardown_msi_irqs(struct pci_
149+
return;
150+
151+
/* Release MSI interrupts */
152+
++<<<<<<< HEAD
153+
+ for_each_pci_msi_entry(msi, pdev) {
154+
+ if (!msi->irq)
155+
+ continue;
156+
+ if (msi->msi_attrib.is_msix)
157+
+ __pci_msix_desc_mask_irq(msi, 1);
158+
+ else
159+
+ __pci_msi_desc_mask_irq(msi, 1, 1);
160+
+ irq_set_msi_desc(msi->irq, NULL);
161+
+ irq_free_desc(msi->irq);
162+
++=======
163+
+ msi_for_each_desc(msi, &pdev->dev, MSI_DESC_ASSOCIATED) {
164+
+ for (i = 0; i < msi->nvec_used; i++) {
165+
+ irq_set_msi_desc(msi->irq + i, NULL);
166+
+ irq_free_desc(msi->irq + i);
167+
+ }
168+
++>>>>>>> ab42fcb511fd (s390/pci: Allow allocation of more than 1 MSI interrupt)
169+
msi->msg.address_lo = 0;
170+
msi->msg.address_hi = 0;
171+
msi->msg.data = 0;
172+
* Unmerged path arch/s390/pci/pci_irq.c

0 commit comments

Comments
 (0)