linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM
@ 2019-10-05 12:02 Heiner Kallweit
  2019-10-05 12:03 ` [PATCH v7 2/5] PCI/ASPM: Allow to re-enable Clock PM Heiner Kallweit
                   ` (5 more replies)
  0 siblings, 6 replies; 17+ messages in thread
From: Heiner Kallweit @ 2019-10-05 12:02 UTC (permalink / raw)
  To: Frederick Lawler, Bjorn Helgaas, Greg KH, Rajat Jain; +Cc: linux-pci

Background of this extension is a problem with the r8169 network driver.
Several combinations of board chipsets and network chip versions have
problems if ASPM is enabled, therefore we have to disable ASPM per
default. However especially on notebooks ASPM can provide significant
power-saving, therefore we want to give users the option to enable
ASPM. With the new sysfs attributes users can control which ASPM
link-states are disabled.

v2:
- use a dedicated sysfs attribute per link state
- allow separate control of ASPM and PCI PM L1 sub-states

v3:
- patch 3: statically allocate the attribute group
- patch 3: replace snprintf with printf
- add patch 4

v4:
- patch 3: add call to sysfs_update_group because is_visible callback
           returns false always at file creation time
- patch 3: simplify code a little

v5:
- rebased to latest pci/next

v6:
- patch 3: consider several review comments from Bjorn
- patch 4: add discussion link to commit message

v7:
- Move adding pcie_aspm_get_link() to separate patch 3
- patch 4: change group name from aspm to link_pm
- patch 4: control visibility of attributes individually

Heiner Kallweit (5):
  PCI/ASPM: add L1 sub-state support to pci_disable_link_state
  PCI/ASPM: allow to re-enable Clock PM
  PCI/ASPM: Add and use helper pcie_aspm_get_link
  PCI/ASPM: Add sysfs attributes for controlling ASPM link states
  PCI/ASPM: Remove Kconfig option PCIEASPM_DEBUG and related code

 Documentation/ABI/testing/sysfs-bus-pci |  14 ++
 drivers/pci/pci-sysfs.c                 |   6 +-
 drivers/pci/pci.h                       |  12 +-
 drivers/pci/pcie/Kconfig                |   7 -
 drivers/pci/pcie/aspm.c                 | 252 ++++++++++++++++--------
 include/linux/pci.h                     |  10 +-
 6 files changed, 199 insertions(+), 102 deletions(-)

-- 
2.23.0



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v7 2/5] PCI/ASPM: Allow to re-enable Clock PM
  2019-10-05 12:02 [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM Heiner Kallweit
@ 2019-10-05 12:03 ` Heiner Kallweit
  2019-10-05 12:04 ` [PATCH v7 1/5] PCI/ASPM: Add L1 sub-state support to pci_disable_link_state Heiner Kallweit
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 17+ messages in thread
From: Heiner Kallweit @ 2019-10-05 12:03 UTC (permalink / raw)
  To: Frederick Lawler, Bjorn Helgaas, Greg KH, Rajat Jain; +Cc: linux-pci

So far Clock PM can't be re-enabled once it has been disabled with
a call to pci_disable_link_state(). Reason is that clkpm_capable
is reset. Change this by adding a clkpm_disable field similar to
aspm_disable.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/pci/pcie/aspm.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index ed463339e..574f822bf 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -64,6 +64,7 @@ struct pcie_link_state {
 	u32 clkpm_capable:1;		/* Clock PM capable? */
 	u32 clkpm_enabled:1;		/* Current Clock PM state */
 	u32 clkpm_default:1;		/* Default Clock PM state by BIOS */
+	u32 clkpm_disable:1;		/* Clock PM disabled */
 
 	/* Exit latencies */
 	struct aspm_latency latency_up;	/* Upstream direction exit latency */
@@ -161,8 +162,11 @@ static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable)
 
 static void pcie_set_clkpm(struct pcie_link_state *link, int enable)
 {
-	/* Don't enable Clock PM if the link is not Clock PM capable */
-	if (!link->clkpm_capable)
+	/*
+	 * Don't enable Clock PM if the link is not Clock PM capable
+	 * or Clock PM is disabled
+	 */
+	if (!link->clkpm_capable || link->clkpm_disable)
 		enable = 0;
 	/* Need nothing if the specified equals to current state */
 	if (link->clkpm_enabled == enable)
@@ -192,7 +196,8 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
 	}
 	link->clkpm_enabled = enabled;
 	link->clkpm_default = enabled;
-	link->clkpm_capable = (blacklist) ? 0 : capable;
+	link->clkpm_capable = capable;
+	link->clkpm_disable = blacklist ? 1 : 0;
 }
 
 static bool pcie_retrain_link(struct pcie_link_state *link)
@@ -1106,10 +1111,9 @@ static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
 		link->aspm_disable |= ASPM_STATE_L1_2_PCIPM;
 	pcie_config_aspm_link(link, policy_to_aspm_state(link));
 
-	if (state & PCIE_LINK_STATE_CLKPM) {
-		link->clkpm_capable = 0;
-		pcie_set_clkpm(link, 0);
-	}
+	if (state & PCIE_LINK_STATE_CLKPM)
+		link->clkpm_disable = 1;
+	pcie_set_clkpm(link, policy_to_clkpm_state(link));
 	mutex_unlock(&aspm_lock);
 	if (sem)
 		up_read(&pci_bus_sem);
-- 
2.23.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v7 1/5] PCI/ASPM: Add L1 sub-state support to pci_disable_link_state
  2019-10-05 12:02 [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM Heiner Kallweit
  2019-10-05 12:03 ` [PATCH v7 2/5] PCI/ASPM: Allow to re-enable Clock PM Heiner Kallweit
@ 2019-10-05 12:04 ` Heiner Kallweit
  2019-10-05 12:07 ` [PATCH v7 3/5] PCI/ASPM: Add and use helper pcie_aspm_get_link Heiner Kallweit
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 17+ messages in thread
From: Heiner Kallweit @ 2019-10-05 12:04 UTC (permalink / raw)
  To: Frederick Lawler, Bjorn Helgaas, Greg KH, Rajat Jain; +Cc: linux-pci

Add support for disabling states L1.1 and L1.2 to
pci_disable_link_state(). Allow separate control of
ASPM and PCI PM L1 sub-states.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
v2:
- allow separate control of ASPM and PCI PM L1 sub-states
---
 drivers/pci/pcie/aspm.c | 11 ++++++++++-
 include/linux/pci.h     | 10 +++++++---
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 652ef23bb..ed463339e 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -1094,7 +1094,16 @@ static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
 	if (state & PCIE_LINK_STATE_L0S)
 		link->aspm_disable |= ASPM_STATE_L0S;
 	if (state & PCIE_LINK_STATE_L1)
-		link->aspm_disable |= ASPM_STATE_L1;
+		/* sub-states require L1 */
+		link->aspm_disable |= ASPM_STATE_L1 | ASPM_STATE_L1SS;
+	if (state & PCIE_LINK_STATE_L1_1)
+		link->aspm_disable |= ASPM_STATE_L1_1;
+	if (state & PCIE_LINK_STATE_L1_2)
+		link->aspm_disable |= ASPM_STATE_L1_2;
+	if (state & PCIE_LINK_STATE_L1_1_PCIPM)
+		link->aspm_disable |= ASPM_STATE_L1_1_PCIPM;
+	if (state & PCIE_LINK_STATE_L1_2_PCIPM)
+		link->aspm_disable |= ASPM_STATE_L1_2_PCIPM;
 	pcie_config_aspm_link(link, policy_to_aspm_state(link));
 
 	if (state & PCIE_LINK_STATE_CLKPM) {
diff --git a/include/linux/pci.h b/include/linux/pci.h
index f9088c89a..9dc5bee14 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1544,9 +1544,13 @@ extern bool pcie_ports_native;
 #define pcie_ports_native	false
 #endif
 
-#define PCIE_LINK_STATE_L0S	1
-#define PCIE_LINK_STATE_L1	2
-#define PCIE_LINK_STATE_CLKPM	4
+#define PCIE_LINK_STATE_L0S		BIT(0)
+#define PCIE_LINK_STATE_L1		BIT(1)
+#define PCIE_LINK_STATE_CLKPM		BIT(2)
+#define PCIE_LINK_STATE_L1_1		BIT(3)
+#define PCIE_LINK_STATE_L1_2		BIT(4)
+#define PCIE_LINK_STATE_L1_1_PCIPM	BIT(5)
+#define PCIE_LINK_STATE_L1_2_PCIPM	BIT(6)
 
 #ifdef CONFIG_PCIEASPM
 int pci_disable_link_state(struct pci_dev *pdev, int state);
-- 
2.23.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v7 3/5] PCI/ASPM: Add and use helper pcie_aspm_get_link
  2019-10-05 12:02 [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM Heiner Kallweit
  2019-10-05 12:03 ` [PATCH v7 2/5] PCI/ASPM: Allow to re-enable Clock PM Heiner Kallweit
  2019-10-05 12:04 ` [PATCH v7 1/5] PCI/ASPM: Add L1 sub-state support to pci_disable_link_state Heiner Kallweit
@ 2019-10-05 12:07 ` Heiner Kallweit
  2019-10-08  1:51   ` Bjorn Helgaas
  2019-10-05 12:07 ` [PATCH v7 4/5] PCI/ASPM: Add sysfs attributes for controlling ASPM link states Heiner Kallweit
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Heiner Kallweit @ 2019-10-05 12:07 UTC (permalink / raw)
  To: Frederick Lawler, Bjorn Helgaas, Greg KH, Rajat Jain; +Cc: linux-pci

Factor out getting the link associated with a pci_dev and use this
helper where appropriate. In addition this helper will be used
in a subsequent patch of this series.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
v7:
- add as separate patch
---
 drivers/pci/pcie/aspm.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 574f822bf..91cfea673 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -1066,19 +1066,28 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
 	up_read(&pci_bus_sem);
 }
 
