linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v1 0/6] Remove struct pcie_link_state.aspm_*
@ 2021-11-06 17:53 Saheed O. Bolarinwa
  2021-11-06 17:53 ` [RFC PATCH v1 1/6] PCI/ASPM: Extract out L1SS_CAP calculations Saheed O. Bolarinwa
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Saheed O. Bolarinwa @ 2021-11-06 17:53 UTC (permalink / raw)
  To: helgaas; +Cc: Saheed O. Bolarinwa, linux-pci, linux-kernel

aspm_{enable, support} in struct pcie_link_state do not need to be
stored. This series removes them and creates functions to calculate
them.

MERGE NOTICE:
These series are based on
»       'commit e4e737bb5c17 ("Linux 5.15-rc2")'


Saheed O. Bolarinwa (6):
  PCI/ASPM: Extract out L1SS_CAP calculations
  PCI/ASPM: Extract the calculation of link->aspm_support
  PCI/ASPM: Extract the calculation of link->aspm_enabled
  PCI/ASPM: Don't cache struct pcie_link_state->aspm_support
  PCI/ASPM: Move pcie_aspm_sanity_check() upwards
  PCI/ASPM: Don't cache struct pcie_link_state->aspm_enabled

 drivers/pci/pcie/aspm.c | 291 +++++++++++++++++++++++-----------------
 1 file changed, 170 insertions(+), 121 deletions(-)

-- 
2.20.1


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

* [RFC PATCH v1 1/6] PCI/ASPM: Extract out L1SS_CAP calculations
  2021-11-06 17:53 [RFC PATCH v1 0/6] Remove struct pcie_link_state.aspm_* Saheed O. Bolarinwa
@ 2021-11-06 17:53 ` Saheed O. Bolarinwa
  2021-11-06 17:53 ` [RFC PATCH v1 2/6] PCI/ASPM: Extract the calculation of link->aspm_support Saheed O. Bolarinwa
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Saheed O. Bolarinwa @ 2021-11-06 17:53 UTC (permalink / raw)
  To: helgaas; +Cc: Saheed O. Bolarinwa, linux-pci, linux-kernel

Inside pcie_aspm_cap_init() the L1SS_CAP of both ends of the link is
calculated. The values are used to calculate link->aspm_support and
link->aspm_enabled. Isolating this calcution with simplify
pcie_aspm_cap_init().

Extract the calculations of L1SS_CAP on both ends into
aspm_calc_both_l1ss_caps().

Signed-off-by: Saheed O. Bolarinwa <refactormyself@gmail.com>
---
 drivers/pci/pcie/aspm.c | 42 ++++++++++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 013a47f587ce..057c6768fb7b 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -540,6 +540,30 @@ static void aspm_calc_l1ss_info(struct pcie_link_state *link,
 	}
 }
 
+static void aspm_calc_both_l1ss_caps(struct pcie_link_state *link,
+				    u32 *up_l1ss_cap, u32 *dwn_l1ss_cap)
+{
+	struct pci_dev *child = link->downstream, *parent = link->pdev;
+
+	pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CAP,
+			      up_l1ss_cap);
+	pci_read_config_dword(child, child->l1ss + PCI_L1SS_CAP,
+			      dwn_l1ss_cap);
+
+	if (!(*up_l1ss_cap & PCI_L1SS_CAP_L1_PM_SS))
+		*up_l1ss_cap = 0;
+	if (!(*dwn_l1ss_cap & PCI_L1SS_CAP_L1_PM_SS))
+		*dwn_l1ss_cap = 0;
+
+	/*
+	 * If we don't have LTR for the entire path from the Root Complex
+	 * to this device, we can't use ASPM L1.2 because it relies on the
+	 * LTR_L1.2_THRESHOLD.  See PCIe r4.0, secs 5.5.4, 6.18.
+	 */
+	if (!child->ltr_path)
+		*dwn_l1ss_cap &= ~PCI_L1SS_CAP_ASPM_L1_2;
+}
+
 static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 {
 	struct pci_dev *child = link->downstream, *parent = link->pdev;
@@ -606,23 +630,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 	link->latency_dw.l1 = calc_l1_latency(child_lnkcap);
 
 	/* Setup L1 substate */
-	pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CAP,
-			      &parent_l1ss_cap);
-	pci_read_config_dword(child, child->l1ss + PCI_L1SS_CAP,
-			      &child_l1ss_cap);
-
-	if (!(parent_l1ss_cap & PCI_L1SS_CAP_L1_PM_SS))
-		parent_l1ss_cap = 0;
-	if (!(child_l1ss_cap & PCI_L1SS_CAP_L1_PM_SS))
-		child_l1ss_cap = 0;
-
-	/*
-	 * If we don't have LTR for the entire path from the Root Complex
-	 * to this device, we can't use ASPM L1.2 because it relies on the
-	 * LTR_L1.2_THRESHOLD.  See PCIe r4.0, secs 5.5.4, 6.18.
-	 */
-	if (!child->ltr_path)
-		child_l1ss_cap &= ~PCI_L1SS_CAP_ASPM_L1_2;
+	aspm_calc_both_l1ss_caps(link, &parent_l1ss_cap, &child_l1ss_cap);
 
 	if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_ASPM_L1_1)
 		link->aspm_support |= ASPM_STATE_L1_1;
-- 
2.20.1


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

* [RFC PATCH v1 2/6] PCI/ASPM: Extract the calculation of link->aspm_support
  2021-11-06 17:53 [RFC PATCH v1 0/6] Remove struct pcie_link_state.aspm_* Saheed O. Bolarinwa
  2021-11-06 17:53 ` [RFC PATCH v1 1/6] PCI/ASPM: Extract out L1SS_CAP calculations Saheed O. Bolarinwa
