Message ID | 20200726220653.635852-2-ian.kumlien@gmail.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | Use maximum latency when determining L1 ASPM | expand |
Sorry, the changelog is broken -- Will resend... That'll teach me for thinking after working out... =) On Mon, Jul 27, 2020 at 12:07 AM Ian Kumlien <ian.kumlien@gmail.com> wrote: > > The current solution verifies per "hop" but doesn't > check the maximum latency, instead it checks the > current "hops" max latency for upstream and downstrea, > > This would work if all "hops" have the same latency, but: > > root -> a -> b -> c -> endpoint > > If c or b has the higest latency, it might not register > > Fix this by maintaining a maximum value for comparison > > Signed-off-by: Ian Kumlien <ian.kumlien@gmail.com> > --- > drivers/pci/pcie/aspm.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c > index b17e5ffd31b1..bd53fba7f382 100644 > --- a/drivers/pci/pcie/aspm.c > +++ b/drivers/pci/pcie/aspm.c > @@ -434,7 +434,7 @@ static void pcie_get_aspm_reg(struct pci_dev *pdev, > > static void pcie_aspm_check_latency(struct pci_dev *endpoint) > { > - u32 latency, l1_switch_latency = 0; > + u32 latency, l1_max_latency = 0, l1_switch_latency = 0; > struct aspm_latency *acceptable; > struct pcie_link_state *link; > > @@ -470,8 +470,9 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint) > * substate latencies (and hence do not do any check). > */ > latency = max_t(u32, link->latency_up.l1, link->latency_dw.l1); > + l1_max_latency = max_t(u32, latency, l1_max_latency); > if ((link->aspm_capable & ASPM_STATE_L1) && > - (latency + l1_switch_latency > acceptable->l1)) > + (l1_max_latency + l1_switch_latency > acceptable->l1)) > link->aspm_capable &= ~ASPM_STATE_L1; > l1_switch_latency += 1000; > > -- > 2.27.0 >
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index b17e5ffd31b1..bd53fba7f382 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -434,7 +434,7 @@ static void pcie_get_aspm_reg(struct pci_dev *pdev, static void pcie_aspm_check_latency(struct pci_dev *endpoint) { - u32 latency, l1_switch_latency = 0; + u32 latency, l1_max_latency = 0, l1_switch_latency = 0; struct aspm_latency *acceptable; struct pcie_link_state *link; @@ -470,8 +470,9 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint) * substate latencies (and hence do not do any check). */ latency = max_t(u32, link->latency_up.l1, link->latency_dw.l1); + l1_max_latency = max_t(u32, latency, l1_max_latency); if ((link->aspm_capable & ASPM_STATE_L1) && - (latency + l1_switch_latency > acceptable->l1)) + (l1_max_latency + l1_switch_latency > acceptable->l1)) link->aspm_capable &= ~ASPM_STATE_L1; l1_switch_latency += 1000;
The current solution verifies per "hop" but doesn't check the maximum latency, instead it checks the current "hops" max latency for upstream and downstrea, This would work if all "hops" have the same latency, but: root -> a -> b -> c -> endpoint If c or b has the higest latency, it might not register Fix this by maintaining a maximum value for comparison Signed-off-by: Ian Kumlien <ian.kumlien@gmail.com> --- drivers/pci/pcie/aspm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)