From: Bjorn Helgaas <helgaas@kernel.org>
To: linux-pci@vger.kernel.org
Cc: "Vidya Sagar" <vidyas@nvidia.com>,
"Saheed O . Bolarinwa" <refactormyself@gmail.com>,
"Lorenzo Pieralisi" <lpieralisi@kernel.org>,
"Krzysztof Wilczyński" <kw@linux.com>,
"Rajat Jain" <rajatja@google.com>,
"Kenneth R . Crudup" <kenny@panix.com>,
"Kai-Heng Feng" <kai.heng.feng@canonical.com>,
"Abhishek Sahu" <abhsahu@nvidia.com>,
"Thierry Reding" <treding@nvidia.com>,
"Jonathan Hunter" <jonathanh@nvidia.com>,
"Krishna Thota" <kthota@nvidia.com>,
"Manikanta Maddireddy" <mmaddireddy@nvidia.com>,
"Vidya Sagar" <sagar.tv@gmail.com>,
sagupta@nvidia.com, linux-kernel@vger.kernel.org,
"Bjorn Helgaas" <bhelgaas@google.com>
Subject: [PATCH 3/3] PCI/ASPM: Correct LTR_L1.2_THRESHOLD computation
Date: Tue, 4 Oct 2022 21:58:09 -0500 [thread overview]
Message-ID: <20221005025809.2247547-4-helgaas@kernel.org> (raw)
In-Reply-To: <20221005025809.2247547-1-helgaas@kernel.org>
From: Bjorn Helgaas <bhelgaas@google.com>
80d7d7a904fa ("PCI/ASPM: Calculate LTR_L1.2_THRESHOLD from device
characteristics") replaced a fixed value (163840ns) with one computed from
T_POWER_OFF, Common_Mode_Restore_Time, etc., but it encoded the
LTR_L1.2_THRESHOLD value incorrectly.
This is especially a problem for small thresholds, e.g., 63ns fell into the
"threshold_ns < 1024" case and was encoded as 32ns:
LTR_L1.2_THRESHOLD_Scale = 1 (multiplier is 32ns)
LTR_L1.2_THRESHOLD_Value = 63 >> 5 = 1
LTR_L1.2_THRESHOLD = multiplier * value = 32ns * 1 = 32ns
Correct the algorithm to encode all times of 1023ns (0x3ff) or smaller
exactly and larger times conservatively (the encoded threshold is never
smaller than was requested). This reduces the chance of entering L1.2
when the device can't tolerate the exit latency.
Fixes: 80d7d7a904fa ("PCI/ASPM: Calculate LTR_L1.2_THRESHOLD from device characteristics")
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/pci/pcie/aspm.c | 49 +++++++++++++++++++++++++++--------------
1 file changed, 32 insertions(+), 17 deletions(-)
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index f12d117f44e0..53a1fa306e1e 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -8,6 +8,7 @@
*/
#include <linux/kernel.h>
+#include <linux/math.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
@@ -350,29 +351,43 @@ static u32 calc_l1ss_pwron(struct pci_dev *pdev, u32 scale, u32 val)
return 0;
}
+/*
+ * Encode an LTR_L1.2_THRESHOLD value for the L1 PM Substates Control 1
+ * register. Ports enter L1.2 when the most recent LTR value is greater
+ * than or equal to LTR_L1.2_THRESHOLD, so we round up to make sure we
+ * don't enter L1.2 too aggressively.
+ *
+ * See PCIe r6.0, sec 5.5.1, 6.18, 7.8.3.3.
+ */
static void encode_l12_threshold(u32 threshold_us, u32 *scale, u32 *value)
{
- u32 threshold_ns = threshold_us * 1000;
+ u64 threshold_ns = (u64) threshold_us * 1000;
- /* See PCIe r3.1, sec 7.33.3 and sec 6.18 */
- if (threshold_ns < 32) {
- *scale = 0;
+ /*
+ * LTR_L1.2_THRESHOLD_Value ("value") is a 10-bit field with max
+ * value of 0x3ff.
+ */
+ if (threshold_ns <= 0x3ff * 1) {
+ *scale = 0; /* Value times 1ns */
*value = threshold_ns;
- } else if (threshold_ns < 1024) {
- *scale = 1;
- *value = threshold_ns >> 5;
- } else if (threshold_ns < 32768) {
- *scale = 2;
- *value = threshold_ns >> 10;
- } else if (threshold_ns < 1048576) {
- *scale = 3;
- *value = threshold_ns >> 15;
- } else if (threshold_ns < 33554432) {
- *scale = 4;
- *value = threshold_ns >> 20;
+ } else if (threshold_ns <= 0x3ff * 32) {
+ *scale = 1; /* Value times 32ns */
+ *value = roundup(threshold_ns, 32) / 32;
+ } else if (threshold_ns <= 0x3ff * 1024) {
+ *scale = 2; /* Value times 1024ns */
+ *value = roundup(threshold_ns, 1024) / 1024;
+ } else if (threshold_ns <= 0x3ff * 32768) {
+ *scale = 3; /* Value times 32768ns */
+ *value = roundup(threshold_ns, 32768) / 32768;
+ } else if (threshold_ns <= 0x3ff * 1048576) {
+ *scale = 4; /* Value times 1048576ns */
+ *value = roundup(threshold_ns, 1048576) / 1048576;
+ } else if (threshold_ns <= 0x3ff * (u64) 33554432) {
+ *scale = 5; /* Value times 33554432ns */
+ *value = roundup(threshold_ns, 33554432) / 33554432;
} else {
*scale = 5;
- *value = threshold_ns >> 25;
+ *value = 0x3ff; /* Max representable value */
}
}
--
2.25.1
next prev parent reply other threads:[~2022-10-05 2:58 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-05 2:58 [PATCH 0/3] PCI/ASPM: Fix L1SS issues Bjorn Helgaas
2022-10-05 2:58 ` [PATCH 1/3] PCI/ASPM: Factor out L1 PM Substates configuration Bjorn Helgaas
2022-10-05 2:58 ` [PATCH 2/3] PCI/ASPM: Ignore L1 PM Substates if device lacks capability Bjorn Helgaas
2022-10-05 3:26 ` Sathyanarayanan Kuppuswamy
2022-10-05 11:07 ` Bjorn Helgaas
2022-10-05 2:58 ` Bjorn Helgaas [this message]
2022-10-05 3:28 ` [PATCH 0/3] PCI/ASPM: Fix L1SS issues Sathyanarayanan Kuppuswamy
2022-10-05 17:57 ` Bjorn Helgaas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221005025809.2247547-4-helgaas@kernel.org \
--to=helgaas@kernel.org \
--cc=abhsahu@nvidia.com \
--cc=bhelgaas@google.com \
--cc=jonathanh@nvidia.com \
--cc=kai.heng.feng@canonical.com \
--cc=kenny@panix.com \
--cc=kthota@nvidia.com \
--cc=kw@linux.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=mmaddireddy@nvidia.com \
--cc=rajatja@google.com \
--cc=refactormyself@gmail.com \
--cc=sagar.tv@gmail.com \
--cc=sagupta@nvidia.com \
--cc=treding@nvidia.com \
--cc=vidyas@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome