linux-kernel-mentees.lists.linuxfoundation.org archive mirror
 help / color / mirror / Atom feed
* [Linux-kernel-mentees] [PATCH v4] PCI: Add support for LTR
@ 2020-09-25 18:03 Puranjay Mohan
  2020-09-26  3:52 ` kernel test robot
  2020-09-26  3:53 ` kernel test robot
  0 siblings, 2 replies; 3+ messages in thread
From: Puranjay Mohan @ 2020-09-25 18:03 UTC (permalink / raw)
  To: bjorn; +Cc: linux-pci, linux-kernel-mentees, Puranjay Mohan

Add a new function pci_ltr_init() which will be called from
pci_init_capabilities() to initialize every PCIe device's LTR values.
Add code in probe.c to evaluate LTR _DSM and save the latencies in pci_dev.

Signed-off-by: Puranjay Mohan <puranjay12@gmail.com>
---
v4 - remove pci_upstream_bridge and use acpi_pci_find_companion()
     to get the handle for evaluating _DSM.
     Add acpi_check_dsm()
     Change the logging mechanism.
v3 - change the algorithm to add latencies, add helper funtions for
     encoding and decoding the latencies.
v2 - add an #ifdefin pci-acpi.c to fix the bug reported by test bot.
v1 - based the patch on v5.9-rc1 so it applies correctly.
---
 drivers/pci/pci-acpi.c   | 37 ++++++++++++++++
 drivers/pci/pci.c        | 96 ++++++++++++++++++++++++++++++++++++++++
 drivers/pci/pci.h        |  3 ++
 drivers/pci/probe.c      |  7 ++-
 include/linux/pci-acpi.h |  1 +
 include/linux/pci.h      |  2 +
 6 files changed, 145 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index d5869a03f748..1bceee861bfc 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -1213,6 +1213,43 @@ static void pci_acpi_optimize_delay(struct pci_dev *pdev,
 	ACPI_FREE(obj);
 }
 
+/* pci_acpi_evaluate_ltr_latency
+ *
+ * @dev - the pci_dev to evaluate and save latencies
+ */
+void pci_acpi_evaluate_ltr_latency(struct pci_dev *dev)
+{
+#ifdef CONFIG_PCIEASPM
+	struct acpi_device *adev;
+	union acpi_object *obj, *elements;
+
+	adev = ACPI_COMPANION(&dev->dev);
+	if (!adev && !pci_dev_is_added(dev))
+		adev = acpi_pci_find_companion(&dev->dev);
+	if (!adev)
+		return;
+
+	if (!acpi_check_dsm(adev->handle, &pci_acpi_dsm_guid, 2,
+				1ULL << DSM_PCI_LTR_MAX_LATENCY))
+		return;
+	obj = acpi_evaluate_dsm(adev->handle, &pci_acpi_dsm_guid, 2,
+					DSM_PCI_LTR_MAX_LATENCY, NULL);
+	if (!obj)
+		return;
+
+	if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 4) {
+		elements = obj->package.elements;
+		dev->max_snoop_latency = (u16)elements[1].integer.value |
+				((u16)elements[0].integer.value <<
+							PCI_LTR_SCALE_SHIFT);
+		dev->max_nosnoop_latency = (u16)elements[3].integer.value |
+				((u16)elements[2].integer.value <<
+							PCI_LTR_SCALE_SHIFT);
+	}
+	ACPI_FREE(obj);
+#endif
+}
+
 static void pci_acpi_set_external_facing(struct pci_dev *dev)
 {
 	u8 val;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index a458c46d7e39..a44f07550fac 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3056,6 +3056,102 @@ void pci_pm_init(struct pci_dev *dev)
 		dev->imm_ready = 1;
 }
 
