Skip to content

Commit 2389d8d

Browse files
ij-intelkwilczynski
authored andcommitted
PCI/bwctrl: Replace lbms_count with PCI_LINK_LBMS_SEEN flag
PCIe BW controller counted LBMS assertions for the purposes of the Target Speed quirk (pcie_failed_link_retrain()). It was also a plan to expose the LBMS count through sysfs to allow better diagnosing link related issues. Lukas Wunner suggested, however, that adding a trace event would be better for diagnostics purposes, leaving only pcie_failed_link_retrain() as a user of the lbms_count. The logic in pcie_failed_link_retrain() does not require keeping count of LBMS assertions, so replace lbms_count with a simple flag in pci_dev's priv_flags. The reduced complexity allows removing pcie_bwctrl_lbms_rwsem. Since pcie_failed_link_retrain() runs before bwctrl is probed during boot, the LBMS in Link Status register still has to be checked by the quirk. The priv_flags numbering is not continuous because hotplug code added a few flags to fill numbers 4-5 (hotplug and bwctrl changes are routed through in different branches). Suggested-by: Lukas Wunner <[email protected]> Signed-off-by: Ilpo Järvinen <[email protected]> [bhelgaas: commit log] Signed-off-by: Bjorn Helgaas <[email protected]> [kwilczynski: squashed a fix to resolve build failures from https://lore.kernel.org/all/[email protected]] Signed-off-by: Krzysztof Wilczyński <[email protected]> Reviewed-by: Lukas Wunner <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent 0af2f6b commit 2389d8d

File tree

5 files changed

+26
-71
lines changed

5 files changed

+26
-71
lines changed

drivers/pci/hotplug/pciehp_ctrl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ static void remove_board(struct controller *ctrl, bool safe_removal)
131131
INDICATOR_NOOP);
132132

133133
/* Don't carry LBMS indications across */
134-
pcie_reset_lbms_count(ctrl->pcie->port);
134+
pcie_reset_lbms(ctrl->pcie->port);
135135
}
136136

137137
static int pciehp_enable_slot(struct controller *ctrl);

drivers/pci/pci.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4757,7 +4757,7 @@ int pcie_retrain_link(struct pci_dev *pdev, bool use_lt)
47574757
* to track link speed or width changes made by hardware itself
47584758
* in attempt to correct unreliable link operation.
47594759
*/
4760-
pcie_reset_lbms_count(pdev);
4760+
pcie_reset_lbms(pdev);
47614761
return rc;
47624762
}
47634763

drivers/pci/pci.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ static inline int pci_dev_set_disconnected(struct pci_dev *dev, void *unused)
557557
#define PCI_DPC_RECOVERED 1
558558
#define PCI_DPC_RECOVERING 2
559559
#define PCI_DEV_REMOVED 3
560+
#define PCI_LINK_LBMS_SEEN 6
560561

