All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/3 v2] PCI/ASPM: Remove struct aspm_latency
@ 2021-09-16  8:49 Saheed O. Bolarinwa
  2021-09-16  8:49 ` [RFC PATCH 1/3 v1] PCI/ASPM: Remove cached latencies in struct pcie_link_state Saheed O. Bolarinwa
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Saheed O. Bolarinwa @ 2021-09-16  8:49 UTC (permalink / raw)
  To: helgaas; +Cc: Bolarinwa O. Saheed, linux-pci, linux-kernel, kw

From: "Bolarinwa O. Saheed" <refactormyself@gmail.com>

To validate and set link latency capability, `struct aspm_latency` and
related members defined within `struct pcie_link_state` are used.
However, since there are not many access to theses values, it is possible
to directly access and compute these values.
Doing this will also reduce the dependency on `struct pcie_link_state`.

The series removes `struct aspm_latency` and related members within 
`struct pcie_link_state`. All latencies are now calculated when needed.

Changes in this version:
 - directly access downstream by calling `pci_function_0()` instead of
   used the `struct pcie_link_state`

Saheed O. Bolarinwa (3):
  PCI/ASPM: Remove link latencies cached within struct pcie_link_state
  PCI/ASPM: Remove struct pcie_link_state.acceptable
  PCI/ASPM: Remove struct aspm_latency

 drivers/pci/pcie/aspm.c | 89 ++++++++++++++++++-----------------------
 1 file changed, 38 insertions(+), 51 deletions(-)

-- 
2.20.1


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

* [RFC PATCH 1/3 v1] PCI/ASPM: Remove cached latencies in struct pcie_link_state
  2021-09-16  8:49 [RFC PATCH 0/3 v2] PCI/ASPM: Remove struct aspm_latency Saheed O. Bolarinwa
@ 2021-09-16  8:49 ` Saheed O. Bolarinwa
  2021-09-16  8:49 ` [RFC PATCH 2/3 v2] PCI/ASPM: Remove struct pcie_link_state.acceptable Saheed O. Bolarinwa
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Saheed O. Bolarinwa @ 2021-09-16  8:49 UTC (permalink / raw)
  To: helgaas; +Cc: Saheed O. Bolarinwa, linux-pci, linux-kernel, kw

The latencies of the upstream and downstream are calculated within
pcie_aspm_cap_init() and cached in struct pcie_link_state.latency_*
These values are only used in pcie_aspm_check_latency() where they are
compared with the acceptable latencies on the link.

This patch:
  - removes `latency_*` entries from struct pcie_link_state.
  - calculates the latencies directly where they are needed.
  - moves pci_function_0() upward, so that the downstream device can be
    obtained directly.
  - further removes dependencies on struct pcie_link_state.

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

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 013a47f587ce..9e85dfc56657 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -66,9 +66,6 @@ struct pcie_link_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 */
-	struct aspm_latency latency_dw;	/* Downstream direction exit latency */
 	/*
 	 * Endpoint acceptable latencies. A pcie downstream port only
 	 * has one slot under it, so at most there are 8 functions.
@@ -376,9 +373,25 @@ static void encode_l12_threshold(u32 threshold_us, u32 *scale, u32 *value)
 	}
 }
 
+/*
+ * The L1 PM substate capability is only implemented in function 0 in a
+ * multi function device.
+ */
+static struct pci_dev *pci_function_0(struct pci_bus *linkbus)
+{
+	struct pci_dev *child;
+
+	list_for_each_entry(child, &linkbus->devices, bus_list)
+		if (PCI_FUNC(child->devfn) == 0)
+			return child;
+	return NULL;
+}
+
 static void pcie_aspm_check_latency(struct pci_dev *endpoint)
 {
-	u32 latency, l1_switch_latency = 0;
+	u32 latency, lnkcap_up, lnkcap_dw, l1_switch_latency = 0;
+	struct pci_dev *downstream;
+	struct aspm_latency latency_up, latency_dw;
 	struct aspm_latency *acceptable;
 	struct pcie_link_state *link;
 
@@ -388,17 +401,26 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint)
 		return;
 
 	link = endpoint->bus->self->link_state;
+	downstream = pci_function_0(link->pdev->subordinate);
 	acceptable = &link->acceptable[PCI_FUNC(endpoint->devfn)];
 
 	while (link) {
+		/* Read direction exit latencies */
+		pcie_capability_read_dword(link->pdev, PCI_EXP_LNKCAP, &lnkcap_up);
+		pcie_capability_read_dword(downstream, PCI_EXP_LNKCAP, &lnkcap_dw);
+		latency_up.l0s = calc_l0s_latency(lnkcap_up);
+		latency_up.l1 = calc_l1_latency(lnkcap_up);
+		latency_dw.l0s = calc_l0s_latency(lnkcap_dw);
+		latency_dw.l1 = calc_l1_latency(lnkcap_dw);
+
 		/* Check upstream direction L0s latency */
 		if ((link->aspm_capable & ASPM_STATE_L0S_UP) &&
-		    (link->latency_up.l0s > acceptable->l0s))
+		    (latency_up.l0s > acceptable->l0s))
 			link->aspm_capable &= ~ASPM_STATE_L0S_UP;
 
 		/* Check downstream direction L0s latency */
 		if ((link->aspm_capable & ASPM_STATE_L0S_DW) &&
-		    (link->latency_dw.l0s > acceptable->l0s))
+		    (latency_dw.l0s > acceptable->l0s))
 			link->aspm_capable &= ~ASPM_STATE_L0S_DW;
 		/*
 		 * Check L1 latency.
@@ -413,7 +435,7 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint)
 		 * L1 exit latencies advertised by a device include L1
 		 * substate latencies (and hence do not do any check).
 		 */
-		latency = max_t(u32, link->latency_up.l1, link->latency_dw.l1);
+		latency = max_t(u32, latency_up.l1, latency_dw.l1);
 		if ((link->aspm_capable & ASPM_STATE_L1) &&
 		    (latency + l1_switch_latency > acceptable->l1))
 			link->aspm_capable &= ~ASPM_STATE_L1;
@@ -423,20 +445,6 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint)
 	}
 }
 
-/*
- * The L1 PM substate capability is only implemented in function 0 in a
- * multi function device.
- */
-static struct pci_dev *pci_function_0(struct pci_bus *linkbus)
-{
-	struct pci_dev *child;
-
-	list_for_each_entry(child, &linkbus->devices, bus_list)
-		if (PCI_FUNC(child->devfn) == 0)
-			return child;
-	return NULL;
-}
-
 static void pci_clear_and_set_dword(struct pci_dev *pdev, int pos,
 				    u32 clear, u32 set)
 {
@@ -593,8 +601,6 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 		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_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPM_L1)
@@ -602,8 +608,6 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 
 	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 */
 	pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CAP,
-- 
2.20.1


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

* [RFC PATCH 2/3 v2] PCI/ASPM: Remove struct pcie_link_state.acceptable
  2021-09-16  8:49 [RFC PATCH 0/3 v2] PCI/ASPM: Remove struct aspm_latency Saheed O. Bolarinwa
  2021-09-16  8:49 ` [RFC PATCH 1/3 v1] PCI/ASPM: Remove cached latencies in struct pcie_link_state Saheed O. Bolarinwa