+/**
+ * pci_ltr_decode - Decode the latency to a value in ns
+ * @latency: latency according to PCIe base specification 7.8.2.
+ */
+u64 pci_ltr_decode(u16 latency)
+{
+	u16 scale = (latency & PCI_LTR_SCALE_MASK) >> 10;
+	u16 value = latency & PCI_LTR_VALUE_MASK;
+
+	switch (scale) {
+	case 0: return value;
+	case 1: return value * 32;
+	case 2: return value * 1024;
+	case 3: return value * 32768;
+	case 4: return value * 1048576;
+	case 5: return value * 33554432;
+	}
+	return 0;
+}
+
+/**
+ * pci_ltr_encode - Encode the value in ns to a 16 bit register value
+ * @val: latency according to PCIe base specification 7.8.2.
+ */
+u16 pci_ltr_encode(u64 val)
+{
+	if (val <= 1UL * 0x3ff)
+		return (0 << 10) | (val & 0x3ff);
+	if (val <= 32UL * 0x3ff)
+		return (1 << 10) | ((val >> 5) & 0x3ff);
+	if (val <= 1024UL * 0x3ff)
+		return (2 << 10) | ((val >> 10) & 0x3ff);
+	if (val <= 32768UL * 0x3ff)
+		return (3 << 10) | ((val >> 15) & 0x3ff);
+	if (val <= 1048576UL * 0x3ff)
+		return (4 << 10) | ((val >> 20) & 0x3ff);
+	if (val <= 33554432UL * 0x3ff)
+		return (5 << 10) | ((val >> 25) & 0x3ff);
+	return 0;
+}
+
+/**
+ * pci_ltr_init - Initialize Latency Tolerance Information of given PCI device
+ * @dev: PCI device to handle.
+ */
+void pci_ltr_init(struct pci_dev *dev)
+{
+#ifdef CONFIG_PCIEASPM
+	struct pci_dev *bridge = dev;
+	int ltr;
+	u64 max_snoop = 0, max_nosnoop = 0;
+	u16 max_snoop_encoded, max_nosnoop_encoded;
+	u16 max_snoop_current, max_nosnoop_current;
+	u64 max_snoop_current_decoded, max_nosnoop_current_decoded;
+
+	ltr = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_LTR);
+	if (!ltr)
+		return;
+
+	bridge = pci_upstream_bridge(bridge);
+	while (bridge) {
+		max_snoop += pci_ltr_decode(bridge->max_snoop_latency);
+		max_nosnoop += pci_ltr_decode(bridge->max_nosnoop_latency);
+		bridge = pci_upstream_bridge(bridge);
+	}
+	max_snoop_encoded = pci_ltr_encode(max_snoop);
+	max_nosnoop_encoded = pci_ltr_encode(max_nosnoop);
+
+	pci_read_config_word(dev, ltr + PCI_LTR_MAX_SNOOP_LAT,
+							&max_snoop_current);
+	max_snoop_current_decoded = pci_ltr_decode(max_snoop_current);
+	pci_read_config_word(dev, ltr + PCI_LTR_MAX_NOSNOOP_LAT,
+							&max_nosnoop_current);
+	max_nosnoop_current_decoded = pci_ltr_decode(max_nosnoop_current);
+
+	pci_dbg(dev,
+		"Calculated Max Snoop Latency %lluns Max No-Snoop Latency %lluns\n",
+							max_snoop, max_nosnoop);
+
+	if (max_snoop != max_snoop_current_decoded) {
+		pci_info(dev, "Max Snoop Latency %lluns (was %lluns)\n",
+					max_snoop, max_snoop_current_decoded);
+		pci_write_config_word(dev,
+					ltr + PCI_LTR_MAX_SNOOP_LAT,
+							max_snoop_encoded);
+	}
+	if (max_nosnoop != max_nosnoop_current_decoded) {
+		pci_info(dev, "Max No-Snoop Latency %lluns (was %lluns)\n",
+					max_nosnoop, max_nosnoop_current_decoded);
+		pci_write_config_word(dev,
+				ltr + PCI_LTR_MAX_NOSNOOP_LAT,
+						max_nosnoop_encoded);
+	}
+#endif
+}
+
 static unsigned long pci_ea_flags(struct pci_dev *dev, u8 prop)
 {
 	unsigned long flags = IORESOURCE_PCI_FIXED | IORESOURCE_PCI_EA_BEI;
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index fa12f7cbc1a0..18890975d0f1 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -110,6 +110,7 @@ void pci_free_cap_save_buffers(struct pci_dev *dev);
 bool pci_bridge_d3_possible(struct pci_dev *dev);
 void pci_bridge_d3_update(struct pci_dev *dev);
 void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev);