@ 2021-11-06 17:53 ` Saheed O. Bolarinwa
  2021-11-06 17:53 ` [RFC PATCH v1 3/6] PCI/ASPM: Extract the calculation of link->aspm_enabled Saheed O. Bolarinwa
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Saheed O. Bolarinwa @ 2021-11-06 17:53 UTC (permalink / raw)
  To: helgaas; +Cc: Saheed O. Bolarinwa, linux-pci, linux-kernel

struct pcie_link_state->aspm_support hold the initial capable
state of the link. This value is calculated inside
pcie_aspm_init_cap(). Isolating this calculation will simplify
pcie_aspm_init_cap().

Extract the calculation of link->aspm_support into
aspm_calc_init_linkcap().

Signed-off-by: Saheed O. Bolarinwa <refactormyself@gmail.com>
---
 drivers/pci/pcie/aspm.c | 60 ++++++++++++++++++++++++-----------------
 1 file changed, 35 insertions(+), 25 deletions(-)

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 057c6768fb7b..23441a32f604 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -564,6 +564,33 @@ static void aspm_calc_both_l1ss_caps(struct pcie_link_state *link,
 		*dwn_l1ss_cap &= ~PCI_L1SS_CAP_ASPM_L1_2;
 }
 
+static u32 aspm_calc_init_linkcap(u32 up_lnkcap, u32 dwn_lnkcap,
+				  u32 up_l1ss_cap, u32 dwn_l1ss_cap)
+{
+	u32 link_cap = 0;
+
+	/*
+	 * Note that we must not enable L0s in either direction on a
+	 * given link unless components on both sides of the link each
+	 * support L0s.
+	 */
+	if (up_lnkcap & dwn_lnkcap & PCI_EXP_LNKCAP_ASPM_L0S)
+		link_cap |= ASPM_STATE_L0S;
+
+	if (up_lnkcap & dwn_lnkcap & PCI_EXP_LNKCAP_ASPM_L1)
+		link_cap |= ASPM_STATE_L1;
+	if (up_l1ss_cap & dwn_l1ss_cap & PCI_L1SS_CAP_ASPM_L1_1)
+		link_cap |= ASPM_STATE_L1_1;
+	if (up_l1ss_cap & dwn_l1ss_cap & PCI_L1SS_CAP_ASPM_L1_2)
+		link_cap |= ASPM_STATE_L1_2;
+	if (up_l1ss_cap & dwn_l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_1)
+		link_cap |= ASPM_STATE_L1_1_PCIPM;
+	if (up_l1ss_cap & dwn_l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_2)
+		link_cap |= ASPM_STATE_L1_2_PCIPM;
+
+	return link_cap;
+}
+
 static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 {
 	struct pci_dev *child = link->downstream, *parent = link->pdev;
@@ -603,16 +630,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 	pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &parent_lnkctl);
 	pcie_capability_read_word(child, PCI_EXP_LNKCTL, &child_lnkctl);
 
-	/*
-	 * Setup L0s state
-	 *
-	 * Note that we must not enable L0s in either direction on a
-	 * given link unless components on both sides of the link each
-	 * support L0s.
-	 */
-	if (parent_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPM_L0S)
-		link->aspm_support |= ASPM_STATE_L0S;
-
+	/* Setup L0s state */
 	if (child_lnkctl & PCI_EXP_LNKCTL_ASPM_L0S)
 		link->aspm_enabled |= ASPM_STATE_L0S_UP;
 	if (parent_lnkctl & PCI_EXP_LNKCTL_ASPM_L0S)