@ 2021-09-16  8:49 ` Saheed O. Bolarinwa
  2021-09-30 23:52   ` Bjorn Helgaas
  2021-09-16  8:49 ` [RFC PATCH 3/3 v1] PCI/ASPM: Remove struct aspm_latency Saheed O. Bolarinwa
  2021-09-26 20:31 ` [RFC PATCH 0/3 v2] " Bjorn Helgaas
  3 siblings, 1 reply; 6+ messages in thread
From: Saheed O. Bolarinwa @ 2021-09-16  8:49 UTC (permalink / raw)
  To: helgaas; +Cc: Saheed O. Bolarinwa, linux-pci, linux-kernel, kw

The acceptable latencies for each device on the bus are calculated within
pcie_aspm_cap_init() and cached in struct pcie_link_state.acceptable. They
are only used in pcie_aspm_check_latency() to validate actual latencies.
Thus, it is possible to avoid caching these values.

This patch:
  - removes `acceptable` from struct pcie_link_state
  - calculates the acceptable latency for each device directly
  - removes the calculations done within pcie_aspm_cap_init()

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

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 9e85dfc56657..0c0c055823f1 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -65,12 +65,6 @@ struct pcie_link_state {
 	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 */
-
-	/*
-	 * Endpoint acceptable latencies. A pcie downstream port only
-	 * has one slot under it, so at most there are 8 functions.
-	 */
-	struct aspm_latency acceptable[8];
 };
 
 static int aspm_disabled, aspm_force;