+void pci_ltr_init(struct pci_dev *dev);
 
 static inline void pci_wakeup_event(struct pci_dev *dev)
 {
@@ -680,11 +681,13 @@ static inline int pci_aer_raw_clear_status(struct pci_dev *dev) { return -EINVAL
 
 #ifdef CONFIG_ACPI
 int pci_acpi_program_hp_params(struct pci_dev *dev);
+void pci_acpi_evaluate_ltr_latency(struct pci_dev *dev);
 #else
 static inline int pci_acpi_program_hp_params(struct pci_dev *dev)
 {
 	return -ENODEV;
 }
+static inline void pci_acpi_evaluate_ltr_latency(struct pci_dev *dev) {}
 #endif
 
 #ifdef CONFIG_PCIEASPM
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 03d37128a24f..74433265ea7e 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2105,6 +2105,11 @@ static void pci_configure_ltr(struct pci_dev *dev)
 
 	if (!pci_is_pcie(dev))
 		return;
+	/*
+	 * Read latency values from _DSM and save in pci_dev
+	 * as a part of latency tolerance reporting mechanism.
+	 */
+	pci_acpi_evaluate_ltr_latency(dev);
 
 	pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap);
 	if (!(cap & PCI_EXP_DEVCAP2_LTR))
@@ -2123,7 +2128,6 @@ static void pci_configure_ltr(struct pci_dev *dev)
 
 		return;
 	}
-
 	if (!host->native_ltr)
 		return;
 
@@ -2400,6 +2404,7 @@ static void pci_init_capabilities(struct pci_dev *dev)
 	pci_ptm_init(dev);		/* Precision Time Measurement */
 	pci_aer_init(dev);		/* Advanced Error Reporting */
 	pci_dpc_init(dev);		/* Downstream Port Containment */
+	pci_ltr_init(dev);		/* Latency Tolerance Reporting */
 
 	pcie_report_downtraining(dev);
 
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 5ba475ca9078..e23236a4ff66 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -110,6 +110,7 @@ extern const guid_t pci_acpi_dsm_guid;
 
 /* _DSM Definitions for PCI */
 #define DSM_PCI_PRESERVE_BOOT_CONFIG		0x05