@@ -621,9 +639,6 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 	link->latency_dw.l0s = calc_l0s_latency(child_lnkcap);
 
 	/* Setup L1 state */
-	if (parent_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPM_L1)
-		link->aspm_support |= ASPM_STATE_L1;
-
 	if (parent_lnkctl & child_lnkctl & PCI_EXP_LNKCTL_ASPM_L1)
 		link->aspm_enabled |= ASPM_STATE_L1;
 	link->latency_up.l1 = calc_l1_latency(parent_lnkcap);
@@ -632,15 +647,6 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 	/* Setup L1 substate */
 	aspm_calc_both_l1ss_caps(link, &parent_l1ss_cap, &child_l1ss_cap);
 
-	if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_ASPM_L1_1)
-		link->aspm_support |= ASPM_STATE_L1_1;
-	if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_ASPM_L1_2)
-		link->aspm_support |= ASPM_STATE_L1_2;
-	if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_1)
-		link->aspm_support |= ASPM_STATE_L1_1_PCIPM;
-	if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_2)
-		link->aspm_support |= ASPM_STATE_L1_2_PCIPM;
-
 	if (parent_l1ss_cap)
 		pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
 				      &parent_l1ss_ctl1);
@@ -657,12 +663,16 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 	if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_2)
 		link->aspm_enabled |= ASPM_STATE_L1_2_PCIPM;
 
-	if (link->aspm_support & ASPM_STATE_L1SS)
-		aspm_calc_l1ss_info(link, parent_l1ss_cap, child_l1ss_cap);
-
 	/* Save default state */
 	link->aspm_default = link->aspm_enabled;
 
+	link->aspm_support = aspm_calc_init_linkcap(parent_lnkcap,
+						    child_lnkcap,
+						    parent_l1ss_cap,
+						    child_l1ss_cap);
+	if (link->aspm_support & ASPM_STATE_L1SS)
+		aspm_calc_l1ss_info(link, parent_l1ss_cap, child_l1ss_cap);
+
 	/* Setup initial capable state. Will be updated later */
 	link->aspm_capable = link->aspm_support;
 
-- 
2.20.1


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

* [RFC PATCH v1 3/6] PCI/ASPM: Extract the calculation of link->aspm_enabled
  2021-11-06 17:53 [RFC PATCH v1 0/6] Remove struct pcie_link_state.aspm_* Saheed O. Bolarinwa
  2021-11-06 17:53 ` [RFC PATCH v1 1/6] PCI/ASPM: Extract out L1SS_CAP calculations Saheed O. Bolarinwa
  2021-11-06 17:53 ` [RFC PATCH v1 2/6] PCI/ASPM: Extract the calculation of link->aspm_support Saheed O. Bolarinwa
@ 2021-11-06 17:53 ` Saheed O. Bolarinwa
  2021-11-06 17:53 ` [RFC PATCH v1 4/6] PCI/ASPM: Don't cache struct pcie_link_state->aspm_support Saheed O. Bolarinwa
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Saheed O. Bolarinwa @ 2021-11-06 17:53 UTC (permalink / raw)
  To: helgaas; +Cc: Saheed O. Bolarinwa, linux-pci, linux-kernel

Inside pcie_aspm_init_cap() the initial enabled state is read
from the firmware and calculated. It is stored in
struct pcie_link_state->aspm_enabled and also backed up in
struct pcie_link_state->aspm_default. pcie_aspm_init_cap() can
be simplified by isolation this calculation.

Extract the calculation of struct pcie_link_state->aspm_enabled
into aspm_calc_enabled_states().

Signed-off-by: Saheed O. Bolarinwa <refactormyself@gmail.com>
---
 drivers/pci/pcie/aspm.c | 66 ++++++++++++++++++++++++-----------------
 1 file changed, 38 insertions(+), 28 deletions(-)

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 23441a32f604..5e8613cb5db6 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -591,13 +591,47 @@ static u32 aspm_calc_init_linkcap(u32 up_lnkcap, u32 dwn_lnkcap,
 	return link_cap;
 }
 