@@ -389,7 +383,7 @@ static struct pci_dev *pci_function_0(struct pci_bus *linkbus)
 
 static void pcie_aspm_check_latency(struct pci_dev *endpoint)
 {
-	u32 latency, lnkcap_up, lnkcap_dw, l1_switch_latency = 0;
+	u32 reg32, latency, encoding, lnkcap_up, lnkcap_dw, l1_switch_latency = 0;
 	struct pci_dev *downstream;
 	struct aspm_latency latency_up, latency_dw;
 	struct aspm_latency *acceptable;
@@ -402,7 +396,13 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint)
 
 	link = endpoint->bus->self->link_state;
 	downstream = pci_function_0(link->pdev->subordinate);
-	acceptable = &link->acceptable[PCI_FUNC(endpoint->devfn)];
+	pcie_capability_read_dword(endpoint, PCI_EXP_DEVCAP, &reg32);
+	/* Calculate endpoint L0s acceptable latency */
+	encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
+	acceptable->l0s = calc_l0s_acceptable(encoding);
+	/* Calculate endpoint L1 acceptable latency */
+	encoding = (reg32 & PCI_EXP_DEVCAP_L1) >> 9;
+	acceptable->l1 = calc_l1_acceptable(encoding);
 
 	while (link) {
 		/* Read direction exit latencies */
@@ -664,22 +664,11 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 
 	/* Get and check endpoint acceptable latencies */
 	list_for_each_entry(child, &linkbus->devices, bus_list) {
-		u32 reg32, encoding;
-		struct aspm_latency *acceptable =
-			&link->acceptable[PCI_FUNC(child->devfn)];
 
 		if (pci_pcie_type(child) != PCI_EXP_TYPE_ENDPOINT &&
 		    pci_pcie_type(child) != PCI_EXP_TYPE_LEG_END)
 			continue;
 
-		pcie_capability_read_dword(child, PCI_EXP_DEVCAP, &reg32);
-		/* Calculate endpoint L0s acceptable latency */
-		encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
-		acceptable->l0s = calc_l0s_acceptable(encoding);
-		/* Calculate endpoint L1 acceptable latency */
-		encoding = (reg32 & PCI_EXP_DEVCAP_L1) >> 9;
-		acceptable->l1 = calc_l1_acceptable(encoding);
-
 		pcie_aspm_check_latency(child);
 	}
 }
-- 
2.20.1


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

* [RFC PATCH 3/3 v1] PCI/ASPM: Remove struct aspm_latency
  2021-09-16  8:49 [RFC PATCH 0/3 v2] PCI/ASPM: Remove struct aspm_latency Saheed O. Bolarinwa
  2021-09-16  8:49 ` [RFC PATCH 1/3 v1] PCI/ASPM: Remove cached latencies in struct pcie_link_state Saheed O. Bolarinwa
  2021-09-16  8:49 ` [RFC PATCH 2/3 v2] PCI/ASPM: Remove struct pcie_link_state.acceptable Saheed O. Bolarinwa
@ 2021-09-16  8:49 ` Saheed O. Bolarinwa
  2021-09-26 20:31 ` [RFC PATCH 0/3 v2] " Bjorn Helgaas
  3 siblings, 0 replies; 6+ messages in thread
From: Saheed O. Bolarinwa @ 2021-09-16  8:49 UTC (permalink / raw)
  To: helgaas; +Cc: Saheed O. Bolarinwa, linux-pci, linux-kernel, kw

The struct aspm_latency is now used only inside pcie_aspm_check_latency().