+#define DSM_PCI_LTR_MAX_LATENCY			0x06
 #define DSM_PCI_DEVICE_NAME			0x07
 #define DSM_PCI_POWER_ON_RESET_DELAY		0x08
 #define DSM_PCI_DEVICE_READINESS_DURATIONS	0x09
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 835530605c0d..af7558e3c331 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -380,6 +380,8 @@ struct pci_dev {
 	struct pcie_link_state	*link_state;	/* ASPM link state */
 	unsigned int	ltr_path:1;	/* Latency Tolerance Reporting
 					   supported from root to here */
+	u16 max_snoop_latency;		/* LTR Max Snoop latency */
+	u16 max_nosnoop_latency;	/* LTR Max No-Snoop latency */
 #endif
 	unsigned int	eetlp_prefix_path:1;	/* End-to-End TLP Prefix */
 
-- 
2.27.0

_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

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

* Re: [Linux-kernel-mentees] [PATCH v4] PCI: Add support for LTR
  2020-09-25 18:03 [Linux-kernel-mentees] [PATCH v4] PCI: Add support for LTR Puranjay Mohan
@ 2020-09-26  3:52 ` kernel test robot
  2020-09-26  3:53 ` kernel test robot
  1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2020-09-26  3:52 UTC (permalink / raw)
  To: Puranjay Mohan, bjorn
  Cc: linux-pci, linux-kernel-mentees, kbuild-all, Puranjay Mohan

[-- Attachment #1: Type: text/plain, Size: 3325 bytes --]

Hi Puranjay,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on pci/next]
[also build test WARNING on pm/linux-next v5.9-rc6 next-20200925]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Puranjay-Mohan/PCI-Add-support-for-LTR/20200926-020527
base:   https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git next
config: microblaze-randconfig-r005-20200925 (attached as .config)
compiler: microblaze-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/8d07a88c56c747b6c2217cad501d3b0d5cfe8ca6
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Puranjay-Mohan/PCI-Add-support-for-LTR/20200926-020527
        git checkout 8d07a88c56c747b6c2217cad501d3b0d5cfe8ca6
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=microblaze 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/pci/pci.c:3064:5: warning: no previous prototype for 'pci_ltr_decode' [-Wmissing-prototypes]
    3064 | u64 pci_ltr_decode(u16 latency)
         |     ^~~~~~~~~~~~~~
>> drivers/pci/pci.c:3084:5: warning: no previous prototype for 'pci_ltr_encode' [-Wmissing-prototypes]
    3084 | u16 pci_ltr_encode(u64 val)
         |     ^~~~~~~~~~~~~~

vim +/pci_ltr_decode +3064 drivers/pci/pci.c

  3059	
  3060	/**
  3061	 * pci_ltr_decode - Decode the latency to a value in ns
  3062	 * @latency: latency according to PCIe base specification 7.8.2.
  3063	 */
> 3064	u64 pci_ltr_decode(u16 latency)
  3065	{
  3066		u16 scale = (latency & PCI_LTR_SCALE_MASK) >> 10;
  3067		u16 value = latency & PCI_LTR_VALUE_MASK;
  3068	
  3069		switch (scale) {
  3070		case 0: return value;
  3071		case 1: return value * 32;
  3072		case 2: return value * 1024;
  3073		case 3: return value * 32768;
  3074		case 4: return value * 1048576;
  3075		case 5: return value * 33554432;
  3076		}
  3077		return 0;
  3078	}
  3079	
  3080	/**
  3081	 * pci_ltr_encode - Encode the value in ns to a 16 bit register value
  3082	 * @val: latency according to PCIe base specification 7.8.2.
  3083	 */
> 3084	u16 pci_ltr_encode(u64 val)
  3085	{
  3086		if (val <= 1UL * 0x3ff)
  3087			return (0 << 10) | (val & 0x3ff);
  3088		if (val <= 32UL * 0x3ff)
  3089			return (1 << 10) | ((val >> 5) & 0x3ff);
  3090		if (val <= 1024UL * 0x3ff)
  3091			return (2 << 10) | ((val >> 10) & 0x3ff);
  3092		if (val <= 32768UL * 0x3ff)
  3093			return (3 << 10) | ((val >> 15) & 0x3ff);
  3094		if (val <= 1048576UL * 0x3ff)
  3095			return (4 << 10) | ((val >> 20) & 0x3ff);
  3096		if (val <= 33554432UL * 0x3ff)
  3097			return (5 << 10) | ((val >> 25) & 0x3ff);
  3098		return 0;
  3099	}
  3100	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27739 bytes --]