+static u32 aspm_calc_enabled_states(struct pcie_link_state *link,
+				    u32 up_l1ss_cap, u32 dwn_l1ss_cap)
+{
+	struct pci_dev *child = link->downstream, *parent = link->pdev;
+	u16 parent_lnkctl, child_lnkctl;
+	u32 aspm_enabled = 0, parent_l1ss_ctl1 = 0, child_l1ss_ctl1 = 0;
+
+	pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &parent_lnkctl);
+	pcie_capability_read_word(child, PCI_EXP_LNKCTL, &child_lnkctl);
+
+	if (child_lnkctl & PCI_EXP_LNKCTL_ASPM_L0S)
+		aspm_enabled |= ASPM_STATE_L0S_UP;
+	if (parent_lnkctl & PCI_EXP_LNKCTL_ASPM_L0S)
+		aspm_enabled |= ASPM_STATE_L0S_DW;
+	if (parent_lnkctl & child_lnkctl & PCI_EXP_LNKCTL_ASPM_L1)
+		aspm_enabled |= ASPM_STATE_L1;
+
+	if (up_l1ss_cap)
+		pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
+				      &parent_l1ss_ctl1);
+	if (dwn_l1ss_cap)
+		pci_read_config_dword(child, child->l1ss + PCI_L1SS_CTL1,
+				      &child_l1ss_ctl1);
+
+	if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_1)
+		aspm_enabled |= ASPM_STATE_L1_1;
+	if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_2)
+		aspm_enabled |= ASPM_STATE_L1_2;
+	if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_1)
+		aspm_enabled |= ASPM_STATE_L1_1_PCIPM;
+	if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_2)
+		aspm_enabled |= ASPM_STATE_L1_2_PCIPM;
+
+	return aspm_enabled;
+}
+
 static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 {
 	struct pci_dev *child = link->downstream, *parent = link->pdev;
 	u32 parent_lnkcap, child_lnkcap;
-	u16 parent_lnkctl, child_lnkctl;
 	u32 parent_l1ss_cap, child_l1ss_cap;
-	u32 parent_l1ss_ctl1 = 0, child_l1ss_ctl1 = 0;
 	struct pci_bus *linkbus = parent->subordinate;
 
 	if (blacklist) {
@@ -627,41 +661,17 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 	 */
 	pcie_capability_read_dword(parent, PCI_EXP_LNKCAP, &parent_lnkcap);
 	pcie_capability_read_dword(child, PCI_EXP_LNKCAP, &child_lnkcap);
-	pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &parent_lnkctl);
-	pcie_capability_read_word(child, PCI_EXP_LNKCTL, &child_lnkctl);
 
-	/* Setup L0s state */
-	if (child_lnkctl & PCI_EXP_LNKCTL_ASPM_L0S)
-		link->aspm_enabled |= ASPM_STATE_L0S_UP;
-	if (parent_lnkctl & PCI_EXP_LNKCTL_ASPM_L0S)
-		link->aspm_enabled |= ASPM_STATE_L0S_DW;
 	link->latency_up.l0s = calc_l0s_latency(parent_lnkcap);
 	link->latency_dw.l0s = calc_l0s_latency(child_lnkcap);
-
-	/* Setup L1 state */
-	if (parent_lnkctl & child_lnkctl & PCI_EXP_LNKCTL_ASPM_L1)
-		link->aspm_enabled |= ASPM_STATE_L1;
 	link->latency_up.l1 = calc_l1_latency(parent_lnkcap);
 	link->latency_dw.l1 = calc_l1_latency(child_lnkcap);
 
 	/* Setup L1 substate */
 	aspm_calc_both_l1ss_caps(link, &parent_l1ss_cap, &child_l1ss_cap);
 
-	if (parent_l1ss_cap)
-		pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
-				      &parent_l1ss_ctl1);
-	if (child_l1ss_cap)
-		pci_read_config_dword(child, child->l1ss + PCI_L1SS_CTL1,
-				      &child_l1ss_ctl1);
-
-	if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_1)
-		link->aspm_enabled |= ASPM_STATE_L1_1;
-	if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_2)
-		link->aspm_enabled |= ASPM_STATE_L1_2;
-	if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_1)
-		link->aspm_enabled |= ASPM_STATE_L1_1_PCIPM;
-	if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_2)
-		link->aspm_enabled |= ASPM_STATE_L1_2_PCIPM;
+	link->aspm_enabled = aspm_calc_enabled_states(link, parent_l1ss_cap,
+						      child_l1ss_cap);
 
 	/* Save default state */
 	link->aspm_default = link->aspm_enabled;
-- 
2.20.1


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

* [RFC PATCH v1 4/6] PCI/ASPM: Don't cache struct pcie_link_state->aspm_support
  2021-11-06 17:53 [RFC PATCH v1 0/6] Remove struct pcie_link_state.aspm_* Saheed O. Bolarinwa
                   ` (2 preceding siblings ...)
  2021-11-06 17:53 ` [RFC PATCH v1 3/6] PCI/ASPM: Extract the calculation of link->aspm_enabled Saheed O. Bolarinwa
