Skip to content

Commit da40572

Browse files
committed
s390/pci: Sort PCI functions prior to creating virtual busses
jira LE-2349 Rebuild_History Non-Buildable kernel-4.18.0-553.40.1.el8_10 commit-author Niklas Schnelle <schnelle@linux.ibm.com> commit 0467cdd 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/0467cdde.failed Instead of relying on the observed but not architected firmware behavior that PCI functions from the same card are listed in ascending RID order in clp_list_pci() ensure this by sorting. To allow for sorting separate the initial clp_list_pci() and creation of the virtual PCI busses. Note that fundamentally in our per-PCI function hotplug design non RID order of discovery is still possible. For example when the two PFs of a two port NIC are hotplugged after initial boot and in descending RID order. In this case the virtual PCI bus would be created by the second PF using that PF's UID as domain number instead of that of the first PF. Thus the domain number would then change from the UID of the second PF to that of the first PF on reboot but there is really nothing we can do about that since changing domain numbers at runtime seems even worse. This only impacts the domain number as the RIDs are consistent and thus even with just the second PF visible it will show up in the correct position on the virtual bus. Reviewed-by: Gerd Bayer <gbayer@linux.ibm.com> Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> (cherry picked from commit 0467cdd) Signed-off-by: Jonathan Maple <jmaple@ciq.com> # Conflicts: # arch/s390/pci/pci.c
1 parent 40181f9 commit da40572

File tree

1 file changed

+219
-0
lines changed

1 file changed