[-- Attachment #3: Type: text/plain, Size: 201 bytes --]

_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

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

* Re: [Linux-kernel-mentees] [PATCH v4] PCI: Add support for LTR
  2020-09-25 18:03 [Linux-kernel-mentees] [PATCH v4] PCI: Add support for LTR Puranjay Mohan
  2020-09-26  3:52 ` kernel test robot
@ 2020-09-26  3:53 ` kernel test robot
  1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2020-09-26  3:53 UTC (permalink / raw)
  To: Puranjay Mohan, bjorn
  Cc: kbuild-all, Puranjay Mohan, linux-pci, clang-built-linux,
	linux-kernel-mentees

[-- Attachment #1: Type: text/plain, Size: 3832 bytes --]

Hi Puranjay,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on pci/next]
[also build test WARNING on pm/linux-next v5.9-rc6 next-20200925]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Puranjay-Mohan/PCI-Add-support-for-LTR/20200926-020527
base:   https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git next
config: riscv-randconfig-r004-20200925 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project a83eb048cb9a75da7a07a9d5318bbdbf54885c87)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/0day-ci/linux/commit/8d07a88c56c747b6c2217cad501d3b0d5cfe8ca6
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Puranjay-Mohan/PCI-Add-support-for-LTR/20200926-020527
        git checkout 8d07a88c56c747b6c2217cad501d3b0d5cfe8ca6
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=riscv 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/pci/pci.c:3064:5: warning: no previous prototype for function 'pci_ltr_decode' [-Wmissing-prototypes]
   u64 pci_ltr_decode(u16 latency)
       ^
   drivers/pci/pci.c:3064:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   u64 pci_ltr_decode(u16 latency)
   ^
   static 
>> drivers/pci/pci.c:3084:5: warning: no previous prototype for function 'pci_ltr_encode' [-Wmissing-prototypes]
   u16 pci_ltr_encode(u64 val)
       ^
   drivers/pci/pci.c:3084:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   u16 pci_ltr_encode(u64 val)
   ^
   static 
   2 warnings generated.

vim +/pci_ltr_decode +3064 drivers/pci/pci.c

  3059	
  3060	/**
  3061	 * pci_ltr_decode - Decode the latency to a value in ns
  3062	 * @latency: latency according to PCIe base specification 7.8.2.
  3063	 */
> 3064	u64 pci_ltr_decode(u16 latency)
  3065	{
  3066		u16 scale = (latency & PCI_LTR_SCALE_MASK) >> 10;
  3067		u16 value = latency & PCI_LTR_VALUE_MASK;
  3068	
  3069		switch (scale) {
  3070		case 0: return value;
  3071		case 1: return value * 32;
  3072		case 2: return value * 1024;
  3073		case 3: return value * 32768;
  3074		case 4: return value * 1048576;
  3075		case 5: return value * 33554432;
  3076		}
  3077		return 0;
  3078	}
  3079	
  3080	/**
  3081	 * pci_ltr_encode - Encode the value in ns to a 16 bit register value
  3082	 * @val: latency according to PCIe base specification 7.8.2.
  3083	 */
> 3084	u16 pci_ltr_encode(u64 val)
  3085	{
  3086		if (val <= 1UL * 0x3ff)
  3087			return (0 << 10) | (val & 0x3ff);
  3088		if (val <= 32UL * 0x3ff)
  3089			return (1 << 10) | ((val >> 5) & 0x3ff);
  3090		if (val <= 1024UL * 0x3ff)
  3091			return (2 << 10) | ((val >> 10) & 0x3ff);
  3092		if (val <= 32768UL * 0x3ff)
  3093			return (3 << 10) | ((val >> 15) & 0x3ff);
  3094		if (val <= 1048576UL * 0x3ff)
  3095			return (4 << 10) | ((val >> 20) & 0x3ff);
  3096		if (val <= 33554432UL * 0x3ff)
  3097			return (5 << 10) | ((val >> 25) & 0x3ff);
  3098		return 0;
  3099	}
  3100	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 33291 bytes --]

[-- Attachment #3: Type: text/plain, Size: 201 bytes --]

_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

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

end of thread, other threads:[~2020-09-26  3:54 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-25 18:03 [Linux-kernel-mentees] [PATCH v4] PCI: Add support for LTR Puranjay Mohan
2020-09-26  3:52 ` kernel test robot
2020-09-26  3:53 ` kernel test robot

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