@ 2021-11-06 17:53 ` Saheed O. Bolarinwa
  2021-11-06 17:53 ` [RFC PATCH v1 5/6] PCI/ASPM: Move pcie_aspm_sanity_check() upwards Saheed O. Bolarinwa
  2021-11-06 17:53 ` [RFC PATCH v1 6/6] PCI/ASPM: Don't cache struct pcie_link_state->aspm_enabled Saheed O. Bolarinwa
  5 siblings, 0 replies; 7+ messages in thread
From: Saheed O. Bolarinwa @ 2021-11-06 17:53 UTC (permalink / raw)
  To: helgaas; +Cc: Saheed O. Bolarinwa, linux-pci, linux-kernel

aspm_support in struct pcie_link_state is used to cache the
initial supported ASPM capabilty states as calculated within
aspm_calc_init_linkcap(). This value can be accessed directly
by calling aspm_calc_init_linkcap().

- Remove aspm_support from struct pcie_link_state;
- Create a wrapper function for aspm_calc_init_linkcap()
- Call the wrapper function outside pcie_aspm_cap_init()
- Within pcie_aspm_cap_init() use a local variable to replace
  struct pcie_link_state->aspm_support.

Signed-off-by: Saheed O. Bolarinwa <refactormyself@gmail.com>
---
 drivers/pci/pcie/aspm.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 5e8613cb5db6..9aaae476ea31 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -54,7 +54,6 @@ struct pcie_link_state {
 	struct list_head sibling;	/* node in link_list */
 
 	/* ASPM state */
-	u32 aspm_support:7;		/* Supported ASPM state */
 	u32 aspm_enabled:7;		/* Enabled ASPM state */
 	u32 aspm_capable:7;		/* Capable ASPM state with latency */
 	u32 aspm_default:7;		/* Default ASPM state by BIOS */
@@ -450,7 +449,8 @@ static void pci_clear_and_set_dword(struct pci_dev *pdev, int pos,
 
 /* Calculate L1.2 PM substate timing parameters */
 static void aspm_calc_l1ss_info(struct pcie_link_state *link,
-				u32 parent_l1ss_cap, u32 child_l1ss_cap)
+				u32 aspm_support, u32 parent_l1ss_cap,
+				u32 child_l1ss_cap)
 {
 	struct pci_dev *child = link->downstream, *parent = link->pdev;
 	u32 val1, val2, scale1, scale2;
@@ -459,7 +459,7 @@ static void aspm_calc_l1ss_info(struct pcie_link_state *link,
 	u32 pctl1, pctl2, cctl1, cctl2;
 	u32 pl1_2_enables, cl1_2_enables;
 
-	if (!(link->aspm_support & ASPM_STATE_L1_2_MASK))
+	if (!(aspm_support & ASPM_STATE_L1_2_MASK))
 		return;
 
 	/* Choose the greater of the two Port Common_Mode_Restore_Times */
@@ -591,6 +591,20 @@ static u32 aspm_calc_init_linkcap(u32 up_lnkcap, u32 dwn_lnkcap,
 	return link_cap;
 }
 
+static u32 aspm_get_init_cap(struct pcie_link_state *link)
+{
+	struct pci_dev *child = link->downstream, *parent = link->pdev;
+	u32 parent_lnkcap, child_lnkcap;
+	u32 parent_l1ss_cap, child_l1ss_cap;
+
+	pcie_capability_read_dword(parent, PCI_EXP_LNKCAP, &parent_lnkcap);
+	pcie_capability_read_dword(child, PCI_EXP_LNKCAP, &child_lnkcap);
+	aspm_calc_both_l1ss_caps(link, &parent_l1ss_cap, &child_l1ss_cap);
+
+	return aspm_calc_init_linkcap(parent_lnkcap, child_lnkcap,
+				      parent_l1ss_cap, child_l1ss_cap);
+}
+
 static u32 aspm_calc_enabled_states(struct pcie_link_state *link,
 				    u32 up_l1ss_cap, u32 dwn_l1ss_cap)
 {
@@ -630,7 +644,7 @@ static u32 aspm_calc_enabled_states(struct pcie_link_state *link,
 static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 {
 	struct pci_dev *child = link->downstream, *parent = link->pdev;
-	u32 parent_lnkcap, child_lnkcap;
+	u32 parent_lnkcap, child_lnkcap, aspm_support;
 	u32 parent_l1ss_cap, child_l1ss_cap;
 	struct pci_bus *linkbus = parent->subordinate;
 
@@ -676,15 +690,14 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 	/* Save default state */
 	link->aspm_default = link->aspm_enabled;
 
-	link->aspm_support = aspm_calc_init_linkcap(parent_lnkcap,
-						    child_lnkcap,
-						    parent_l1ss_cap,
-						    child_l1ss_cap);
-	if (link->aspm_support & ASPM_STATE_L1SS)
-		aspm_calc_l1ss_info(link, parent_l1ss_cap, child_l1ss_cap);
+	aspm_support = aspm_calc_init_linkcap(parent_lnkcap, child_lnkcap,
+					      parent_l1ss_cap, child_l1ss_cap);
+	if (aspm_support & ASPM_STATE_L1SS)
+		aspm_calc_l1ss_info(link, aspm_support, parent_l1ss_cap,
+				    child_l1ss_cap);
 
 	/* Setup initial capable state. Will be updated later */
-	link->aspm_capable = link->aspm_support;
+	link->aspm_capable = aspm_support;
 
 	/* Get and check endpoint acceptable latencies */
 	list_for_each_entry(child, &linkbus->devices, bus_list) {
@@ -994,7 +1007,7 @@ static void pcie_update_aspm_capable(struct pcie_link_state *root)
 	list_for_each_entry(link, &link_list, sibling) {
 		if (link->root != root)
 			continue;
-		link->aspm_capable = link->aspm_support;
+		link->aspm_capable = aspm_get_init_cap(link);
 	}
 	list_for_each_entry(link, &link_list, sibling) {
 		struct pci_dev *child;
-- 
2.20.1


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

* [RFC PATCH v1 5/6] PCI/ASPM: Move pcie_aspm_sanity_check() upwards
  2021-11-06 17:53 [RFC PATCH v1 0/6] Remove struct pcie_link_state.aspm_* Saheed O. Bolarinwa
                   ` (3 preceding siblings ...)
  2021-11-06 17:53 ` [RFC PATCH v1 4/6] PCI/ASPM: Don't cache struct pcie_link_state->aspm_support Saheed O. Bolarinwa
@ 2021-11-06 17:53 ` Saheed O. Bolarinwa
  2021-11-06 17:53 ` [RFC PATCH v1 6/6] PCI/ASPM: Don't cache struct pcie_link_state->aspm_enabled Saheed O. Bolarinwa
  5 siblings, 0 replies; 7+ messages in thread
From: Saheed O. Bolarinwa @ 2021-11-06 17:53 UTC (permalink / raw)
  To: helgaas; +Cc: Saheed O. Bolarinwa, linux-pci, linux-kernel

Move pcie_aspm_sanity_check() upwards to make more accessible.

Signed-off-by: Saheed O. Bolarinwa <refactormyself@gmail.com>
---
 drivers/pci/pcie/aspm.c | 70 ++++++++++++++++++++---------------------
 1 file changed, 35 insertions(+), 35 deletions(-)

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 9aaae476ea31..05ca165380e1 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -447,6 +447,41 @@ static void pci_clear_and_set_dword(struct pci_dev *pdev, int pos,
 	pci_write_config_dword(pdev, pos, val);
 }
 
+static int pcie_aspm_sanity_check(struct pci_dev *pdev)
+{
+	struct pci_dev *child;
+	u32 reg32;
+
+	/*
+	 * Some functions in a slot might not all be PCIe functions,
+	 * very strange. Disable ASPM for the whole slot
+	 */
+	list_for_each_entry(child, &pdev->subordinate->devices, bus_list) {
+		if (!pci_is_pcie(child))
+			return -EINVAL;
+
+		/*
+		 * If ASPM is disabled then we're not going to change
+		 * the BIOS state. It's safe to continue even if it's a
+		 * pre-1.1 device
+		 */
+
+		if (aspm_disabled)
+			continue;
+
+		/*
+		 * Disable ASPM for pre-1.1 PCIe device, we follow MS to use
+		 * RBER bit to determine if a function is 1.1 version device
+		 */
+		pcie_capability_read_dword(child, PCI_EXP_DEVCAP, &reg32);
+		if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
+			pci_info(child, "disabling ASPM on pre-1.1 PCIe device.  You can enable it with 'pcie_aspm=force'\n");
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
 /* Calculate L1.2 PM substate timing parameters */
 static void aspm_calc_l1ss_info(struct pcie_link_state *link,
 				u32 aspm_support, u32 parent_l1ss_cap,
@@ -846,41 +881,6 @@ static void free_link_state(struct pcie_link_state *link)
 	kfree(link);
 }
 
-static int pcie_aspm_sanity_check(struct pci_dev *pdev)
-{
-	struct pci_dev *child;
-	u32 reg32;
-
-	/*
-	 * Some functions in a slot might not all be PCIe functions,
-	 * very strange. Disable ASPM for the whole slot
-	 */
-	list_for_each_entry(child, &pdev->subordinate->devices, bus_list) {
-		if (!pci_is_pcie(child))
-			return -EINVAL;
-
-		/*
-		 * If ASPM is disabled then we're not going to change
-		 * the BIOS state. It's safe to continue even if it's a
-		 * pre-1.1 device
-		 */
-
-		if (aspm_disabled)
-			continue;
-
-		/*
-		 * Disable ASPM for pre-1.1 PCIe device, we follow MS to use
-		 * RBER bit to determine if a function is 1.1 version device
-		 */
-		pcie_capability_read_dword(child, PCI_EXP_DEVCAP, &reg32);
-		if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
-			pci_info(child, "disabling ASPM on pre-1.1 PCIe device.  You can enable it with 'pcie_aspm=force'\n");
-			return -EINVAL;
-		}
-	}
-	return 0;
-}
-
 static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev)
 {
 	struct pcie_link_state *link;
-- 
2.20.1


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

* [RFC PATCH v1 6/6] PCI/ASPM: Don't cache struct pcie_link_state->aspm_enabled
  2021-11-06 17:53 [RFC PATCH v1 0/6] Remove struct pcie_link_state.aspm_* Saheed O. Bolarinwa
                   ` (4 preceding siblings ...)
  2021-11-06 17:53 ` [RFC PATCH v1 5/6] PCI/ASPM: Move pcie_aspm_sanity_check() upwards Saheed O. Bolarinwa
@ 2021-11-06 17:53 ` Saheed O. Bolarinwa
  5 siblings, 0 replies; 7+ messages in thread