+219
-0
lines changed
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
s390/pci: Sort PCI functions prior to creating virtual busses
2+
3+
jira LE-2349
4+
Rebuild_History Non-Buildable kernel-4.18.0-553.40.1.el8_10
5+
commit-author Niklas Schnelle <schnelle@linux.ibm.com>
6+
commit 0467cdde8c4320bbfdb31a8cff1277b202f677fc
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/0467cdde.failed
10+
11+
Instead of relying on the observed but not architected firmware behavior
12+
that PCI functions from the same card are listed in ascending RID order
13+
in clp_list_pci() ensure this by sorting. To allow for sorting separate
14+
the initial clp_list_pci() and creation of the virtual PCI busses.
15+
16+
Note that fundamentally in our per-PCI function hotplug design non RID
17+
order of discovery is still possible. For example when the two PFs of
18+
a two port NIC are hotplugged after initial boot and in descending RID
19+
order. In this case the virtual PCI bus would be created by the second
20+
PF using that PF's UID as domain number instead of that of the first PF.
21+
Thus the domain number would then change from the UID of the second PF
22+
to that of the first PF on reboot but there is really nothing we can do
23+
about that since changing domain numbers at runtime seems even worse.
24+
This only impacts the domain number as the RIDs are consistent and thus
25+
even with just the second PF visible it will show up in the correct
26+
position on the virtual bus.
27+
28+
Reviewed-by: Gerd Bayer <gbayer@linux.ibm.com>
29+
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
30+
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
31+
(cherry picked from commit 0467cdde8c4320bbfdb31a8cff1277b202f677fc)
32+
Signed-off-by: Jonathan Maple <jmaple@ciq.com>
33+
34+
# Conflicts:
35+
# arch/s390/pci/pci.c
36+
diff --cc arch/s390/pci/pci.c
37+
index 162ca752cec9,b7efa96776ea..000000000000
38+
--- a/arch/s390/pci/pci.c
39+
+++ b/arch/s390/pci/pci.c
40+
@@@ -27,6 -27,9 +27,12 @@@
41+
#include <linux/seq_file.h>
42+
#include <linux/jump_label.h>
43+
#include <linux/pci.h>
44+
++<<<<<<< HEAD
45+
++=======
46+
+ #include <linux/printk.h>
47+
+ #include <linux/lockdep.h>
48+
+ #include <linux/list_sort.h>
49+
++>>>>>>> 0467cdde8c43 (s390/pci: Sort PCI functions prior to creating virtual busses)
50+
51+
#include <asm/isc.h>
52+
#include <asm/airq.h>
53+
@@@ -885,9 -801,23 +890,22 @@@ struct zpci_dev *zpci_create_device(u3
54+
zdev->state = state;
55+
56+
kref_init(&zdev->kref);
57+
- mutex_init(&zdev->state_lock);
58+
- mutex_init(&zdev->fmb_lock);
59+
+ mutex_init(&zdev->lock);
60+
mutex_init(&zdev->kzdev_lock);
61+
62+
+ return zdev;
63+
+
64+
+ error:
65+
+ zpci_dbg(0, "crt fid:%x, rc:%d\n", fid, rc);
66+
+ kfree(zdev);
67+
+ return ERR_PTR(rc);
68+
+ }
69+
+
70+
+ int zpci_add_device(struct zpci_dev *zdev)
71+
+ {
72+
+ int rc;
73+
+
74+
+ zpci_dbg(1, "add fid:%x, fh:%x, c:%d\n", zdev->fid, zdev->fh, zdev->state);
75+
rc = zpci_init_iommu(zdev);
76+
if (rc)
77+
goto error;
78+
@@@ -1197,14 -1165,9 +1256,17 @@@ static int __init pci_base_init(void
79+
if (rc)
80+
goto out_irq;
81+
82+
++<<<<<<< HEAD
83+
+ rc = zpci_dma_init();
84+
+ if (rc)
85+
+ goto out_dma;
86+
+
87+
+ rc = clp_scan_pci_devices();
88+
++=======
89+
+ rc = zpci_scan_devices();
90+
++>>>>>>> 0467cdde8c43 (s390/pci: Sort PCI functions prior to creating virtual busses)
91+
if (rc)
92+
goto out_find;
93+
- zpci_bus_scan_busses();
94+
95+
s390_pci_initialized = 1;
96+
return 0;
97+
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
98+
index 15948089980a..25dae71f4671 100644
99+
--- a/arch/s390/include/asm/pci.h
100+
+++ b/arch/s390/include/asm/pci.h
101+
@@ -129,6 +129,7 @@ struct zpci_dev {
102+
u16 vfn; /* virtual function number */
103+
u16 pchid; /* physical channel ID */
104+
u16 maxstbl; /* Maximum store block size */
105+
+ u16 rid; /* RID as supplied by firmware */
106+
u8 pfgid; /* function group ID */
107+
u8 pft; /* pci function type */
108+
u8 port;
109+
@@ -215,12 +216,14 @@ extern struct airq_iv *zpci_aif_sbv;
110+
----------------------------------------------------------------------------- */
111+
/* Base stuff */
112+
struct zpci_dev *zpci_create_device(u32 fid, u32 fh, enum zpci_state state);
113+
+int zpci_add_device(struct zpci_dev *zdev);
114+
int zpci_enable_device(struct zpci_dev *);
115+
int zpci_disable_device(struct zpci_dev *);
116+
int zpci_scan_configured_device(struct zpci_dev *zdev, u32 fh);
117+
int zpci_deconfigure_device(struct zpci_dev *zdev);
118+
void zpci_device_reserved(struct zpci_dev *zdev);
119+
bool zpci_is_device_configured(struct zpci_dev *zdev);
120+
+int zpci_scan_devices(void);
121+
122+
int zpci_hot_reset_device(struct zpci_dev *zdev);
123+
int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64, u8 *);
124+
@@ -231,7 +234,7 @@ void zpci_update_fh(struct zpci_dev *zdev, u32 fh);
125+
/* CLP */
126+
int rhel8_clp_rescan_pci_devices_simple(void);
127+
int clp_setup_writeback_mio(void);
128+
-int clp_scan_pci_devices(void);
129+
+int clp_scan_pci_devices(struct list_head *scan_list);
130+
int clp_query_pci_fn(struct zpci_dev *zdev);
131+
int clp_enable_fh(struct zpci_dev *zdev, u32 *fh, u8 nr_dma_as);
132+
int clp_disable_fh(struct zpci_dev *zdev, u32 *fh);
133+
* Unmerged path arch/s390/pci/pci.c
134+
diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c
135+
index 34759316747b..0e3a6b839ce9 100644
136+
--- a/arch/s390/pci/pci_clp.c
137+
+++ b/arch/s390/pci/pci_clp.c
138+
@@ -163,8 +163,10 @@ static int clp_store_query_pci_fn(struct zpci_dev *zdev,
139+
zdev->port = response->port;
140+
zdev->uid = response->uid;
141+
zdev->fmb_length = sizeof(u32) * response->fmb_len;
142+
- zdev->rid_available = response->rid_avail;
143+
zdev->is_physfn = response->is_physfn;
144+
+ zdev->rid_available = response->rid_avail;
145+
+ if (zdev->rid_available)
146+
+ zdev->rid = response->rid;
147+
if (!s390_pci_no_rid && zdev->rid_available)
148+
zdev->devfn = response->rid & ZPCI_RID_MASK_DEVFN;
149+
150+
@@ -406,6 +408,7 @@ static int clp_find_pci(struct clp_req_rsp_list_pci *rrb, u32 fid,
151+
152+
static void __clp_add(struct clp_fh_list_entry *entry, void *data)
153+
{
154+
+ struct list_head *scan_list = data;
155+
struct zpci_dev *zdev;
156+
157+
if (!entry->vendor_id)
158+
@@ -416,10 +419,11 @@ static void __clp_add(struct clp_fh_list_entry *entry, void *data)
159+
zpci_zdev_put(zdev);
160+
return;
161+
}
162+
- zpci_create_device(entry->fid, entry->fh, entry->config_state);
163+
+ zdev = zpci_create_device(entry->fid, entry->fh, entry->config_state);
164+
+ list_add_tail(&zdev->entry, scan_list);
165+
}
166+
167+
-int clp_scan_pci_devices(void)
168+
+int clp_scan_pci_devices(struct list_head *scan_list)
169+
{
170+
struct clp_req_rsp_list_pci *rrb;
171+
int rc;
172+
@@ -428,7 +432,7 @@ int clp_scan_pci_devices(void)
173+
if (!rrb)
174+
return -ENOMEM;
175+
176+
- rc = clp_list_pci(rrb, NULL, __clp_add);
177+
+ rc = clp_list_pci(rrb, scan_list, __clp_add);
178+
179+
clp_free_block(rrb);
180+
return rc;
181+
diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c
182+
index b3961f1016ea..74edb6fb6582 100644
183+
--- a/arch/s390/pci/pci_event.c
184+
+++ b/arch/s390/pci/pci_event.c
185+
@@ -328,6 +328,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
186+
zdev = zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_CONFIGURED);
187+
if (IS_ERR(zdev))
188+
break;
189+
+ zpci_add_device(zdev);
190+
} else {
191+
/* the configuration request may be stale */
192+
if (zdev->state != ZPCI_FN_STATE_STANDBY)
193+
@@ -337,10 +338,14 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
194+
zpci_scan_configured_device(zdev, ccdf->fh);
195+
break;
196+
case 0x0302: /* Reserved -> Standby */
197+
- if (!zdev)
198+
- zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_STANDBY);
199+
- else
200+
+ if (!zdev) {
201+
+ zdev = zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_STANDBY);
202+
+ if (IS_ERR(zdev))
203+
+ break;
204+
+ zpci_add_device(zdev);
205+
+ } else {
206+
zpci_update_fh(zdev, ccdf->fh);
207+
+ }
208+
break;
209+
case 0x0303: /* Deconfiguration requested */
210+
if (zdev) {
211+
@@ -369,7 +374,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
212+
break;
213+
case 0x0306: /* 0x308 or 0x302 for multiple devices */
214+
zpci_remove_reserved_devices();
215+
- clp_scan_pci_devices();
216+
+ zpci_scan_devices();
217+
break;
218+
case 0x0308: /* Standby -> Reserved */
219+
if (!zdev)

0 commit comments

Comments
 (0)