Since this struct is trivial, this patch:
  - replaces struct aspm_latency variables with u32 variables
  - removes struct aspm_latency

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

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 0c0c055823f1..8093c9335e1f 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -41,11 +41,6 @@
 #define ASPM_STATE_ALL		(ASPM_STATE_L0S | ASPM_STATE_L1 |	\
 				 ASPM_STATE_L1SS)
 
-struct aspm_latency {
-	u32 l0s;			/* L0s latency (nsec) */
-	u32 l1;				/* L1 latency (nsec) */
-};
-
 struct pcie_link_state {
 	struct pci_dev *pdev;		/* Upstream component of the Link */
 	struct pci_dev *downstream;	/* Downstream component, function 0 */
@@ -384,9 +379,9 @@ static struct pci_dev *pci_function_0(struct pci_bus *linkbus)
 static void pcie_aspm_check_latency(struct pci_dev *endpoint)
 {
 	u32 reg32, latency, encoding, lnkcap_up, lnkcap_dw, l1_switch_latency = 0;
+	u32 latency_up_l0s, latency_up_l1, latency_dw_l0s, latency_dw_l1;
+	u32 acceptable_l0s, acceptable_l1;
 	struct pci_dev *downstream;
-	struct aspm_latency latency_up, latency_dw;
-	struct aspm_latency *acceptable;
 	struct pcie_link_state *link;
 
 	/* Device not in D0 doesn't need latency check */
@@ -399,28 +394,28 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint)
 	pcie_capability_read_dword(endpoint, PCI_EXP_DEVCAP, &reg32);
 	/* Calculate endpoint L0s acceptable latency */
 	encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
-	acceptable->l0s = calc_l0s_acceptable(encoding);
+	acceptable_l0s = calc_l0s_acceptable(encoding);
 	/* Calculate endpoint L1 acceptable latency */
 	encoding = (reg32 & PCI_EXP_DEVCAP_L1) >> 9;
-	acceptable->l1 = calc_l1_acceptable(encoding);
+	acceptable_l1 = calc_l1_acceptable(encoding);
 
 	while (link) {
 		/* Read direction exit latencies */
 		pcie_capability_read_dword(link->pdev, PCI_EXP_LNKCAP, &lnkcap_up);
 		pcie_capability_read_dword(downstream, PCI_EXP_LNKCAP, &lnkcap_dw);
-		latency_up.l0s = calc_l0s_latency(lnkcap_up);
-		latency_up.l1 = calc_l1_latency(lnkcap_up);
-		latency_dw.l0s = calc_l0s_latency(lnkcap_dw);
-		latency_dw.l1 = calc_l1_latency(lnkcap_dw);
+		latency_up_l0s = calc_l0s_latency(lnkcap_up);
+		latency_up_l1 = calc_l1_latency(lnkcap_up);
+		latency_dw_l0s = calc_l0s_latency(lnkcap_dw);
+		latency_dw_l1 = calc_l1_latency(lnkcap_dw);
 
 		/* Check upstream direction L0s latency */
 		if ((link->aspm_capable & ASPM_STATE_L0S_UP) &&
-		    (latency_up.l0s > acceptable->l0s))
+		    (latency_up_l0s > acceptable_l0s))
 			link->aspm_capable &= ~ASPM_STATE_L0S_UP;
 
 		/* Check downstream direction L0s latency */
 		if ((link->aspm_capable & ASPM_STATE_L0S_DW) &&
-		    (latency_dw.l0s > acceptable->l0s))
+		    (latency_dw_l0s > acceptable_l0s))
 			link->aspm_capable &= ~ASPM_STATE_L0S_DW;
 		/*
 		 * Check L1 latency.
@@ -435,9 +430,9 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint)
 		 * L1 exit latencies advertised by a device include L1
 		 * substate latencies (and hence do not do any check).
 		 */
-		latency = max_t(u32, latency_up.l1, latency_dw.l1);
+		latency = max_t(u32, latency_up_l1, latency_dw_l1);
 		if ((link->aspm_capable & ASPM_STATE_L1) &&
-		    (latency + l1_switch_latency > acceptable->l1))
+		    (latency + l1_switch_latency > acceptable_l1))
 			link->aspm_capable &= ~ASPM_STATE_L1;
 		l1_switch_latency += 1000;
 