From: Saheed O. Bolarinwa @ 2021-11-06 17:53 UTC (permalink / raw)
  To: helgaas; +Cc: Saheed O. Bolarinwa, linux-pci, linux-kernel

aspm_enabled in struct pcie_link_state usually holds the current
enabled states of the link. This value is set in two places:
1. pcie_aspm_cap_init(): if the passed in blacklist value holds true,
   then `link->aspm_enabled = ASPM_STATE_ALL` otherwise values are
   read from the register and link->aspm_enabled is calculated.
   This calculation has been extracted into aspm_calc_enabled_states()
   in an earlier patch in this series.
2. pcie_config_aspm_link(): when a valid state is calculated from the
   value passed in. The result is later written into the register. The
   calculated valid state is then store in struct
   pcie_link_state->aspm_enabled.

The calculations in aspm_calc_enabled_states() reads and uses the
current state in the register. This can be called whenever
link->aspm_enabled is needed. We don't need to store the state.

For the case when blacklist value holds in pcie_aspm_cap_init(), this
value comes from pcie_aspm_init_link_state(). We can obtain this value
whenever link->aspm_enabled is needed and determine if the current
enabled states should be set to "ASPM_STATE_ALL". So also in this case
we don't need to store the enabled states, it can be obtained on the
fly.

 - Remove aspm_enabled from struct pcie_link_state.
 - Create a wrapper function arround aspm_calc_enabled_states().
 - Replace references to aspm_enabled with a function call.