+static struct pcie_link_state *pcie_aspm_get_link(struct pci_dev *pdev)
+{
+	struct pci_dev *upstream;
+
+	if (pcie_downstream_port(pdev))
+		upstream = pdev;
+	else
+		upstream = pci_upstream_bridge(pdev);
+
+	return upstream ? upstream->link_state : NULL;
+}
+
 static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
 {
-	struct pci_dev *parent = pdev->bus->self;
 	struct pcie_link_state *link;
 
 	if (!pci_is_pcie(pdev))
 		return 0;
 
-	if (pcie_downstream_port(pdev))
-		parent = pdev;
-	if (!parent || !parent->link_state)
+	link = pcie_aspm_get_link(pdev);
+	if (!link)
 		return -EINVAL;
-
 	/*
 	 * A driver requested that ASPM be disabled on this device, but
 	 * if we don't have permission to manage ASPM (e.g., on ACPI
@@ -1095,7 +1104,6 @@ static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
 	if (sem)
 		down_read(&pci_bus_sem);
 	mutex_lock(&aspm_lock);
-	link = parent->link_state;
 	if (state & PCIE_LINK_STATE_L0S)
 		link->aspm_disable |= ASPM_STATE_L0S;
 	if (state & PCIE_LINK_STATE_L1)
@@ -1188,14 +1196,14 @@ module_param_call(policy, pcie_aspm_set_policy, pcie_aspm_get_policy,
  */
 bool pcie_aspm_enabled(struct pci_dev *pdev)
 {
-	struct pci_dev *bridge = pci_upstream_bridge(pdev);
+	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
 	bool ret;
 
-	if (!bridge)
+	if (!link)
 		return false;
 
 	mutex_lock(&aspm_lock);
-	ret = bridge->link_state ? !!bridge->link_state->aspm_enabled : false;
+	ret = link->aspm_enabled;
 	mutex_unlock(&aspm_lock);
 
 	return ret;
-- 
2.23.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v7 4/5] PCI/ASPM: Add sysfs attributes for controlling ASPM link states
  2019-10-05 12:02 [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM Heiner Kallweit
                   ` (2 preceding siblings ...)
  2019-10-05 12:07 ` [PATCH v7 3/5] PCI/ASPM: Add and use helper pcie_aspm_get_link Heiner Kallweit
@ 2019-10-05 12:07 ` Heiner Kallweit
  2019-10-08  1:53   ` Bjorn Helgaas
  2019-11-21 20:49   ` Bjorn Helgaas
  2019-10-05 12:08 ` [PATCH v7 5/5] PCI/ASPM: Remove Kconfig option PCIEASPM_DEBUG and related code Heiner Kallweit
  2019-10-08 22:10 ` [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM Bjorn Helgaas
  5 siblings, 2 replies; 17+ messages in thread
From: Heiner Kallweit @ 2019-10-05 12:07 UTC (permalink / raw)
  To: Frederick Lawler, Bjorn Helgaas, Greg KH, Rajat Jain; +Cc: linux-pci

Background of this extension is a problem with the r8169 network driver.
Several combinations of board chipsets and network chip versions have
problems if ASPM is enabled, therefore we have to disable ASPM per default.
However especially on notebooks ASPM can provide significant power-saving,
therefore we want to give users the option to enable ASPM. With the new
sysfs attributes users can control which ASPM link-states are
enabled/disabled.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
v2:
- use a dedicated sysfs attribute per link state
- allow separate control of ASPM and PCI PM L1 sub-states
v3:
- statically allocate the attribute group
- replace snprintf with printf
- base on top of "PCI: Make pcie_downstream_port() available outside of access.c"
v4:
- add call to sysfs_update_group because is_visible callback returns false
  always at file creation time
- simplify code a little
v5:
- rebased to latest pci/next
v6:
- fix style of added documentation and extend it
- don't use term "parent" and rename function to pcie_aspm_get_link
- rename pcie_check_valid_aspm_endpoint to pcie_is_aspm_dev
- enable the sysfs files also selected other port types
- avoid usage of !!
v7:
- change group name from aspm to link_pm
- control visibility of attributes individually
---
 Documentation/ABI/testing/sysfs-bus-pci |  14 ++
 drivers/pci/pci-sysfs.c                 |   3 +
 drivers/pci/pci.h                       |   4 +
 drivers/pci/pcie/aspm.c                 | 174 ++++++++++++++++++++++++
 4 files changed, 195 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci
index 8bfee557e..c86c8ab00 100644
--- a/Documentation/ABI/testing/sysfs-bus-pci
+++ b/Documentation/ABI/testing/sysfs-bus-pci
@@ -347,3 +347,17 @@ Description:
 		If the device has any Peer-to-Peer memory registered, this
 	        file contains a '1' if the memory has been published for
 		use outside the driver that owns the device.
+
+What:		/sys/bus/pci/devices/.../link_pm/clkpm
+		/sys/bus/pci/devices/.../link_pm/l0s_aspm
+		/sys/bus/pci/devices/.../link_pm/l1_aspm
+		/sys/bus/pci/devices/.../link_pm/l1_1_aspm
+		/sys/bus/pci/devices/.../link_pm/l1_2_aspm
+		/sys/bus/pci/devices/.../link_pm/l1_1_pcipm
+		/sys/bus/pci/devices/.../link_pm/l1_2_pcipm
+Date:		October 2019
+Contact:	Heiner Kallweit <hkallweit1@gmail.com>
+Description:	If ASPM is supported for an endpoint, then these files
+		can be used to disable or enable the individual
+		power management states. Write y/1/on to enable,
+		n/0/off to disable.
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 793412954..0e76c02e0 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1587,6 +1587,9 @@ static const struct attribute_group *pci_dev_attr_groups[] = {
 	&pcie_dev_attr_group,
 #ifdef CONFIG_PCIEAER
 	&aer_stats_attr_group,
+#endif
+#ifdef CONFIG_PCIEASPM
+	&aspm_ctrl_attr_group,
 #endif
 	NULL,
 };
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 3f6947ee3..b2cd21e8c 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -667,4 +667,8 @@ static inline int pci_acpi_program_hp_params(struct pci_dev *dev)
 }
 #endif
 
+#ifdef CONFIG_PCIEASPM
+extern const struct attribute_group aspm_ctrl_attr_group;
+#endif
+
 #endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 91cfea673..05ea02abf 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -899,6 +899,14 @@ static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev)
 	return link;
 }
 
+static void pcie_aspm_update_sysfs_visibility(struct pci_dev *pdev)
+{
+	struct pci_dev *child;
+
+	list_for_each_entry(child, &pdev->subordinate->devices, bus_list)
+		sysfs_update_group(&child->dev.kobj, &aspm_ctrl_attr_group);
+}
+
 /*
  * pcie_aspm_init_link_state: Initiate PCI express link state.
  * It is called after the pcie and its children devices are scanned.
@@ -960,6 +968,9 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
 		pcie_set_clkpm(link, policy_to_clkpm_state(link));
 	}
 
+	/* Update visibility of ASPM sysfs attributes */
+	pcie_aspm_update_sysfs_visibility(pdev);
+
 unlock:
 	mutex_unlock(&aspm_lock);
 out:
@@ -1315,6 +1326,169 @@ void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev)
 }
 #endif
 
+static ssize_t aspm_attr_show_common(struct device *dev,
+				     struct device_attribute *attr,
+				     char *buf, u8 state)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct pcie_link_state *link;
+	bool enabled;
+
+	link = pcie_aspm_get_link(pdev);
+
+	mutex_lock(&aspm_lock);
+	enabled = link->aspm_enabled & state;
+	mutex_unlock(&aspm_lock);
+
+	return sprintf(buf, "%d\n", enabled ? 1 : 0);
+}
+
+static ssize_t aspm_attr_store_common(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t len, u8 state)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct pcie_link_state *link;
+	bool state_enable;
+
+	link = pcie_aspm_get_link(pdev);
+
+	if (strtobool(buf, &state_enable) < 0)
+		return -EINVAL;
+
+	down_read(&pci_bus_sem);
+	mutex_lock(&aspm_lock);
+
+	if (state_enable) {
+		link->aspm_disable &= ~state;
+		/* need to enable L1 for sub-states */
+		if (state & ASPM_STATE_L1SS)
+			link->aspm_disable &= ~ASPM_STATE_L1;
+	} else {
+		link->aspm_disable |= state;
+	}
+
+	pcie_config_aspm_link(link, policy_to_aspm_state(link));
+
+	mutex_unlock(&aspm_lock);
+	up_read(&pci_bus_sem);
+
+	return len;
+}
+
+#define ASPM_ATTR(_f, _s)						\
+static ssize_t _f##_show(struct device *dev,				\
+			 struct device_attribute *attr, char *buf)	\
+{ return aspm_attr_show_common(dev, attr, buf, ASPM_STATE_##_s); }	\
+									\
+static ssize_t _f##_store(struct device *dev,				\
+			  struct device_attribute *attr,		\
+			  const char *buf, size_t len)			\
+{ return aspm_attr_store_common(dev, attr, buf, len, ASPM_STATE_##_s); }
+
+ASPM_ATTR(l0s_aspm, L0S)
+ASPM_ATTR(l1_aspm, L1)
+ASPM_ATTR(l1_1_aspm, L1_1)
+ASPM_ATTR(l1_2_aspm, L1_2)
+ASPM_ATTR(l1_1_pcipm, L1_1_PCIPM)
+ASPM_ATTR(l1_2_pcipm, L1_2_PCIPM)
+
+static ssize_t clkpm_show(struct device *dev,
+			  struct device_attribute *attr, char *buf)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct pcie_link_state *link;
+	int val;
+
+	link = pcie_aspm_get_link(pdev);
+
+	mutex_lock(&aspm_lock);
+	val = link->clkpm_enabled;
+	mutex_unlock(&aspm_lock);
+
+	return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t clkpm_store(struct device *dev,
+			   struct device_attribute *attr,
+			   const char *buf, size_t len)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct pcie_link_state *link;
+	bool state_enable;
+
+	link = pcie_aspm_get_link(pdev);
+
+	if (strtobool(buf, &state_enable) < 0)
+		return -EINVAL;
+
+	down_read(&pci_bus_sem);
+	mutex_lock(&aspm_lock);
+
+	link->clkpm_disable = !state_enable;
+	pcie_set_clkpm(link, policy_to_clkpm_state(link));
+
+	mutex_unlock(&aspm_lock);
+	up_read(&pci_bus_sem);
+
+	return len;
+}
+
+static DEVICE_ATTR_RW(clkpm);
+static DEVICE_ATTR_RW(l0s_aspm);
+static DEVICE_ATTR_RW(l1_aspm);
+static DEVICE_ATTR_RW(l1_1_aspm);
+static DEVICE_ATTR_RW(l1_2_aspm);
+static DEVICE_ATTR_RW(l1_1_pcipm);
+static DEVICE_ATTR_RW(l1_2_pcipm);
+
+static struct attribute *aspm_ctrl_attrs[] = {
+	&dev_attr_clkpm.attr,
+	&dev_attr_l0s_aspm.attr,
+	&dev_attr_l1_aspm.attr,
+	&dev_attr_l1_1_aspm.attr,
+	&dev_attr_l1_2_aspm.attr,
+	&dev_attr_l1_1_pcipm.attr,
+	&dev_attr_l1_2_pcipm.attr,
+	NULL
+};
+
+static umode_t aspm_ctrl_attrs_are_visible(struct kobject *kobj,
+					   struct attribute *a, int n)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct pcie_link_state *link = NULL;
+	static const u8 aspm_state_map[] = {
+		ASPM_STATE_L0S,
+		ASPM_STATE_L1,
+		ASPM_STATE_L1_1,
+		ASPM_STATE_L1_2,
+		ASPM_STATE_L1_1_PCIPM,
+		ASPM_STATE_L1_2_PCIPM,
+	};
+
+	if (aspm_disabled)
+		return 0;
+
+	if (pci_is_pcie(pdev))
+		link = pcie_aspm_get_link(pdev);
+
+	if (!link)
+		return 0;
+
+	if (n)
+		return link->aspm_capable & aspm_state_map[n - 1] ? a->mode : 0;
+	else
+		return link->clkpm_capable ? a->mode : 0;
+}
+
+const struct attribute_group aspm_ctrl_attr_group = {
+	.name = "link_pm",
+	.attrs = aspm_ctrl_attrs,
+	.is_visible = aspm_ctrl_attrs_are_visible,
+};
+
 static int __init pcie_aspm_disable(char *str)
 {
 	if (!strcmp(str, "off")) {
-- 
2.23.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v7 5/5] PCI/ASPM: Remove Kconfig option PCIEASPM_DEBUG and related code
  2019-10-05 12:02 [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM Heiner Kallweit
                   ` (3 preceding siblings ...)
  2019-10-05 12:07 ` [PATCH v7 4/5] PCI/ASPM: Add sysfs attributes for controlling ASPM link states Heiner Kallweit
@ 2019-10-05 12:08 ` Heiner Kallweit
  2019-10-08 22:10 ` [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM Bjorn Helgaas
  5 siblings, 0 replies; 17+ messages in thread
From: Heiner Kallweit @ 2019-10-05 12:08 UTC (permalink / raw)
  To: Frederick Lawler, Bjorn Helgaas, Greg KH, Rajat Jain; +Cc: linux-pci

Now that we have sysfs attributes for enabling/disabling the individual
ASPM link states, this debug code isn't needed any longer. Removing this
debug code has been discussed for quite some time, see e.g. [0].

[0] https://lore.kernel.org/lkml/20180727202619.GD173328@bhelgaas-glaptop.roam.corp.google.com/

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
v6:
- add discussion link to commit message
---
 drivers/pci/pci-sysfs.c  |   3 --
 drivers/pci/pci.h        |   8 ---
 drivers/pci/pcie/Kconfig |   7 ---
 drivers/pci/pcie/aspm.c  | 105 ---------------------------------------
 4 files changed, 123 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 0e76c02e0..92bf1b1ce 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1330,7 +1330,6 @@ static int pci_create_capabilities_sysfs(struct pci_dev *dev)
 	int retval;
 
 	pcie_vpd_create_sysfs_dev_files(dev);
-	pcie_aspm_create_sysfs_dev_files(dev);
 
 	if (dev->reset_fn) {
 		retval = device_create_file(&dev->dev, &dev_attr_reset);
@@ -1340,7 +1339,6 @@ static int pci_create_capabilities_sysfs(struct pci_dev *dev)
 	return 0;
 
 error:
-	pcie_aspm_remove_sysfs_dev_files(dev);
 	pcie_vpd_remove_sysfs_dev_files(dev);
 	return retval;
 }
@@ -1416,7 +1414,6 @@ int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
 static void pci_remove_capabilities_sysfs(struct pci_dev *dev)
 {
 	pcie_vpd_remove_sysfs_dev_files(dev);
-	pcie_aspm_remove_sysfs_dev_files(dev);
 	if (dev->reset_fn) {
 		device_remove_file(&dev->dev, &dev_attr_reset);
 		dev->reset_fn = 0;
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index b2cd21e8c..ae231e3cd 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -541,14 +541,6 @@ static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) { }
 static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { }
 #endif
 
-#ifdef CONFIG_PCIEASPM_DEBUG
-void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev);
-void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev);
-#else
-static inline void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) { }
-static inline void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev) { }
-#endif
-
 #ifdef CONFIG_PCIE_ECRC
 void pcie_set_ecrc_checking(struct pci_dev *dev);
 void pcie_ecrc_get_policy(char *str);
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig
index 362eb8cfa..a2e862d4e 100644
--- a/drivers/pci/pcie/Kconfig
+++ b/drivers/pci/pcie/Kconfig
@@ -79,13 +79,6 @@ config PCIEASPM
 
 	  When in doubt, say Y.
 
-config PCIEASPM_DEBUG
-	bool "Debug PCI Express ASPM"
-	depends on PCIEASPM
-	help
-	  This enables PCI Express ASPM debug support. It will add per-device
-	  interface to control ASPM.
-
 choice
 	prompt "Default ASPM policy"
 	default PCIEASPM_DEFAULT
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 05ea02abf..896299a6b 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -1221,111 +1221,6 @@ bool pcie_aspm_enabled(struct pci_dev *pdev)
 }
 EXPORT_SYMBOL_GPL(pcie_aspm_enabled);
 
-#ifdef CONFIG_PCIEASPM_DEBUG
-static ssize_t link_state_show(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct pci_dev *pci_device = to_pci_dev(dev);
-	struct pcie_link_state *link_state = pci_device->link_state;
-
-	return sprintf(buf, "%d\n", link_state->aspm_enabled);
-}
-
-static ssize_t link_state_store(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t n)
-{
-	struct pci_dev *pdev = to_pci_dev(dev);
-	struct pcie_link_state *link, *root = pdev->link_state->root;
-	u32 state;
-
-	if (aspm_disabled)
-		return -EPERM;
-
-	if (kstrtouint(buf, 10, &state))
-		return -EINVAL;
-	if ((state & ~ASPM_STATE_ALL) != 0)
-		return -EINVAL;
-
-	down_read(&pci_bus_sem);
-	mutex_lock(&aspm_lock);
-	list_for_each_entry(link, &link_list, sibling) {
-		if (link->root != root)
-			continue;
-		pcie_config_aspm_link(link, state);
-	}
-	mutex_unlock(&aspm_lock);
-	up_read(&pci_bus_sem);
-	return n;
-}
-
-static ssize_t clk_ctl_show(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct pci_dev *pci_device = to_pci_dev(dev);
-	struct pcie_link_state *link_state = pci_device->link_state;
-
-	return sprintf(buf, "%d\n", link_state->clkpm_enabled);
-}
-
-static ssize_t clk_ctl_store(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t n)
-{
-	struct pci_dev *pdev = to_pci_dev(dev);
-	bool state;
-
-	if (strtobool(buf, &state))
-		return -EINVAL;
-
-	down_read(&pci_bus_sem);
-	mutex_lock(&aspm_lock);
-	pcie_set_clkpm_nocheck(pdev->link_state, state);
-	mutex_unlock(&aspm_lock);
-	up_read(&pci_bus_sem);
-
-	return n;
-}
-
-static DEVICE_ATTR_RW(link_state);
-static DEVICE_ATTR_RW(clk_ctl);
-
-static char power_group[] = "power";
-void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev)
-{
-	struct pcie_link_state *link_state = pdev->link_state;
-
-	if (!link_state)
-		return;
-
-	if (link_state->aspm_support)
-		sysfs_add_file_to_group(&pdev->dev.kobj,
-			&dev_attr_link_state.attr, power_group);
-	if (link_state->clkpm_capable)
-		sysfs_add_file_to_group(&pdev->dev.kobj,
-			&dev_attr_clk_ctl.attr, power_group);
-}
-
-void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev)
-{
-	struct pcie_link_state *link_state = pdev->link_state;
-
-	if (!link_state)
-		return;
-
-	if (link_state->aspm_support)
-		sysfs_remove_file_from_group(&pdev->dev.kobj,
-			&dev_attr_link_state.attr, power_group);
-	if (link_state->clkpm_capable)
-		sysfs_remove_file_from_group(&pdev->dev.kobj,
-			&dev_attr_clk_ctl.attr, power_group);
-}
-#endif
-
 static ssize_t aspm_attr_show_common(struct device *dev,
 				     struct device_attribute *attr,
 				     char *buf, u8 state)
-- 
2.23.0



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 3/5] PCI/ASPM: Add and use helper pcie_aspm_get_link
  2019-10-05 12:07 ` [PATCH v7 3/5] PCI/ASPM: Add and use helper pcie_aspm_get_link Heiner Kallweit
@ 2019-10-08  1:51   ` Bjorn Helgaas
  0 siblings, 0 replies; 17+ messages in thread
From: Bjorn Helgaas @ 2019-10-08  1:51 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: Frederick Lawler, Greg KH, Rajat Jain, linux-pci

On Sat, Oct 05, 2019 at 02:07:18PM +0200, Heiner Kallweit wrote:
> Factor out getting the link associated with a pci_dev and use this
> helper where appropriate. In addition this helper will be used
> in a subsequent patch of this series.
> 
> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
> ---
> v7:
> - add as separate patch
> ---
>  drivers/pci/pcie/aspm.c | 26 +++++++++++++++++---------
>  1 file changed, 17 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
> index 574f822bf..91cfea673 100644
> --- a/drivers/pci/pcie/aspm.c
> +++ b/drivers/pci/pcie/aspm.c
> @@ -1066,19 +1066,28 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
>  	up_read(&pci_bus_sem);
>  }
>  
> +static struct pcie_link_state *pcie_aspm_get_link(struct pci_dev *pdev)
> +{
> +	struct pci_dev *upstream;
> +
> +	if (pcie_downstream_port(pdev))
> +		upstream = pdev;

Is there a case where this is called for a downstream port?  After
this series is completely applied, the callers I see are:

  __pci_disable_link_state()
  pcie_aspm_enabled()
  aspm_attr_show_common()
  aspm_attr_store_common()
  clkpm_show()
  clkpm_store()
  aspm_ctrl_attrs_are_visible()

I'm pretty sure all of these only care about upstream ports, i.e., we
only call them for endpoints, switch upstream ports, etc.

What do you think about something like this?

  static struct pcie_link_state *pcie_aspm_get_link(struct pci_dev *pdev)
  {
    struct pci_dev *bridge;

    if (pci_is_pcie(pdev)) {
      bridge = pci_upstream_bridge(pdev);
      if (bridge && pci_is_pcie(bridge))
        return bridge->link_state;
    }

    return NULL;
  }

Then we could remove the pci_is_pcie() checks from
__pci_disable_link_state() and aspm_ctrl_attrs_are_visible().

> +	else
> +		upstream = pci_upstream_bridge(pdev);
> +
> +	return upstream ? upstream->link_state : NULL;
> +}
> +
>  static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
>  {
> -	struct pci_dev *parent = pdev->bus->self;
>  	struct pcie_link_state *link;
>  
>  	if (!pci_is_pcie(pdev))
>  		return 0;
>  
> -	if (pcie_downstream_port(pdev))
> -		parent = pdev;
> -	if (!parent || !parent->link_state)
> +	link = pcie_aspm_get_link(pdev);
> +	if (!link)
>  		return -EINVAL;
> -
>  	/*
>  	 * A driver requested that ASPM be disabled on this device, but
>  	 * if we don't have permission to manage ASPM (e.g., on ACPI
> @@ -1095,7 +1104,6 @@ static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
>  	if (sem)
>  		down_read(&pci_bus_sem);
>  	mutex_lock(&aspm_lock);
> -	link = parent->link_state;
>  	if (state & PCIE_LINK_STATE_L0S)
>  		link->aspm_disable |= ASPM_STATE_L0S;
>  	if (state & PCIE_LINK_STATE_L1)
> @@ -1188,14 +1196,14 @@ module_param_call(policy, pcie_aspm_set_policy, pcie_aspm_get_policy,
>   */
>  bool pcie_aspm_enabled(struct pci_dev *pdev)
>  {
> -	struct pci_dev *bridge = pci_upstream_bridge(pdev);
> +	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
>  	bool ret;
>  
> -	if (!bridge)
> +	if (!link)
>  		return false;
>  
>  	mutex_lock(&aspm_lock);
> -	ret = bridge->link_state ? !!bridge->link_state->aspm_enabled : false;
> +	ret = link->aspm_enabled;
>  	mutex_unlock(&aspm_lock);

I'm not sure why this mutex is needed; I cc'd you on my query to
Rafael about this.  Unrelated to your patch, of course.

>  	return ret;
> -- 
> 2.23.0
> 
> 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 4/5] PCI/ASPM: Add sysfs attributes for controlling ASPM link states
  2019-10-05 12:07 ` [PATCH v7 4/5] PCI/ASPM: Add sysfs attributes for controlling ASPM link states Heiner Kallweit
@ 2019-10-08  1:53   ` Bjorn Helgaas
  2019-11-21 20:49   ` Bjorn Helgaas
  1 sibling, 0 replies; 17+ messages in thread
From: Bjorn Helgaas @ 2019-10-08  1:53 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: Frederick Lawler, Greg KH, Rajat Jain, linux-pci

On Sat, Oct 05, 2019 at 02:07:56PM +0200, Heiner Kallweit wrote:
> Background of this extension is a problem with the r8169 network driver.
> Several combinations of board chipsets and network chip versions have
> problems if ASPM is enabled, therefore we have to disable ASPM per default.
> However especially on notebooks ASPM can provide significant power-saving,
> therefore we want to give users the option to enable ASPM. With the new
> sysfs attributes users can control which ASPM link-states are
> enabled/disabled.
> 
> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>

> +static ssize_t aspm_attr_show_common(struct device *dev,
> +				     struct device_attribute *attr,
> +				     char *buf, u8 state)
> +{
> +	struct pci_dev *pdev = to_pci_dev(dev);
> +	struct pcie_link_state *link;
> +	bool enabled;
> +
> +	link = pcie_aspm_get_link(pdev);
> +
> +	mutex_lock(&aspm_lock);
> +	enabled = link->aspm_enabled & state;
> +	mutex_unlock(&aspm_lock);

Not sure the mutex is needed; do you have a reason, or is it just
copied from existing code?  If the latter, we can just wait to see
what Rafael says.

> +	return sprintf(buf, "%d\n", enabled ? 1 : 0);
> +}

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM
  2019-10-05 12:02 [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM Heiner Kallweit
                   ` (4 preceding siblings ...)
  2019-10-05 12:08 ` [PATCH v7 5/5] PCI/ASPM: Remove Kconfig option PCIEASPM_DEBUG and related code Heiner Kallweit
@ 2019-10-08 22:10 ` Bjorn Helgaas
  2019-10-10 13:22   ` Bjorn Helgaas
  5 siblings, 1 reply; 17+ messages in thread
From: Bjorn Helgaas @ 2019-10-08 22:10 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: Frederick Lawler, Greg KH, Rajat Jain, linux-pci

On Sat, Oct 05, 2019 at 02:02:29PM +0200, Heiner Kallweit wrote:
> Background of this extension is a problem with the r8169 network driver.
> Several combinations of board chipsets and network chip versions have
> problems if ASPM is enabled, therefore we have to disable ASPM per
> default. However especially on notebooks ASPM can provide significant
> power-saving, therefore we want to give users the option to enable
> ASPM. With the new sysfs attributes users can control which ASPM
> link-states are disabled.
> 
> v2:
> - use a dedicated sysfs attribute per link state
> - allow separate control of ASPM and PCI PM L1 sub-states
> 
> v3:
> - patch 3: statically allocate the attribute group
> - patch 3: replace snprintf with printf
> - add patch 4
> 
> v4:
> - patch 3: add call to sysfs_update_group because is_visible callback
>            returns false always at file creation time
> - patch 3: simplify code a little
> 
> v5:
> - rebased to latest pci/next
> 
> v6:
> - patch 3: consider several review comments from Bjorn
> - patch 4: add discussion link to commit message
> 
> v7:
> - Move adding pcie_aspm_get_link() to separate patch 3
> - patch 4: change group name from aspm to link_pm
> - patch 4: control visibility of attributes individually
> 
> Heiner Kallweit (5):
>   PCI/ASPM: add L1 sub-state support to pci_disable_link_state
>   PCI/ASPM: allow to re-enable Clock PM
>   PCI/ASPM: Add and use helper pcie_aspm_get_link
>   PCI/ASPM: Add sysfs attributes for controlling ASPM link states
>   PCI/ASPM: Remove Kconfig option PCIEASPM_DEBUG and related code
> 
>  Documentation/ABI/testing/sysfs-bus-pci |  14 ++
>  drivers/pci/pci-sysfs.c                 |   6 +-
>  drivers/pci/pci.h                       |  12 +-
>  drivers/pci/pcie/Kconfig                |   7 -
>  drivers/pci/pcie/aspm.c                 | 252 ++++++++++++++++--------
>  include/linux/pci.h                     |  10 +-
>  6 files changed, 199 insertions(+), 102 deletions(-)

I applied these to pci/aspm for v5.5.  Thank you very much for all the
work you put into this!

There are a couple questions that are still open, but I have no
problem if we want to make minor tweaks before the merge window opens.

Bjorn

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM
  2019-10-08 22:10 ` [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM Bjorn Helgaas
@ 2019-10-10 13:22   ` Bjorn Helgaas
  2019-10-10 20:45     ` Heiner Kallweit
  0 siblings, 1 reply; 17+ messages in thread
From: Bjorn Helgaas @ 2019-10-10 13:22 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: Frederick Lawler, Greg KH, Rajat Jain, linux-pci

On Tue, Oct 08, 2019 at 05:10:40PM -0500, Bjorn Helgaas wrote:
> On Sat, Oct 05, 2019 at 02:02:29PM +0200, Heiner Kallweit wrote:
> > Background of this extension is a problem with the r8169 network driver.
> > Several combinations of board chipsets and network chip versions have
> > problems if ASPM is enabled, therefore we have to disable ASPM per
> > default. However especially on notebooks ASPM can provide significant
> > power-saving, therefore we want to give users the option to enable
> > ASPM. With the new sysfs attributes users can control which ASPM
> > link-states are disabled.
> > 
> > v2:
> > - use a dedicated sysfs attribute per link state
> > - allow separate control of ASPM and PCI PM L1 sub-states
> > 
> > v3:
> > - patch 3: statically allocate the attribute group
> > - patch 3: replace snprintf with printf
> > - add patch 4
> > 
> > v4:
> > - patch 3: add call to sysfs_update_group because is_visible callback
> >            returns false always at file creation time
> > - patch 3: simplify code a little
> > 
> > v5:
> > - rebased to latest pci/next
> > 
> > v6:
> > - patch 3: consider several review comments from Bjorn
> > - patch 4: add discussion link to commit message
> > 
> > v7:
> > - Move adding pcie_aspm_get_link() to separate patch 3
> > - patch 4: change group name from aspm to link_pm
> > - patch 4: control visibility of attributes individually
> > 
> > Heiner Kallweit (5):
> >   PCI/ASPM: add L1 sub-state support to pci_disable_link_state
> >   PCI/ASPM: allow to re-enable Clock PM
> >   PCI/ASPM: Add and use helper pcie_aspm_get_link
> >   PCI/ASPM: Add sysfs attributes for controlling ASPM link states
> >   PCI/ASPM: Remove Kconfig option PCIEASPM_DEBUG and related code
> > 
> >  Documentation/ABI/testing/sysfs-bus-pci |  14 ++
> >  drivers/pci/pci-sysfs.c                 |   6 +-
> >  drivers/pci/pci.h                       |  12 +-
> >  drivers/pci/pcie/Kconfig                |   7 -
> >  drivers/pci/pcie/aspm.c                 | 252 ++++++++++++++++--------
> >  include/linux/pci.h                     |  10 +-
> >  6 files changed, 199 insertions(+), 102 deletions(-)
> 
> I applied these to pci/aspm for v5.5.  Thank you very much for all the
> work you put into this!
> 
> There are a couple questions that are still open, but I have no
> problem if we want to make minor tweaks before the merge window opens.

To resolve these open questions, I propose the diff below, which:

  - Makes pcie_aspm_get_link() work only when called for an Upstream
    Port (Endpoint, Switch Upstream Port, or other component at the
    downstream end of a Link).  I don't think there's any caller that
    needs to supply the upstream end.

  - Makes pcie_aspm_get_link() check that both ends are PCIe devices.
    This might be overkill, but we can't rely on the PCI topology
    being "correct", e.g., we have to deal gracefully with a
    virtualization or similar scenario where a bridge is PCI and the
    child is PCIe.  In that case, we shouldn't try to manage ASPM, so
    we don't need a link_state, but I couldn't quite convince myself
    that pcie_aspm_init_link_state() handles these cases.

  - Removes the aspm_lock from the sysfs show functions.  Per the
    discussion with Rafael, I don't think it's necessary there:

      https://lore.kernel.org/r/20191007223428.GA72605@google.com

    I didn't remove it from the store functions because they do ASPM
    reconfiguration and I didn't try to figure out the locking there.

Let me know what you think about this.  If it looks right, I'll just
squash these changes into the relevant patches.

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 200ec994299d..83a169a196f5 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -1078,24 +1078,22 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
 
 static struct pcie_link_state *pcie_aspm_get_link(struct pci_dev *pdev)
 {
-	struct pci_dev *upstream;
+	struct pci_dev *bridge;
 
-	if (pcie_downstream_port(pdev))
-		upstream = pdev;
-	else
-		upstream = pci_upstream_bridge(pdev);
+	if (!pci_is_pcie(pdev))
+		return NULL;
+
+	bridge = pci_upstream_bridge(pdev);
+	if (!bridge || !pci_is_pcie(bridge))
+		return NULL;
 
-	return upstream ? upstream->link_state : NULL;
+	return bridge->link_state;
 }
 
 static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
 {
-	struct pcie_link_state *link;
-
-	if (!pci_is_pcie(pdev))
-		return 0;
+	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
 
-	link = pcie_aspm_get_link(pdev);
 	if (!link)
 		return -EINVAL;
 	/*
@@ -1225,16 +1223,9 @@ static ssize_t aspm_attr_show_common(struct device *dev,
 				     char *buf, u8 state)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
-	struct pcie_link_state *link;
-	bool enabled;
-
-	link = pcie_aspm_get_link(pdev);
-
-	mutex_lock(&aspm_lock);
-	enabled = link->aspm_enabled & state;
-	mutex_unlock(&aspm_lock);
+	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
 
-	return sprintf(buf, "%d\n", enabled ? 1 : 0);
+	return sprintf(buf, "%d\n", (link->aspm_enabled & state) ? 1 : 0);
 }
 
 static ssize_t aspm_attr_store_common(struct device *dev,
@@ -1242,11 +1233,9 @@ static ssize_t aspm_attr_store_common(struct device *dev,
 				      const char *buf, size_t len, u8 state)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
-	struct pcie_link_state *link;
+	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
 	bool state_enable;
 
-	link = pcie_aspm_get_link(pdev);
-
 	if (strtobool(buf, &state_enable) < 0)
 		return -EINVAL;
 
@@ -1291,16 +1280,9 @@ static ssize_t clkpm_show(struct device *dev,
 			  struct device_attribute *attr, char *buf)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
-	struct pcie_link_state *link;
-	int val;
-
-	link = pcie_aspm_get_link(pdev);
-
-	mutex_lock(&aspm_lock);
-	val = link->clkpm_enabled;
-	mutex_unlock(&aspm_lock);
+	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
 
-	return sprintf(buf, "%d\n", val);
+	return sprintf(buf, "%d\n", link->clkpm_enabled);
 }
 
 static ssize_t clkpm_store(struct device *dev,
@@ -1308,11 +1290,9 @@ static ssize_t clkpm_store(struct device *dev,
 			   const char *buf, size_t len)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
-	struct pcie_link_state *link;
+	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
 	bool state_enable;
 
-	link = pcie_aspm_get_link(pdev);
-
 	if (strtobool(buf, &state_enable) < 0)
 		return -EINVAL;
 
@@ -1352,7 +1332,7 @@ static umode_t aspm_ctrl_attrs_are_visible(struct kobject *kobj,
 {
 	struct device *dev = kobj_to_dev(kobj);
 	struct pci_dev *pdev = to_pci_dev(dev);
-	struct pcie_link_state *link = NULL;
+	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
 	static const u8 aspm_state_map[] = {
 		ASPM_STATE_L0S,
 		ASPM_STATE_L1,
@@ -1362,19 +1342,13 @@ static umode_t aspm_ctrl_attrs_are_visible(struct kobject *kobj,
 		ASPM_STATE_L1_2_PCIPM,
 	};
 
-	if (aspm_disabled)
-		return 0;
-
-	if (pci_is_pcie(pdev))
-		link = pcie_aspm_get_link(pdev);
-
-	if (!link)
+	if (aspm_disabled || !link)
 		return 0;
 
-	if (n)
-		return link->aspm_capable & aspm_state_map[n - 1] ? a->mode : 0;
-	else
+	if (n == 0)
 		return link->clkpm_capable ? a->mode : 0;
+
+	return link->aspm_capable & aspm_state_map[n - 1] ? a->mode : 0;
 }
 
 const struct attribute_group aspm_ctrl_attr_group = {

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM
  2019-10-10 13:22   ` Bjorn Helgaas
@ 2019-10-10 20:45     ` Heiner Kallweit
  2019-10-15 20:30       ` Bjorn Helgaas
  0 siblings, 1 reply; 17+ messages in thread
From: Heiner Kallweit @ 2019-10-10 20:45 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: Frederick Lawler, Greg KH, Rajat Jain, linux-pci

On 10.10.2019 15:22, Bjorn Helgaas wrote:
> On Tue, Oct 08, 2019 at 05:10:40PM -0500, Bjorn Helgaas wrote:
>> On Sat, Oct 05, 2019 at 02:02:29PM +0200, Heiner Kallweit wrote:
>>> Background of this extension is a problem with the r8169 network driver.
>>> Several combinations of board chipsets and network chip versions have
>>> problems if ASPM is enabled, therefore we have to disable ASPM per
>>> default. However especially on notebooks ASPM can provide significant
>>> power-saving, therefore we want to give users the option to enable
>>> ASPM. With the new sysfs attributes users can control which ASPM
>>> link-states are disabled.
>>>
>>> v2:
>>> - use a dedicated sysfs attribute per link state
>>> - allow separate control of ASPM and PCI PM L1 sub-states
>>>
>>> v3:
>>> - patch 3: statically allocate the attribute group
>>> - patch 3: replace snprintf with printf
>>> - add patch 4
>>>
>>> v4:
>>> - patch 3: add call to sysfs_update_group because is_visible callback
>>>            returns false always at file creation time
>>> - patch 3: simplify code a little
>>>
>>> v5:
>>> - rebased to latest pci/next
>>>
>>> v6:
>>> - patch 3: consider several review comments from Bjorn
>>> - patch 4: add discussion link to commit message
>>>
>>> v7:
>>> - Move adding pcie_aspm_get_link() to separate patch 3
>>> - patch 4: change group name from aspm to link_pm
>>> - patch 4: control visibility of attributes individually
>>>
>>> Heiner Kallweit (5):
>>>   PCI/ASPM: add L1 sub-state support to pci_disable_link_state
>>>   PCI/ASPM: allow to re-enable Clock PM
>>>   PCI/ASPM: Add and use helper pcie_aspm_get_link
>>>   PCI/ASPM: Add sysfs attributes for controlling ASPM link states
>>>   PCI/ASPM: Remove Kconfig option PCIEASPM_DEBUG and related code
>>>
>>>  Documentation/ABI/testing/sysfs-bus-pci |  14 ++
>>>  drivers/pci/pci-sysfs.c                 |   6 +-
>>>  drivers/pci/pci.h                       |  12 +-
>>>  drivers/pci/pcie/Kconfig                |   7 -
>>>  drivers/pci/pcie/aspm.c                 | 252 ++++++++++++++++--------
>>>  include/linux/pci.h                     |  10 +-
>>>  6 files changed, 199 insertions(+), 102 deletions(-)
>>
>> I applied these to pci/aspm for v5.5.  Thank you very much for all the
>> work you put into this!
>>
>> There are a couple questions that are still open, but I have no
>> problem if we want to make minor tweaks before the merge window opens.
> 
> To resolve these open questions, I propose the diff below, which:
> 
>   - Makes pcie_aspm_get_link() work only when called for an Upstream
>     Port (Endpoint, Switch Upstream Port, or other component at the
>     downstream end of a Link).  I don't think there's any caller that
>     needs to supply the upstream end.
> 
>   - Makes pcie_aspm_get_link() check that both ends are PCIe devices.
>     This might be overkill, but we can't rely on the PCI topology
>     being "correct", e.g., we have to deal gracefully with a
>     virtualization or similar scenario where a bridge is PCI and the
>     child is PCIe.  In that case, we shouldn't try to manage ASPM, so
>     we don't need a link_state, but I couldn't quite convince myself
>     that pcie_aspm_init_link_state() handles these cases.
> 
>   - Removes the aspm_lock from the sysfs show functions.  Per the
>     discussion with Rafael, I don't think it's necessary there:
> 
>       https://lore.kernel.org/r/20191007223428.GA72605@google.com
> 
>     I didn't remove it from the store functions because they do ASPM
>     reconfiguration and I didn't try to figure out the locking there.
> 
> Let me know what you think about this.  If it looks right, I'll just
> squash these changes into the relevant patches.
> 
Looks good to me. Thanks, Heiner

> diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
> index 200ec994299d..83a169a196f5 100644
> --- a/drivers/pci/pcie/aspm.c
> +++ b/drivers/pci/pcie/aspm.c
> @@ -1078,24 +1078,22 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
>  
>  static struct pcie_link_state *pcie_aspm_get_link(struct pci_dev *pdev)
>  {
> -	struct pci_dev *upstream;
> +	struct pci_dev *bridge;
>  
> -	if (pcie_downstream_port(pdev))
> -		upstream = pdev;
> -	else
> -		upstream = pci_upstream_bridge(pdev);
> +	if (!pci_is_pcie(pdev))
> +		return NULL;
> +
> +	bridge = pci_upstream_bridge(pdev);
> +	if (!bridge || !pci_is_pcie(bridge))
> +		return NULL;
>  
> -	return upstream ? upstream->link_state : NULL;
> +	return bridge->link_state;
>  }
>  
>  static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
>  {
> -	struct pcie_link_state *link;
> -
> -	if (!pci_is_pcie(pdev))
> -		return 0;
> +	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
>  
> -	link = pcie_aspm_get_link(pdev);
>  	if (!link)
>  		return -EINVAL;
>  	/*
> @@ -1225,16 +1223,9 @@ static ssize_t aspm_attr_show_common(struct device *dev,
>  				     char *buf, u8 state)
>  {
>  	struct pci_dev *pdev = to_pci_dev(dev);
> -	struct pcie_link_state *link;
> -	bool enabled;
> -
> -	link = pcie_aspm_get_link(pdev);
> -
> -	mutex_lock(&aspm_lock);
> -	enabled = link->aspm_enabled & state;
> -	mutex_unlock(&aspm_lock);
> +	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
>  
> -	return sprintf(buf, "%d\n", enabled ? 1 : 0);
> +	return sprintf(buf, "%d\n", (link->aspm_enabled & state) ? 1 : 0);
>  }
>  
>  static ssize_t aspm_attr_store_common(struct device *dev,
> @@ -1242,11 +1233,9 @@ static ssize_t aspm_attr_store_common(struct device *dev,
>  				      const char *buf, size_t len, u8 state)
>  {
>  	struct pci_dev *pdev = to_pci_dev(dev);
> -	struct pcie_link_state *link;
> +	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
>  	bool state_enable;
>  
> -	link = pcie_aspm_get_link(pdev);
> -
>  	if (strtobool(buf, &state_enable) < 0)
>  		return -EINVAL;
>  
> @@ -1291,16 +1280,9 @@ static ssize_t clkpm_show(struct device *dev,
>  			  struct device_attribute *attr, char *buf)
>  {
>  	struct pci_dev *pdev = to_pci_dev(dev);
> -	struct pcie_link_state *link;
> -	int val;
> -
> -	link = pcie_aspm_get_link(pdev);
> -
> -	mutex_lock(&aspm_lock);
> -	val = link->clkpm_enabled;
> -	mutex_unlock(&aspm_lock);
> +	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
>  
> -	return sprintf(buf, "%d\n", val);
> +	return sprintf(buf, "%d\n", link->clkpm_enabled);
>  }
>  
>  static ssize_t clkpm_store(struct device *dev,
> @@ -1308,11 +1290,9 @@ static ssize_t clkpm_store(struct device *dev,
>  			   const char *buf, size_t len)
>  {
>  	struct pci_dev *pdev = to_pci_dev(dev);
> -	struct pcie_link_state *link;
> +	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
>  	bool state_enable;
>  
> -	link = pcie_aspm_get_link(pdev);
> -
>  	if (strtobool(buf, &state_enable) < 0)
>  		return -EINVAL;
>  
> @@ -1352,7 +1332,7 @@ static umode_t aspm_ctrl_attrs_are_visible(struct kobject *kobj,
>  {
>  	struct device *dev = kobj_to_dev(kobj);
>  	struct pci_dev *pdev = to_pci_dev(dev);
> -	struct pcie_link_state *link = NULL;
> +	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
>  	static const u8 aspm_state_map[] = {
>  		ASPM_STATE_L0S,
>  		ASPM_STATE_L1,
> @@ -1362,19 +1342,13 @@ static umode_t aspm_ctrl_attrs_are_visible(struct kobject *kobj,
>  		ASPM_STATE_L1_2_PCIPM,
>  	};
>  
> -	if (aspm_disabled)
> -		return 0;
> -
> -	if (pci_is_pcie(pdev))
> -		link = pcie_aspm_get_link(pdev);
> -
> -	if (!link)
> +	if (aspm_disabled || !link)
>  		return 0;
>  
> -	if (n)
> -		return link->aspm_capable & aspm_state_map[n - 1] ? a->mode : 0;
> -	else
> +	if (n == 0)
>  		return link->clkpm_capable ? a->mode : 0;
> +
> +	return link->aspm_capable & aspm_state_map[n - 1] ? a->mode : 0;
>  }
>  
>  const struct attribute_group aspm_ctrl_attr_group = {
> 


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM
  2019-10-10 20:45     ` Heiner Kallweit
@ 2019-10-15 20:30       ` Bjorn Helgaas
  0 siblings, 0 replies; 17+ messages in thread
From: Bjorn Helgaas @ 2019-10-15 20:30 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: Frederick Lawler, Greg KH, Rajat Jain, linux-pci

On Thu, Oct 10, 2019 at 10:45:52PM +0200, Heiner Kallweit wrote:
> On 10.10.2019 15:22, Bjorn Helgaas wrote:
> > On Tue, Oct 08, 2019 at 05:10:40PM -0500, Bjorn Helgaas wrote:
> >> On Sat, Oct 05, 2019 at 02:02:29PM +0200, Heiner Kallweit wrote:
> >>> Background of this extension is a problem with the r8169 network driver.
> >>> Several combinations of board chipsets and network chip versions have
> >>> problems if ASPM is enabled, therefore we have to disable ASPM per
> >>> default. However especially on notebooks ASPM can provide significant
> >>> power-saving, therefore we want to give users the option to enable
> >>> ASPM. With the new sysfs attributes users can control which ASPM
> >>> link-states are disabled.
> >>>
> >>> v2:
> >>> - use a dedicated sysfs attribute per link state
> >>> - allow separate control of ASPM and PCI PM L1 sub-states
> >>>
> >>> v3:
> >>> - patch 3: statically allocate the attribute group
> >>> - patch 3: replace snprintf with printf
> >>> - add patch 4
> >>>
> >>> v4:
> >>> - patch 3: add call to sysfs_update_group because is_visible callback
> >>>            returns false always at file creation time
> >>> - patch 3: simplify code a little
> >>>
> >>> v5:
> >>> - rebased to latest pci/next
> >>>
> >>> v6:
> >>> - patch 3: consider several review comments from Bjorn
> >>> - patch 4: add discussion link to commit message
> >>>
> >>> v7:
> >>> - Move adding pcie_aspm_get_link() to separate patch 3
> >>> - patch 4: change group name from aspm to link_pm
> >>> - patch 4: control visibility of attributes individually
> >>>
> >>> Heiner Kallweit (5):
> >>>   PCI/ASPM: add L1 sub-state support to pci_disable_link_state
> >>>   PCI/ASPM: allow to re-enable Clock PM
> >>>   PCI/ASPM: Add and use helper pcie_aspm_get_link
> >>>   PCI/ASPM: Add sysfs attributes for controlling ASPM link states
> >>>   PCI/ASPM: Remove Kconfig option PCIEASPM_DEBUG and related code
> >>>
> >>>  Documentation/ABI/testing/sysfs-bus-pci |  14 ++
> >>>  drivers/pci/pci-sysfs.c                 |   6 +-
> >>>  drivers/pci/pci.h                       |  12 +-
> >>>  drivers/pci/pcie/Kconfig                |   7 -
> >>>  drivers/pci/pcie/aspm.c                 | 252 ++++++++++++++++--------
> >>>  include/linux/pci.h                     |  10 +-
> >>>  6 files changed, 199 insertions(+), 102 deletions(-)
> >>
> >> I applied these to pci/aspm for v5.5.  Thank you very much for all the
> >> work you put into this!
> >>
> >> There are a couple questions that are still open, but I have no
> >> problem if we want to make minor tweaks before the merge window opens.
> > 
> > To resolve these open questions, I propose the diff below, which:
> > 
> >   - Makes pcie_aspm_get_link() work only when called for an Upstream
> >     Port (Endpoint, Switch Upstream Port, or other component at the
> >     downstream end of a Link).  I don't think there's any caller that
> >     needs to supply the upstream end.
> > 
> >   - Makes pcie_aspm_get_link() check that both ends are PCIe devices.
> >     This might be overkill, but we can't rely on the PCI topology
> >     being "correct", e.g., we have to deal gracefully with a
> >     virtualization or similar scenario where a bridge is PCI and the
> >     child is PCIe.  In that case, we shouldn't try to manage ASPM, so
> >     we don't need a link_state, but I couldn't quite convince myself
> >     that pcie_aspm_init_link_state() handles these cases.
> > 
> >   - Removes the aspm_lock from the sysfs show functions.  Per the
> >     discussion with Rafael, I don't think it's necessary there:
> > 
> >       https://lore.kernel.org/r/20191007223428.GA72605@google.com
> > 
> >     I didn't remove it from the store functions because they do ASPM
> >     reconfiguration and I didn't try to figure out the locking there.
> > 
> > Let me know what you think about this.  If it looks right, I'll just
> > squash these changes into the relevant patches.
> > 
> Looks good to me. Thanks, Heiner

Thanks, I squashed these in and updated pci/aspm.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 4/5] PCI/ASPM: Add sysfs attributes for controlling ASPM link states
  2019-10-05 12:07 ` [PATCH v7 4/5] PCI/ASPM: Add sysfs attributes for controlling ASPM link states Heiner Kallweit
  2019-10-08  1:53   ` Bjorn Helgaas
@ 2019-11-21 20:49   ` Bjorn Helgaas
  2019-11-21 21:03     ` Rajat Jain
  1 sibling, 1 reply; 17+ messages in thread
From: Bjorn Helgaas @ 2019-11-21 20:49 UTC (permalink / raw)
  To: Heiner Kallweit
  Cc: Frederick Lawler, Greg KH, Rajat Jain, linux-pci,
	Rafael J. Wysocki, Mika Westerberg, Wong Vee Khee, Hui Chun Ong,
	Keith Busch, linux-kernel

[+cc Rafael, Mika, Wong, Hui, Rajat, Keith, LKML, original patch at [5]]

On Sat, Oct 05, 2019 at 02:07:56PM +0200, Heiner Kallweit wrote:

> +What:		/sys/bus/pci/devices/.../link_pm/clkpm
> +		/sys/bus/pci/devices/.../link_pm/l0s_aspm
> +		/sys/bus/pci/devices/.../link_pm/l1_aspm
> +		/sys/bus/pci/devices/.../link_pm/l1_1_aspm
> +		/sys/bus/pci/devices/.../link_pm/l1_2_aspm
> +		/sys/bus/pci/devices/.../link_pm/l1_1_pcipm
> +		/sys/bus/pci/devices/.../link_pm/l1_2_pcipm
> +Date:		October 2019
> +Contact:	Heiner Kallweit <hkallweit1@gmail.com>
> +Description:	If ASPM is supported for an endpoint, then these files
> +		can be used to disable or enable the individual
> +		power management states. Write y/1/on to enable,
> +		n/0/off to disable.

This is queued up for the v5.5 merge window, so if we want to tweak
anything (path names or otherwise), now is the time.

I think I might be inclined to change the directory from "link_pm" to
"link", e.g.,

  - /sys/bus/pci/devices/0000:00:1c.0/link_pm/clkpm
  + /sys/bus/pci/devices/0000:00:1c.0/link/clkpm

because there are other things that haven't been merged yet that could
go in link/ as well:

  * Mika's "link disable" control [1]
  * Dilip's link width/speed controls [2,3]

The max_link_speed, max_link_width, current_link_speed,
current_link_width files could also logically be in link/, although
they've already been merged at the top level.

Rajat's AER statistics change [4] is also coming.  Those stats aren't
link-related, so they wouldn't go in link/.  The current strawman is
an "aer_stats" directory, but I wonder if we should make a more
generic directory like "errors" that could be used for both AER and
DPC and potentially other error-related things.

For example, we could have these link-related things:

  /sys/.../0000:00:1c.0/link/clkpm            # RW ASPM stuff
  /sys/.../0000:00:1c.0/link/l0s_aspm
  /sys/.../0000:00:1c.0/link/...
  /sys/.../0000:00:1c.0/link/disable          # RW Mika
  /sys/.../0000:00:1c.0/link/speed            # RW Dilip's control
  /sys/.../0000:00:1c.0/link/width            # RW Dilip's control
  /sys/.../0000:00:1c.0/link/max_speed        # RO possible rework
  /sys/.../0000:00:1c.0/link/max_width        # RO possible rework

With these backwards compatibility symlinks:

  /sys/.../0000:00:1c.0/max_link_speed     -> link/max_speed
  /sys/.../0000:00:1c.0/current_link_speed -> link/speed

Rajat's current patch puts the AER stats here at the top level:

  /sys/.../0000:00:1c.0/aer_stats/fatal_bit4_DLP

But maybe we could push them down like this:

  /sys/.../0000:00:1c.0/errors/aer/stats/unc_04_dlp
  /sys/.../0000:00:1c.0/errors/aer/stats/unc_26_poison_tlb_blocked
  /sys/.../0000:00:1c.0/errors/aer/stats/cor_00_rx_err
  /sys/.../0000:00:1c.0/errors/aer/stats/cor_15_hdr_log_overflow

There are some AER-related things we don't have at all today that
could go here:

  /sys/.../0000:00:1c.0/errors/aer/ecrc_gen
  /sys/.../0000:00:1c.0/errors/aer/ecrc_check
  /sys/.../0000:00:1c.0/errors/aer/unc_err_status
  /sys/.../0000:00:1c.0/errors/aer/unc_err_mask
  /sys/.../0000:00:1c.0/errors/aer/unc_err_sev

And we might someday want DPC knobs like this:

  /sys/.../0000:00:1c.0/errors/dpc/status
  /sys/.../0000:00:1c.0/errors/dpc/error_source

Any thoughts?

Bjorn

[1] https://lore.kernel.org/r/20190529104942.74991-1-mika.westerberg@linux.intel.com
[2] https://lore.kernel.org/r/d8574605f8e70f41ce1e88ccfb56b63c8f85e4df.1571638827.git.eswara.kota@linux.intel.com
[3] https://lore.kernel.org/r/20191030221436.GA261632@google.com/
[4] https://lore.kernel.org/r/20190827222145.32642-2-rajatja@google.com
[5] https://lore.kernel.org/r/b1c83f8a-9bf6-eac5-82d0-cf5b90128fbf@gmail.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 4/5] PCI/ASPM: Add sysfs attributes for controlling ASPM link states
  2019-11-21 20:49   ` Bjorn Helgaas
@ 2019-11-21 21:03     ` Rajat Jain
  2019-11-21 21:10       ` Greg KH
  0 siblings, 1 reply; 17+ messages in thread
From: Rajat Jain @ 2019-11-21 21:03 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Heiner Kallweit, Frederick Lawler, Greg KH, linux-pci,
	Rafael J. Wysocki, Mika Westerberg, Wong Vee Khee, Hui Chun Ong,
	Keith Busch, Linux Kernel Mailing List

Hi,

On Thu, Nov 21, 2019 at 12:49 PM Bjorn Helgaas <helgaas@kernel.org> wrote:
>
> [+cc Rafael, Mika, Wong, Hui, Rajat, Keith, LKML, original patch at [5]]
>
> On Sat, Oct 05, 2019 at 02:07:56PM +0200, Heiner Kallweit wrote:
>
> > +What:                /sys/bus/pci/devices/.../link_pm/clkpm
> > +             /sys/bus/pci/devices/.../link_pm/l0s_aspm
> > +             /sys/bus/pci/devices/.../link_pm/l1_aspm
> > +             /sys/bus/pci/devices/.../link_pm/l1_1_aspm
> > +             /sys/bus/pci/devices/.../link_pm/l1_2_aspm
> > +             /sys/bus/pci/devices/.../link_pm/l1_1_pcipm
> > +             /sys/bus/pci/devices/.../link_pm/l1_2_pcipm
> > +Date:                October 2019
> > +Contact:     Heiner Kallweit <hkallweit1@gmail.com>
> > +Description: If ASPM is supported for an endpoint, then these files
> > +             can be used to disable or enable the individual
> > +             power management states. Write y/1/on to enable,
> > +             n/0/off to disable.
>
> This is queued up for the v5.5 merge window, so if we want to tweak
> anything (path names or otherwise), now is the time.
>
> I think I might be inclined to change the directory from "link_pm" to
> "link", e.g.,
>
>   - /sys/bus/pci/devices/0000:00:1c.0/link_pm/clkpm
>   + /sys/bus/pci/devices/0000:00:1c.0/link/clkpm
>
> because there are other things that haven't been merged yet that could
> go in link/ as well:
>
>   * Mika's "link disable" control [1]
>   * Dilip's link width/speed controls [2,3]
>
> The max_link_speed, max_link_width, current_link_speed,
> current_link_width files could also logically be in link/, although
> they've already been merged at the top level.
>
> Rajat's AER statistics change [4] is also coming.  Those stats aren't
> link-related, so they wouldn't go in link/.  The current strawman is
> an "aer_stats" directory, but I wonder if we should make a more
> generic directory like "errors" that could be used for both AER and
> DPC and potentially other error-related things.

Sorry, I haven't been able to find time for it for some time. I doubt
if I'll be able to make it to 5.6 timeframe. Nevertheless...

>
> For example, we could have these link-related things:
>
>   /sys/.../0000:00:1c.0/link/clkpm            # RW ASPM stuff
>   /sys/.../0000:00:1c.0/link/l0s_aspm
>   /sys/.../0000:00:1c.0/link/...
>   /sys/.../0000:00:1c.0/link/disable          # RW Mika
>   /sys/.../0000:00:1c.0/link/speed            # RW Dilip's control
>   /sys/.../0000:00:1c.0/link/width            # RW Dilip's control
>   /sys/.../0000:00:1c.0/link/max_speed        # RO possible rework
>   /sys/.../0000:00:1c.0/link/max_width        # RO possible rework
>
> With these backwards compatibility symlinks:
>
>   /sys/.../0000:00:1c.0/max_link_speed     -> link/max_speed
>   /sys/.../0000:00:1c.0/current_link_speed -> link/speed
>
> Rajat's current patch puts the AER stats here at the top level:
>
>   /sys/.../0000:00:1c.0/aer_stats/fatal_bit4_DLP
>
> But maybe we could push them down like this:
>
>   /sys/.../0000:00:1c.0/errors/aer/stats/unc_04_dlp
>   /sys/.../0000:00:1c.0/errors/aer/stats/unc_26_poison_tlb_blocked
>   /sys/.../0000:00:1c.0/errors/aer/stats/cor_00_rx_err
>   /sys/.../0000:00:1c.0/errors/aer/stats/cor_15_hdr_log_overflow

How do we create sub-sub-sub directories in sysfs (errors/aer/stats)?
My understanding is that we can only create 1 subdirectory by using a
"named" attribute group. If we want more hierarchy, the "errors" and
the "aer" will need to be backed up by a kobject. Doable, but just
mentioning.

Overall the proposal looks like a step in the right direction to me.

Thanks & Best Regards,

Rajat

>
> There are some AER-related things we don't have at all today that
> could go here:
>
>   /sys/.../0000:00:1c.0/errors/aer/ecrc_gen
>   /sys/.../0000:00:1c.0/errors/aer/ecrc_check
>   /sys/.../0000:00:1c.0/errors/aer/unc_err_status
>   /sys/.../0000:00:1c.0/errors/aer/unc_err_mask
>   /sys/.../0000:00:1c.0/errors/aer/unc_err_sev
>
> And we might someday want DPC knobs like this:
>
>   /sys/.../0000:00:1c.0/errors/dpc/status
>   /sys/.../0000:00:1c.0/errors/dpc/error_source
>
> Any thoughts?
>
> Bjorn
>
> [1] https://lore.kernel.org/r/20190529104942.74991-1-mika.westerberg@linux.intel.com
> [2] https://lore.kernel.org/r/d8574605f8e70f41ce1e88ccfb56b63c8f85e4df.1571638827.git.eswara.kota@linux.intel.com
> [3] https://lore.kernel.org/r/20191030221436.GA261632@google.com/
> [4] https://lore.kernel.org/r/20190827222145.32642-2-rajatja@google.com
> [5] https://lore.kernel.org/r/b1c83f8a-9bf6-eac5-82d0-cf5b90128fbf@gmail.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 4/5] PCI/ASPM: Add sysfs attributes for controlling ASPM link states
  2019-11-21 21:03     ` Rajat Jain
@ 2019-11-21 21:10       ` Greg KH
  2019-11-21 23:04         ` Bjorn Helgaas
  0 siblings, 1 reply; 17+ messages in thread
From: Greg KH @ 2019-11-21 21:10 UTC (permalink / raw)
  To: Rajat Jain
  Cc: Bjorn Helgaas, Heiner Kallweit, Frederick Lawler, linux-pci,
	Rafael J. Wysocki, Mika Westerberg, Wong Vee Khee, Hui Chun Ong,
	Keith Busch, Linux Kernel Mailing List

On Thu, Nov 21, 2019 at 01:03:06PM -0800, Rajat Jain wrote:
> Hi,
> 
> On Thu, Nov 21, 2019 at 12:49 PM Bjorn Helgaas <helgaas@kernel.org> wrote:
> >
> > [+cc Rafael, Mika, Wong, Hui, Rajat, Keith, LKML, original patch at [5]]
> >
> > On Sat, Oct 05, 2019 at 02:07:56PM +0200, Heiner Kallweit wrote:
> >
> > > +What:                /sys/bus/pci/devices/.../link_pm/clkpm
> > > +             /sys/bus/pci/devices/.../link_pm/l0s_aspm
> > > +             /sys/bus/pci/devices/.../link_pm/l1_aspm
> > > +             /sys/bus/pci/devices/.../link_pm/l1_1_aspm
> > > +             /sys/bus/pci/devices/.../link_pm/l1_2_aspm
> > > +             /sys/bus/pci/devices/.../link_pm/l1_1_pcipm
> > > +             /sys/bus/pci/devices/.../link_pm/l1_2_pcipm
> > > +Date:                October 2019
> > > +Contact:     Heiner Kallweit <hkallweit1@gmail.com>
> > > +Description: If ASPM is supported for an endpoint, then these files
> > > +             can be used to disable or enable the individual
> > > +             power management states. Write y/1/on to enable,
> > > +             n/0/off to disable.
> >
> > This is queued up for the v5.5 merge window, so if we want to tweak
> > anything (path names or otherwise), now is the time.
> >
> > I think I might be inclined to change the directory from "link_pm" to
> > "link", e.g.,
> >
> >   - /sys/bus/pci/devices/0000:00:1c.0/link_pm/clkpm
> >   + /sys/bus/pci/devices/0000:00:1c.0/link/clkpm
> >
> > because there are other things that haven't been merged yet that could
> > go in link/ as well:
> >
> >   * Mika's "link disable" control [1]
> >   * Dilip's link width/speed controls [2,3]
> >
> > The max_link_speed, max_link_width, current_link_speed,
> > current_link_width files could also logically be in link/, although
> > they've already been merged at the top level.
> >
> > Rajat's AER statistics change [4] is also coming.  Those stats aren't
> > link-related, so they wouldn't go in link/.  The current strawman is
> > an "aer_stats" directory, but I wonder if we should make a more
> > generic directory like "errors" that could be used for both AER and
> > DPC and potentially other error-related things.
> 
> Sorry, I haven't been able to find time for it for some time. I doubt
> if I'll be able to make it to 5.6 timeframe. Nevertheless...
> 
> >
> > For example, we could have these link-related things:
> >
> >   /sys/.../0000:00:1c.0/link/clkpm            # RW ASPM stuff
> >   /sys/.../0000:00:1c.0/link/l0s_aspm
> >   /sys/.../0000:00:1c.0/link/...
> >   /sys/.../0000:00:1c.0/link/disable          # RW Mika
> >   /sys/.../0000:00:1c.0/link/speed            # RW Dilip's control
> >   /sys/.../0000:00:1c.0/link/width            # RW Dilip's control
> >   /sys/.../0000:00:1c.0/link/max_speed        # RO possible rework
> >   /sys/.../0000:00:1c.0/link/max_width        # RO possible rework
> >
> > With these backwards compatibility symlinks:
> >
> >   /sys/.../0000:00:1c.0/max_link_speed     -> link/max_speed
> >   /sys/.../0000:00:1c.0/current_link_speed -> link/speed
> >
> > Rajat's current patch puts the AER stats here at the top level:
> >
> >   /sys/.../0000:00:1c.0/aer_stats/fatal_bit4_DLP
> >
> > But maybe we could push them down like this:
> >
> >   /sys/.../0000:00:1c.0/errors/aer/stats/unc_04_dlp
> >   /sys/.../0000:00:1c.0/errors/aer/stats/unc_26_poison_tlb_blocked
> >   /sys/.../0000:00:1c.0/errors/aer/stats/cor_00_rx_err
> >   /sys/.../0000:00:1c.0/errors/aer/stats/cor_15_hdr_log_overflow
> 
> How do we create sub-sub-sub directories in sysfs (errors/aer/stats)?

You should not.

> My understanding is that we can only create 1 subdirectory by using a
> "named" attribute group. If we want more hierarchy, the "errors" and
> the "aer" will need to be backed up by a kobject. Doable, but just
> mentioning.

Not doable, you break userspace tools as they will not "see" those
directories or attributes.

Keep it only 1 deep if at all possible please.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 4/5] PCI/ASPM: Add sysfs attributes for controlling ASPM link states
  2019-11-21 21:10       ` Greg KH
@ 2019-11-21 23:04         ` Bjorn Helgaas
  2019-11-24 17:02           ` Greg KH
  0 siblings, 1 reply; 17+ messages in thread
From: Bjorn Helgaas @ 2019-11-21 23:04 UTC (permalink / raw)
  To: Greg KH
  Cc: Rajat Jain, Heiner Kallweit, Frederick Lawler, linux-pci,
	Rafael J. Wysocki, Mika Westerberg, Keith Busch,
	Linux Kernel Mailing List

[-cc Wong, Hui]

On Thu, Nov 21, 2019 at 10:10:17PM +0100, Greg KH wrote:
> On Thu, Nov 21, 2019 at 01:03:06PM -0800, Rajat Jain wrote:
> > On Thu, Nov 21, 2019 at 12:49 PM Bjorn Helgaas <helgaas@kernel.org> wrote:
> > > On Sat, Oct 05, 2019 at 02:07:56PM +0200, Heiner Kallweit wrote:
> > >
> > > > +What:                /sys/bus/pci/devices/.../link_pm/clkpm
> > > > +             /sys/bus/pci/devices/.../link_pm/l0s_aspm
> > > > +             /sys/bus/pci/devices/.../link_pm/l1_aspm
> > > > +             /sys/bus/pci/devices/.../link_pm/l1_1_aspm
> > > > +             /sys/bus/pci/devices/.../link_pm/l1_2_aspm
> > > > +             /sys/bus/pci/devices/.../link_pm/l1_1_pcipm
> > > > +             /sys/bus/pci/devices/.../link_pm/l1_2_pcipm
> > > > +Date:                October 2019
> > > > +Contact:     Heiner Kallweit <hkallweit1@gmail.com>
> > > > +Description: If ASPM is supported for an endpoint, then these files
> > > > +             can be used to disable or enable the individual
> > > > +             power management states. Write y/1/on to enable,
> > > > +             n/0/off to disable.
> > >
> > > This is queued up for the v5.5 merge window, so if we want to tweak
> > > anything (path names or otherwise), now is the time.
> > >
> > > I think I might be inclined to change the directory from "link_pm" to
> > > "link", e.g.,
> > >
> > >   - /sys/bus/pci/devices/0000:00:1c.0/link_pm/clkpm
> > >   + /sys/bus/pci/devices/0000:00:1c.0/link/clkpm
> > >
> > > because there are other things that haven't been merged yet that could
> > > go in link/ as well:
> > >
> > >   * Mika's "link disable" control [1]
> > >   * Dilip's link width/speed controls [2,3]
> > >
> > > The max_link_speed, max_link_width, current_link_speed,
> > > current_link_width files could also logically be in link/, although
> > > they've already been merged at the top level.
> > >
> > > Rajat's AER statistics change [4] is also coming.  Those stats aren't
> > > link-related, so they wouldn't go in link/.  The current strawman is
> > > an "aer_stats" directory, but I wonder if we should make a more
> > > generic directory like "errors" that could be used for both AER and
> > > DPC and potentially other error-related things.
> > 
> > Sorry, I haven't been able to find time for it for some time. I doubt
> > if I'll be able to make it to 5.6 timeframe. Nevertheless...
> > 
> > > For example, we could have these link-related things:
> > >
> > >   /sys/.../0000:00:1c.0/link/clkpm            # RW ASPM stuff
> > >   /sys/.../0000:00:1c.0/link/l0s_aspm
> > >   /sys/.../0000:00:1c.0/link/...
> > >   /sys/.../0000:00:1c.0/link/disable          # RW Mika
> > >   /sys/.../0000:00:1c.0/link/speed            # RW Dilip's control
> > >   /sys/.../0000:00:1c.0/link/width            # RW Dilip's control
> > >   /sys/.../0000:00:1c.0/link/max_speed        # RO possible rework
> > >   /sys/.../0000:00:1c.0/link/max_width        # RO possible rework
> > >
> > > With these backwards compatibility symlinks:
> > >
> > >   /sys/.../0000:00:1c.0/max_link_speed     -> link/max_speed
> > >   /sys/.../0000:00:1c.0/current_link_speed -> link/speed
> > >
> > > Rajat's current patch puts the AER stats here at the top level:
> > >
> > >   /sys/.../0000:00:1c.0/aer_stats/fatal_bit4_DLP
> > >
> > > But maybe we could push them down like this:
> > >
> > >   /sys/.../0000:00:1c.0/errors/aer/stats/unc_04_dlp
> > >   /sys/.../0000:00:1c.0/errors/aer/stats/unc_26_poison_tlb_blocked
> > >   /sys/.../0000:00:1c.0/errors/aer/stats/cor_00_rx_err
> > >   /sys/.../0000:00:1c.0/errors/aer/stats/cor_15_hdr_log_overflow
> > 
> > How do we create sub-sub-sub directories in sysfs (errors/aer/stats)?
> 
> You should not.
> 
> > My understanding is that we can only create 1 subdirectory by using a
> > "named" attribute group. If we want more hierarchy, the "errors" and
> > the "aer" will need to be backed up by a kobject. Doable, but just
> > mentioning.
> 
> Not doable, you break userspace tools as they will not "see" those
> directories or attributes.
>
> Keep it only 1 deep if at all possible please.

Oh, that's good to know, thanks!  I guess we'll have to think more
about the error stuff.

What sort of tools would this break?  There are no AER tools since the
AER stats sysfs files don't exist yet, so I assume there are some
generic sysfs tools or libraries.

Incidentally,
https://www.kernel.org/doc/html/latest/admin-guide/sysfs-rules.html
suggests that maybe we should be documenting these files with
/sys/devices paths instead of the symlinks in /sys/bus/pci/devices/,
e.g.,

  diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci
  -What:		/sys/bus/pci/devices/.../msi_bus
  -What:		/sys/bus/pci/devices/.../msi_irqs/
  -What:		/sys/bus/pci/devices/.../msi_irqs/<N>
  +What:		/sys/devices/pci*/.../msi_bus
  +What:		/sys/devices/pci*/.../msi_irqs/
  +What:		/sys/devices/pci*/.../msi_irqs/<N>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 4/5] PCI/ASPM: Add sysfs attributes for controlling ASPM link states
  2019-11-21 23:04         ` Bjorn Helgaas
@ 2019-11-24 17:02           ` Greg KH
  0 siblings, 0 replies; 17+ messages in thread
From: Greg KH @ 2019-11-24 17:02 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Rajat Jain, Heiner Kallweit, Frederick Lawler, linux-pci,
	Rafael J. Wysocki, Mika Westerberg, Keith Busch,
	Linux Kernel Mailing List

On Thu, Nov 21, 2019 at 05:04:11PM -0600, Bjorn Helgaas wrote:
> What sort of tools would this break?  There are no AER tools since the
> AER stats sysfs files don't exist yet, so I assume there are some
> generic sysfs tools or libraries.

Any normal tool that looks at sysfs attributes, like udev and friends.
They will "miss" the uevent for the subdirs and not know how to
associate anything with the "parent" struct device.

> Incidentally,
> https://www.kernel.org/doc/html/latest/admin-guide/sysfs-rules.html
> suggests that maybe we should be documenting these files with
> /sys/devices paths instead of the symlinks in /sys/bus/pci/devices/,
> e.g.,
> 
>   diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci
>   -What:		/sys/bus/pci/devices/.../msi_bus
>   -What:		/sys/bus/pci/devices/.../msi_irqs/
>   -What:		/sys/bus/pci/devices/.../msi_irqs/<N>
>   +What:		/sys/devices/pci*/.../msi_bus
>   +What:		/sys/devices/pci*/.../msi_irqs/
>   +What:		/sys/devices/pci*/.../msi_irqs/<N>

Either is fine, but yes, the second one is nicer.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2019-11-24 17:02 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-05 12:02 [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM Heiner Kallweit
2019-10-05 12:03 ` [PATCH v7 2/5] PCI/ASPM: Allow to re-enable Clock PM Heiner Kallweit
2019-10-05 12:04 ` [PATCH v7 1/5] PCI/ASPM: Add L1 sub-state support to pci_disable_link_state Heiner Kallweit
2019-10-05 12:07 ` [PATCH v7 3/5] PCI/ASPM: Add and use helper pcie_aspm_get_link Heiner Kallweit
2019-10-08  1:51   ` Bjorn Helgaas
2019-10-05 12:07 ` [PATCH v7 4/5] PCI/ASPM: Add sysfs attributes for controlling ASPM link states Heiner Kallweit
2019-10-08  1:53   ` Bjorn Helgaas
2019-11-21 20:49   ` Bjorn Helgaas
2019-11-21 21:03     ` Rajat Jain
2019-11-21 21:10       ` Greg KH
2019-11-21 23:04         ` Bjorn Helgaas
2019-11-24 17:02           ` Greg KH
2019-10-05 12:08 ` [PATCH v7 5/5] PCI/ASPM: Remove Kconfig option PCIEASPM_DEBUG and related code Heiner Kallweit
2019-10-08 22:10 ` [PATCH v7 0/5] PCI/ASPM: Add sysfs attributes for controlling ASPM Bjorn Helgaas
2019-10-10 13:22   ` Bjorn Helgaas
2019-10-10 20:45     ` Heiner Kallweit
2019-10-15 20:30       ` Bjorn Helgaas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).