@@ -664,7 +659,6 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 
 	/* Get and check endpoint acceptable latencies */
 	list_for_each_entry(child, &linkbus->devices, bus_list) {
-
 		if (pci_pcie_type(child) != PCI_EXP_TYPE_ENDPOINT &&
 		    pci_pcie_type(child) != PCI_EXP_TYPE_LEG_END)
 			continue;
-- 
2.20.1


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

* Re: [RFC PATCH 0/3 v2] PCI/ASPM: Remove struct aspm_latency
  2021-09-16  8:49 [RFC PATCH 0/3 v2] PCI/ASPM: Remove struct aspm_latency Saheed O. Bolarinwa
                   ` (2 preceding siblings ...)
  2021-09-16  8:49 ` [RFC PATCH 3/3 v1] PCI/ASPM: Remove struct aspm_latency Saheed O. Bolarinwa
@ 2021-09-26 20:31 ` Bjorn Helgaas
  3 siblings, 0 replies; 6+ messages in thread
From: Bjorn Helgaas @ 2021-09-26 20:31 UTC (permalink / raw)
  To: Saheed O. Bolarinwa; +Cc: linux-pci, linux-kernel, kw

On Thu, Sep 16, 2021 at 10:49:23AM +0200, Saheed O. Bolarinwa wrote:
> From: "Bolarinwa O. Saheed" <refactormyself@gmail.com>
> 
> To validate and set link latency capability, `struct aspm_latency` and
> related members defined within `struct pcie_link_state` are used.
> However, since there are not many access to theses values, it is possible
> to directly access and compute these values.
> Doing this will also reduce the dependency on `struct pcie_link_state`.
> 
> The series removes `struct aspm_latency` and related members within 
> `struct pcie_link_state`. All latencies are now calculated when needed.
> 
> Changes in this version:
>  - directly access downstream by calling `pci_function_0()` instead of
>    used the `struct pcie_link_state`
> 
> Saheed O. Bolarinwa (3):
>   PCI/ASPM: Remove link latencies cached within struct pcie_link_state
>   PCI/ASPM: Remove struct pcie_link_state.acceptable
>   PCI/ASPM: Remove struct aspm_latency
> 
>  drivers/pci/pcie/aspm.c | 89 ++++++++++++++++++-----------------------
>  1 file changed, 38 insertions(+), 51 deletions(-)

Hi Saheed, what is this series based on?  The other series
(https://lore.kernel.org/r/20210916085206.2268-1-refactormyself@gmail.com)
aplies cleanly to my "main" branch (v5.15-rc2), but this one doesn't
apply either there or on top of the other.

Bjorn

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

* Re: [RFC PATCH 2/3 v2] PCI/ASPM: Remove struct pcie_link_state.acceptable
  2021-09-16  8:49 ` [RFC PATCH 2/3 v2] PCI/ASPM: Remove struct pcie_link_state.acceptable Saheed O. Bolarinwa
@ 2021-09-30 23:52   ` Bjorn Helgaas
  0 siblings, 0 replies; 6+ messages in thread
From: Bjorn Helgaas @ 2021-09-30 23:52 UTC (permalink / raw)
  To: Saheed O. Bolarinwa; +Cc: linux-pci, linux-kernel, kw

On Thu, Sep 16, 2021 at 10:49:25AM +0200, Saheed O. Bolarinwa wrote:
> The acceptable latencies for each device on the bus are calculated within
> pcie_aspm_cap_init() and cached in struct pcie_link_state.acceptable. They
> are only used in pcie_aspm_check_latency() to validate actual latencies.
> Thus, it is possible to avoid caching these values.
> 
> This patch:
>   - removes `acceptable` from struct pcie_link_state
>   - calculates the acceptable latency for each device directly
>   - removes the calculations done within pcie_aspm_cap_init()
> 
> Signed-off-by: Saheed O. Bolarinwa <refactormyself@gmail.com>
> ---
>  drivers/pci/pcie/aspm.c | 27 ++++++++-------------------
>  1 file changed, 8 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
> index 9e85dfc56657..0c0c055823f1 100644
> --- a/drivers/pci/pcie/aspm.c
> +++ b/drivers/pci/pcie/aspm.c
> @@ -65,12 +65,6 @@ struct pcie_link_state {
>  	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 */
> -
> -	/*
> -	 * Endpoint acceptable latencies. A pcie downstream port only
> -	 * has one slot under it, so at most there are 8 functions.
> -	 */
> -	struct aspm_latency acceptable[8];
>  };
>  
>  static int aspm_disabled, aspm_force;
> @@ -389,7 +383,7 @@ static struct pci_dev *pci_function_0(struct pci_bus *linkbus)
>  
>  static void pcie_aspm_check_latency(struct pci_dev *endpoint)
>  {
> -	u32 latency, lnkcap_up, lnkcap_dw, l1_switch_latency = 0;
> +	u32 reg32, latency, encoding, lnkcap_up, lnkcap_dw, l1_switch_latency = 0;
>  	struct pci_dev *downstream;
>  	struct aspm_latency latency_up, latency_dw;
>  	struct aspm_latency *acceptable;
> @@ -402,7 +396,13 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint)
>  
>  	link = endpoint->bus->self->link_state;
>  	downstream = pci_function_0(link->pdev->subordinate);
> -	acceptable = &link->acceptable[PCI_FUNC(endpoint->devfn)];
> +	pcie_capability_read_dword(endpoint, PCI_EXP_DEVCAP, &reg32);

I think you can use endpoint->devcap here, can't you?

> +	/* Calculate endpoint L0s acceptable latency */
> +	encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
> +	acceptable->l0s = calc_l0s_acceptable(encoding);
> +	/* Calculate endpoint L1 acceptable latency */
> +	encoding = (reg32 & PCI_EXP_DEVCAP_L1) >> 9;
> +	acceptable->l1 = calc_l1_acceptable(encoding);

I think it's a little weird that we call pcie_aspm_check_latency() for
all the functions in a multi-function device.  It's true that they can
all have different acceptable latencies, but they're all on the
downstream end of the same link, so they will all see the same exit
latencies.

I would think we could compute the minimum latency across all the
functions and do a single check to see whether the link can meet that.
But that would be material for a future patch, not this one.

>  	while (link) {
>  		/* Read direction exit latencies */
> @@ -664,22 +664,11 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
>  
>  	/* Get and check endpoint acceptable latencies */
>  	list_for_each_entry(child, &linkbus->devices, bus_list) {
> -		u32 reg32, encoding;
> -		struct aspm_latency *acceptable =
> -			&link->acceptable[PCI_FUNC(child->devfn)];
>  
>  		if (pci_pcie_type(child) != PCI_EXP_TYPE_ENDPOINT &&
>  		    pci_pcie_type(child) != PCI_EXP_TYPE_LEG_END)
>  			continue;
>  
> -		pcie_capability_read_dword(child, PCI_EXP_DEVCAP, &reg32);
> -		/* Calculate endpoint L0s acceptable latency */
> -		encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
> -		acceptable->l0s = calc_l0s_acceptable(encoding);
> -		/* Calculate endpoint L1 acceptable latency */
> -		encoding = (reg32 & PCI_EXP_DEVCAP_L1) >> 9;
> -		acceptable->l1 = calc_l1_acceptable(encoding);
> -
>  		pcie_aspm_check_latency(child);
>  	}
>  }
> -- 
> 2.20.1
> 

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

end of thread, other threads:[~2021-09-30 23:52 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-16  8:49 [RFC PATCH 0/3 v2] PCI/ASPM: Remove struct aspm_latency Saheed O. Bolarinwa
2021-09-16  8:49 ` [RFC PATCH 1/3 v1] PCI/ASPM: Remove cached latencies in struct pcie_link_state Saheed O. Bolarinwa
2021-09-16  8:49 ` [RFC PATCH 2/3 v2] PCI/ASPM: Remove struct pcie_link_state.acceptable Saheed O. Bolarinwa
2021-09-30 23:52   ` Bjorn Helgaas
2021-09-16  8:49 ` [RFC PATCH 3/3 v1] PCI/ASPM: Remove struct aspm_latency Saheed O. Bolarinwa
2021-09-26 20:31 ` [RFC PATCH 0/3 v2] " Bjorn Helgaas

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.