Signed-off-by: Saheed O. Bolarinwa <refactormyself@gmail.com>
---
 drivers/pci/pcie/aspm.c | 36 ++++++++++++++++++++++--------------
 1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 05ca165380e1..dce0851c6ab5 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -54,7 +54,6 @@ struct pcie_link_state {
 	struct list_head sibling;	/* node in link_list */
 
 	/* ASPM state */
-	u32 aspm_enabled:7;		/* Enabled ASPM state */
 	u32 aspm_capable:7;		/* Capable ASPM state with latency */
 	u32 aspm_default:7;		/* Default ASPM state by BIOS */
 	u32 aspm_disable:7;		/* Disabled ASPM state */
@@ -676,6 +675,18 @@ static u32 aspm_calc_enabled_states(struct pcie_link_state *link,
 	return aspm_enabled;
 }
 
+static u32 aspm_get_enabled_states(struct pcie_link_state *link)
+{
+	u32 up_l1ss_cap, dwn_l1ss_cap;
+
+	if (pcie_aspm_sanity_check(link->pdev))
+		return ASPM_STATE_ALL;
+
+	aspm_calc_both_l1ss_caps(link, &up_l1ss_cap, &dwn_l1ss_cap);
+
+	return aspm_calc_enabled_states(link, up_l1ss_cap, dwn_l1ss_cap);
+}
+
 static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 {
 	struct pci_dev *child = link->downstream, *parent = link->pdev;
@@ -684,8 +695,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 	struct pci_bus *linkbus = parent->subordinate;
 
 	if (blacklist) {
-		/* Set enabled/disable so that we will disable ASPM later */
-		link->aspm_enabled = ASPM_STATE_ALL;
+		/* Set disable so that we will disable ASPM later */
 		link->aspm_disable = ASPM_STATE_ALL;
 		return;
 	}
@@ -719,11 +729,9 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 	/* Setup L1 substate */
 	aspm_calc_both_l1ss_caps(link, &parent_l1ss_cap, &child_l1ss_cap);
 
-	link->aspm_enabled = aspm_calc_enabled_states(link, parent_l1ss_cap,
-						      child_l1ss_cap);
-
 	/* Save default state */
-	link->aspm_default = link->aspm_enabled;
+	link->aspm_default = aspm_calc_enabled_states(link, parent_l1ss_cap,
+						      child_l1ss_cap);
 
 	aspm_support = aspm_calc_init_linkcap(parent_lnkcap, child_lnkcap,
 					      parent_l1ss_cap, child_l1ss_cap);
@@ -762,7 +770,7 @@ static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state)
 	u32 val, enable_req;
 	struct pci_dev *child = link->downstream, *parent = link->pdev;
 
-	enable_req = (link->aspm_enabled ^ state) & state;
+	enable_req = (aspm_get_enabled_states(link) ^ state) & state;
 
 	/*
 	 * Here are the rules specified in the PCIe spec for enabling L1SS:
@@ -821,6 +829,7 @@ static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state)
 	u32 upstream = 0, dwstream = 0;
 	struct pci_dev *child = link->downstream, *parent = link->pdev;
 	struct pci_bus *linkbus = parent->subordinate;
+	u32 aspm_enabled = aspm_get_enabled_states(link);
 
 	/* Enable only the states that were not explicitly disabled */
 	state &= (link->aspm_capable & ~link->aspm_disable);
@@ -832,11 +841,11 @@ static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state)
 	/* Spec says both ports must be in D0 before enabling PCI PM substates*/
 	if (parent->current_state != PCI_D0 || child->current_state != PCI_D0) {
 		state &= ~ASPM_STATE_L1_SS_PCIPM;
-		state |= (link->aspm_enabled & ASPM_STATE_L1_SS_PCIPM);
+		state |= (aspm_enabled & ASPM_STATE_L1_SS_PCIPM);
 	}
 
 	/* Nothing to do if the link is already in the requested state */