561562
static inline void pci_dev_assign_added(struct pci_dev *dev)
562563
{
@@ -824,14 +825,9 @@ static inline void pcie_ecrc_get_policy(char *str) { }
824825
#endif
825826

826827
#ifdef CONFIG_PCIEPORTBUS
827-
void pcie_reset_lbms_count(struct pci_dev *port);
828-
int pcie_lbms_count(struct pci_dev *port, unsigned long *val);
828+
void pcie_reset_lbms(struct pci_dev *port);
829829
#else
830-
static inline void pcie_reset_lbms_count(struct pci_dev *port) {}
831-
static inline int pcie_lbms_count(struct pci_dev *port, unsigned long *val)
832-
{
833-
return -EOPNOTSUPP;
834-
}
830+
static inline void pcie_reset_lbms(struct pci_dev *port) {}
835831
#endif
836832

837833
struct pci_dev_reset_methods {

drivers/pci/pcie/bwctrl.c

Lines changed: 18 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,14 @@
3838
/**
3939
* struct pcie_bwctrl_data - PCIe bandwidth controller
4040
* @set_speed_mutex: Serializes link speed changes
41-
* @lbms_count: Count for LBMS (since last reset)
4241
* @cdev: Thermal cooling device associated with the port
4342
*/
4443
struct pcie_bwctrl_data {
4544
struct mutex set_speed_mutex;
46-
atomic_t lbms_count;
4745
struct thermal_cooling_device *cdev;
4846
};
4947

50-
/*
51-
* Prevent port removal during LBMS count accessors and Link Speed changes.
52-
*
53-
* These have to be differentiated because pcie_bwctrl_change_speed() calls
54-
* pcie_retrain_link() which uses LBMS count reset accessor on success
55-
* (using just one rwsem triggers "possible recursive locking detected"
56-
* warning).
57-
*/
58-
static DECLARE_RWSEM(pcie_bwctrl_lbms_rwsem);
48+
/* Prevent port removal during Link Speed changes. */
5949
static DECLARE_RWSEM(pcie_bwctrl_setspeed_rwsem);
6050

6151
static bool pcie_valid_speed(enum pci_bus_speed speed)
@@ -202,15 +192,14 @@ int pcie_set_target_speed(struct pci_dev *port, enum pci_bus_speed speed_req,
202192

203193
static void pcie_bwnotif_enable(struct pcie_device *srv)
204194
{
205-
struct pcie_bwctrl_data *data = srv->port->link_bwctrl;
206195
struct pci_dev *port = srv->port;
207196
u16 link_status;
208197
int ret;
209198

210-
/* Count LBMS seen so far as one */
199+
/* Note if LBMS has been seen so far */
211200
ret = pcie_capability_read_word(port, PCI_EXP_LNKSTA, &link_status);
212201
if (ret == PCIBIOS_SUCCESSFUL && link_status & PCI_EXP_LNKSTA_LBMS)
213-
atomic_inc(&data->lbms_count);
202+
set_bit(PCI_LINK_LBMS_SEEN, &port->priv_flags);
214203

215204
pcie_capability_set_word(port, PCI_EXP_LNKCTL,
216205
PCI_EXP_LNKCTL_LBMIE | PCI_EXP_LNKCTL_LABIE);
@@ -233,7 +222,6 @@ static void pcie_bwnotif_disable(struct pci_dev *port)
233222
static irqreturn_t pcie_bwnotif_irq(int irq, void *context)
234223
{
235224
struct pcie_device *srv = context;
236-
struct pcie_bwctrl_data *data = srv->port->link_bwctrl;
237225
struct pci_dev *port = srv->port;
238226
u16 link_status, events;
239227
int ret;
@@ -247,7 +235,7 @@ static irqreturn_t pcie_bwnotif_irq(int irq, void *context)
247235
return IRQ_NONE;
248236

249237
if (events & PCI_EXP_LNKSTA_LBMS)
250-
atomic_inc(&data->lbms_count);
238+
set_bit(PCI_LINK_LBMS_SEEN, &port->priv_flags);
251239

252240
pcie_capability_write_word(port, PCI_EXP_LNKSTA, events);
253241

@@ -262,31 +250,10 @@ static irqreturn_t pcie_bwnotif_irq(int irq, void *context)
262250
return IRQ_HANDLED;
263251
}
264252

265-
void pcie_reset_lbms_count(struct pci_dev *port)
266-
{
267-
struct pcie_bwctrl_data *data;
268-
269-
guard(rwsem_read)(&pcie_bwctrl_lbms_rwsem);
270-
data = port->link_bwctrl;
271-
if (data)
272-
atomic_set(&data->lbms_count, 0);
273-
else
274-
pcie_capability_write_word(port, PCI_EXP_LNKSTA,
275-
PCI_EXP_LNKSTA_LBMS);
276-
}
277-
278-
int pcie_lbms_count(struct pci_dev *port, unsigned long *val)
253+
void pcie_reset_lbms(struct pci_dev *port)
279254
{
280-
struct pcie_bwctrl_data *data;
281-
282-
guard(rwsem_read)(&pcie_bwctrl_lbms_rwsem);
283-
data = port->link_bwctrl;
284-
if (!data)
285-
return -ENOTTY;
286-
287-
*val = atomic_read(&data->lbms_count);
288-
289-
return 0;
255+
clear_bit(PCI_LINK_LBMS_SEEN, &port->priv_flags);
256+
pcie_capability_write_word(port, PCI_EXP_LNKSTA, PCI_EXP_LNKSTA_LBMS);
290257
}
291258

292259
static int pcie_bwnotif_probe(struct pcie_device *srv)
@@ -308,18 +275,16 @@ static int pcie_bwnotif_probe(struct pcie_device *srv)
308275
return ret;
309276

310277
scoped_guard(rwsem_write, &pcie_bwctrl_setspeed_rwsem) {
311-
scoped_guard(rwsem_write, &pcie_bwctrl_lbms_rwsem) {
312-
port->link_bwctrl = data;
313-
314-
ret = request_irq(srv->irq, pcie_bwnotif_irq,
315-
IRQF_SHARED, "PCIe bwctrl", srv);
316-
if (ret) {
317-
port->link_bwctrl = NULL;
318-
return ret;
319-
}
278+
port->link_bwctrl = data;
320279

321-
pcie_bwnotif_enable(srv);
280+
ret = request_irq(srv->irq, pcie_bwnotif_irq,
281+
IRQF_SHARED, "PCIe bwctrl", srv);
282+
if (ret) {
283+
port->link_bwctrl = NULL;
284+
return ret;
322285
}
286+
287+
pcie_bwnotif_enable(srv);
323288
}
324289

325290
pci_dbg(port, "enabled with IRQ %d\n", srv->irq);
@@ -339,13 +304,11 @@ static void pcie_bwnotif_remove(struct pcie_device *srv)
339304
pcie_cooling_device_unregister(data->cdev);
340305

341306
scoped_guard(rwsem_write, &pcie_bwctrl_setspeed_rwsem) {
342-
scoped_guard(rwsem_write, &pcie_bwctrl_lbms_rwsem) {
343-
pcie_bwnotif_disable(srv->port);
307+
pcie_bwnotif_disable(srv->port);
344308

345-
free_irq(srv->irq, srv);
309+
free_irq(srv->irq, srv);
346310

347-
srv->port->link_bwctrl = NULL;
348-
}
311+
srv->port->link_bwctrl = NULL;
349312
}
350313
}
351314

drivers/pci/quirks.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,10 @@
3838

3939
static bool pcie_lbms_seen(struct pci_dev *dev, u16 lnksta)
4040
{
41-
unsigned long count;
42-
int ret;
43-
44-
ret = pcie_lbms_count(dev, &count);
45-
if (ret < 0)
46-
return lnksta & PCI_EXP_LNKSTA_LBMS;
41+
if (test_bit(PCI_LINK_LBMS_SEEN, &dev->priv_flags))
42+
return true;
4743

48-
return count > 0;
44+
return lnksta & PCI_EXP_LNKSTA_LBMS;
4945
}
5046

5147
/*

0 commit comments

Comments
 (0)