-	if (link->aspm_enabled == state)
+	if (aspm_enabled == state)
 		return;
 	/* Convert ASPM state to upstream/downstream ASPM register state */
 	if (state & ASPM_STATE_L0S_UP)
@@ -863,8 +872,6 @@ static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state)
 		pcie_config_aspm_dev(child, dwstream);
 	if (!(state & ASPM_STATE_L1))
 		pcie_config_aspm_dev(parent, upstream);
-
-	link->aspm_enabled = state;
 }
 
 static void pcie_config_aspm_path(struct pcie_link_state *link)
@@ -1238,7 +1245,7 @@ bool pcie_aspm_enabled(struct pci_dev *pdev)
 	if (!link)
 		return false;
 
-	return link->aspm_enabled;
+	return aspm_get_enabled_states(link);
 }
 EXPORT_SYMBOL_GPL(pcie_aspm_enabled);
 
@@ -1249,7 +1256,8 @@ static ssize_t aspm_attr_show_common(struct device *dev,
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
 
-	return sysfs_emit(buf, "%d\n", (link->aspm_enabled & state) ? 1 : 0);
+	return sysfs_emit(buf, "%d\n",
+			  (aspm_get_enabled_states(link) & state) ? 1 : 0);
 }
 
 static ssize_t aspm_attr_store_common(struct device *dev,
-- 
2.20.1


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

end of thread, other threads:[~2021-11-06 17:54 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-06 17:53 [RFC PATCH v1 0/6] Remove struct pcie_link_state.aspm_* Saheed O. Bolarinwa
2021-11-06 17:53 ` [RFC PATCH v1 1/6] PCI/ASPM: Extract out L1SS_CAP calculations Saheed O. Bolarinwa
2021-11-06 17:53 ` [RFC PATCH v1 2/6] PCI/ASPM: Extract the calculation of link->aspm_support Saheed O. Bolarinwa
2021-11-06 17:53 ` [RFC PATCH v1 3/6] PCI/ASPM: Extract the calculation of link->aspm_enabled Saheed O. Bolarinwa
2021-11-06 17:53 ` [RFC PATCH v1 4/6] PCI/ASPM: Don't cache struct pcie_link_state->aspm_support Saheed O. Bolarinwa
2021-11-06 17:53 ` [RFC PATCH v1 5/6] PCI/ASPM: Move pcie_aspm_sanity_check() upwards Saheed O. Bolarinwa
2021-11-06 17:53 ` [RFC PATCH v1 6/6] PCI/ASPM: Don't cache struct pcie_link_state->aspm_enabled Saheed O. Bolarinwa

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).