public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/6] PCI/ASPM: Add locked helper for enabling link state
       [not found] <20231114135553.32301-1-johan+linaro@kernel.org>
@ 2023-11-14 13:55 ` Johan Hovold
  2023-11-15 14:26   ` kernel test robot
                     ` (2 more replies)
  2023-11-14 13:55 ` [PATCH 2/6] PCI: vmd: Fix deadlock when enabling ASPM Johan Hovold
  1 sibling, 3 replies; 11+ messages in thread
From: Johan Hovold @ 2023-11-14 13:55 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas
  Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Manivannan Sadhasivam,
	Rob Herring, Nirmal Patel, Jonathan Derrick, linux-arm-msm,
	linux-pci, linux-kernel, Johan Hovold, stable, Michael Bottini,
	David E . Box

Add a helper for enabling link states that can be used in contexts where
a pci_bus_sem read lock is already held (e.g. from pci_walk_bus()).

This helper will be used to fix a couple of potential deadlocks where
the current helper is called with the lock already held, hence the CC
stable tag.

Fixes: f492edb40b54 ("PCI: vmd: Add quirk to configure PCIe ASPM and LTR")
Cc: stable@vger.kernel.org	# 6.3
Cc: Michael Bottini <michael.a.bottini@linux.intel.com>
Cc: David E. Box <david.e.box@linux.intel.com>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
 drivers/pci/pcie/aspm.c | 53 +++++++++++++++++++++++++++++++----------
 include/linux/pci.h     |  3 +++
 2 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 50b04ae5c394..8cf8cc2d6bba 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -1109,17 +1109,7 @@ int pci_disable_link_state(struct pci_dev *pdev, int state)
 }
 EXPORT_SYMBOL(pci_disable_link_state);
 
-/**
- * pci_enable_link_state - Clear and set the default device link state so that
- * the link may be allowed to enter the specified states. Note that if the
- * BIOS didn't grant ASPM control to the OS, this does nothing because we can't
- * touch the LNKCTL register. Also note that this does not enable states
- * disabled by pci_disable_link_state(). Return 0 or a negative errno.
- *
- * @pdev: PCI device
- * @state: Mask of ASPM link states to enable
- */
-int pci_enable_link_state(struct pci_dev *pdev, int state)
+static int __pci_enable_link_state(struct pci_dev *pdev, int state, bool locked)
 {
 	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
 
@@ -1136,7 +1126,8 @@ int pci_enable_link_state(struct pci_dev *pdev, int state)
 		return -EPERM;
 	}
 
-	down_read(&pci_bus_sem);
+	if (!locked)
+		down_read(&pci_bus_sem);
 	mutex_lock(&aspm_lock);
 	link->aspm_default = 0;
 	if (state & PCIE_LINK_STATE_L0S)
@@ -1157,12 +1148,48 @@ int pci_enable_link_state(struct pci_dev *pdev, int state)
 	link->clkpm_default = (state & PCIE_LINK_STATE_CLKPM) ? 1 : 0;
 	pcie_set_clkpm(link, policy_to_clkpm_state(link));
 	mutex_unlock(&aspm_lock);
-	up_read(&pci_bus_sem);
+	if (!locked)
+		up_read(&pci_bus_sem);
 
 	return 0;
 }
+
+/**
+ * pci_enable_link_state - Clear and set the default device link state so that
+ * the link may be allowed to enter the specified states. Note that if the
+ * BIOS didn't grant ASPM control to the OS, this does nothing because we can't
+ * touch the LNKCTL register. Also note that this does not enable states
+ * disabled by pci_disable_link_state(). Return 0 or a negative errno.
+ *
+ * @pdev: PCI device
+ * @state: Mask of ASPM link states to enable
+ */
+int pci_enable_link_state(struct pci_dev *pdev, int state)
+{
+	return __pci_enable_link_state(pdev, state, false);
+}
 EXPORT_SYMBOL(pci_enable_link_state);
 
+/**
+ * pci_enable_link_state - Clear and set the default device link state so that
+ * the link may be allowed to enter the specified states. Note that if the
+ * BIOS didn't grant ASPM control to the OS, this does nothing because we can't
+ * touch the LNKCTL register. Also note that this does not enable states
+ * disabled by pci_disable_link_state(). Return 0 or a negative errno.
+ *
+ * @pdev: PCI device
+ * @state: Mask of ASPM link states to enable
+ *
+ * Context: Caller holds pci_bus_sem read lock.
+ */
+int pci_enable_link_state_locked(struct pci_dev *pdev, int state)
+{
+	lockdep_assert_held_read(&pci_bus_sem);
+
+	return __pci_enable_link_state(pdev, state, true);
+}
+EXPORT_SYMBOL(pci_enable_link_state_locked);
+
 static int pcie_aspm_set_policy(const char *val,
 				const struct kernel_param *kp)
 {
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 60ca768bc867..dea043bc1e38 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1829,6 +1829,7 @@ extern bool pcie_ports_native;
 int pci_disable_link_state(struct pci_dev *pdev, int state);
 int pci_disable_link_state_locked(struct pci_dev *pdev, int state);
 int pci_enable_link_state(struct pci_dev *pdev, int state);
+int pci_enable_link_state_locked(struct pci_dev *pdev, int state);
 void pcie_no_aspm(void);
 bool pcie_aspm_support_enabled(void);
 bool pcie_aspm_enabled(struct pci_dev *pdev);
@@ -1839,6 +1840,8 @@ static inline int pci_disable_link_state_locked(struct pci_dev *pdev, int state)
 { return 0; }
 static inline int pci_enable_link_state(struct pci_dev *pdev, int state)
 { return 0; }
+static inline int pci_enable_link_state_locked(struct pci_dev *pdev, int state)
+{ return 0; }
 static inline void pcie_no_aspm(void) { }
 static inline bool pcie_aspm_support_enabled(void) { return false; }
 static inline bool pcie_aspm_enabled(struct pci_dev *pdev) { return false; }
-- 
2.41.0


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

* [PATCH 2/6] PCI: vmd: Fix deadlock when enabling ASPM
       [not found] <20231114135553.32301-1-johan+linaro@kernel.org>
  2023-11-14 13:55 ` [PATCH 1/6] PCI/ASPM: Add locked helper for enabling link state Johan Hovold
@ 2023-11-14 13:55 ` Johan Hovold
  2023-11-17 10:28   ` Manivannan Sadhasivam
  1 sibling, 1 reply; 11+ messages in thread
From: Johan Hovold @ 2023-11-14 13:55 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas
  Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Manivannan Sadhasivam,
	Rob Herring, Nirmal Patel, Jonathan Derrick, linux-arm-msm,
	linux-pci, linux-kernel, Johan Hovold, stable, Michael Bottini,
	David E . Box

The vmd_pm_enable_quirk() helper is called from pci_walk_bus() during
probe to enable ASPM for controllers with VMD_FEAT_BIOS_PM_QUIRK set.

Since pci_walk_bus() already holds a pci_bus_sem read lock, use the new
locked helper to enable link states in order to avoid a potential
deadlock (e.g. in case someone takes a write lock before reacquiring
the read lock).

Fixes: f492edb40b54 ("PCI: vmd: Add quirk to configure PCIe ASPM and LTR")
Cc: stable@vger.kernel.org      # 6.3
Cc: Michael Bottini <michael.a.bottini@linux.intel.com>
Cc: David E. Box <david.e.box@linux.intel.com>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
 drivers/pci/controller/vmd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
index 94ba61fe1c44..0452cbc362ee 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -751,7 +751,7 @@ static int vmd_pm_enable_quirk(struct pci_dev *pdev, void *userdata)
 	if (!(features & VMD_FEAT_BIOS_PM_QUIRK))
 		return 0;
 
-	pci_enable_link_state(pdev, PCIE_LINK_STATE_ALL);
+	pci_enable_link_state_locked(pdev, PCIE_LINK_STATE_ALL);
 
 	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_LTR);
 	if (!pos)
-- 
2.41.0


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

* Re: [PATCH 1/6] PCI/ASPM: Add locked helper for enabling link state
  2023-11-14 13:55 ` [PATCH 1/6] PCI/ASPM: Add locked helper for enabling link state Johan Hovold
@ 2023-11-15 14:26   ` kernel test robot
  2023-11-15 16:06     ` Johan Hovold
  2023-11-17 10:28   ` Manivannan Sadhasivam
  2023-11-18  0:00   ` David E. Box
  2 siblings, 1 reply; 11+ messages in thread
From: kernel test robot @ 2023-11-15 14:26 UTC (permalink / raw)
  To: Johan Hovold, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Bjorn Helgaas
  Cc: oe-kbuild-all, Andy Gross, Bjorn Andersson, Konrad Dybcio,
	Manivannan Sadhasivam, Rob Herring, Nirmal Patel,
	Jonathan Derrick, linux-arm-msm, linux-pci, linux-kernel,
	Johan Hovold, stable, Michael Bottini, David E . Box

Hi Johan,

kernel test robot noticed the following build warnings:

[auto build test WARNING on pci/next]
[also build test WARNING on pci/for-linus linus/master v6.7-rc1 next-20231115]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Johan-Hovold/PCI-ASPM-Add-locked-helper-for-enabling-link-state/20231114-220117
base:   https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git next
patch link:    https://lore.kernel.org/r/20231114135553.32301-2-johan%2Blinaro%40kernel.org
patch subject: [PATCH 1/6] PCI/ASPM: Add locked helper for enabling link state
config: x86_64-randconfig-002-20231115 (https://download.01.org/0day-ci/archive/20231115/202311152225.ZdVv0ufT-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231115/202311152225.ZdVv0ufT-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311152225.ZdVv0ufT-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/pci/pcie/aspm.c:1186: warning: expecting prototype for pci_enable_link_state(). Prototype was for pci_enable_link_state_locked() instead


vim +1186 drivers/pci/pcie/aspm.c

  1172	
  1173	/**
  1174	 * pci_enable_link_state - Clear and set the default device link state so that
  1175	 * the link may be allowed to enter the specified states. Note that if the
  1176	 * BIOS didn't grant ASPM control to the OS, this does nothing because we can't
  1177	 * touch the LNKCTL register. Also note that this does not enable states
  1178	 * disabled by pci_disable_link_state(). Return 0 or a negative errno.
  1179	 *
  1180	 * @pdev: PCI device
  1181	 * @state: Mask of ASPM link states to enable
  1182	 *
  1183	 * Context: Caller holds pci_bus_sem read lock.
  1184	 */
  1185	int pci_enable_link_state_locked(struct pci_dev *pdev, int state)
> 1186	{
  1187		lockdep_assert_held_read(&pci_bus_sem);
  1188	
  1189		return __pci_enable_link_state(pdev, state, true);
  1190	}
  1191	EXPORT_SYMBOL(pci_enable_link_state_locked);
  1192	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH 1/6] PCI/ASPM: Add locked helper for enabling link state
  2023-11-15 14:26   ` kernel test robot
@ 2023-11-15 16:06     ` Johan Hovold
  2023-11-17 10:27       ` Manivannan Sadhasivam
  0 siblings, 1 reply; 11+ messages in thread
From: Johan Hovold @ 2023-11-15 16:06 UTC (permalink / raw)
  To: kernel test robot
  Cc: Johan Hovold, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Bjorn Helgaas, oe-kbuild-all, Andy Gross, Bjorn Andersson,
	Konrad Dybcio, Manivannan Sadhasivam, Rob Herring, Nirmal Patel,
	Jonathan Derrick, linux-arm-msm, linux-pci, linux-kernel, stable,
	Michael Bottini, David E . Box

On Wed, Nov 15, 2023 at 10:26:40PM +0800, kernel test robot wrote:
 
> >> drivers/pci/pcie/aspm.c:1186: warning: expecting prototype for pci_enable_link_state(). Prototype was for pci_enable_link_state_locked() instead
> 
> 
> vim +1186 drivers/pci/pcie/aspm.c
> 
>   1172	
>   1173	/**
>   1174	 * pci_enable_link_state - Clear and set the default device link state so that

I apparently forgot to update the name here to

	pci_enable_link_state_locked

[ ... ]

>   1184	 */
>   1185	int pci_enable_link_state_locked(struct pci_dev *pdev, int state)

Perhaps this can be fixed up when applying, or otherwise I'll respin.

Johan

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

* Re: [PATCH 1/6] PCI/ASPM: Add locked helper for enabling link state
  2023-11-15 16:06     ` Johan Hovold
@ 2023-11-17 10:27       ` Manivannan Sadhasivam
  2023-11-17 10:30         ` Johan Hovold
  0 siblings, 1 reply; 11+ messages in thread
From: Manivannan Sadhasivam @ 2023-11-17 10:27 UTC (permalink / raw)
  To: Johan Hovold
  Cc: kernel test robot, Johan Hovold, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Bjorn Helgaas, oe-kbuild-all,
	Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Nirmal Patel, Jonathan Derrick, linux-arm-msm, linux-pci,
	linux-kernel, stable, Michael Bottini, David E . Box

On Wed, Nov 15, 2023 at 05:06:23PM +0100, Johan Hovold wrote:
> On Wed, Nov 15, 2023 at 10:26:40PM +0800, kernel test robot wrote:
>  
> > >> drivers/pci/pcie/aspm.c:1186: warning: expecting prototype for pci_enable_link_state(). Prototype was for pci_enable_link_state_locked() instead
> > 
> > 
> > vim +1186 drivers/pci/pcie/aspm.c
> > 
> >   1172	
> >   1173	/**
> >   1174	 * pci_enable_link_state - Clear and set the default device link state so that
> 
> I apparently forgot to update the name here to
> 
> 	pci_enable_link_state_locked
> 

While fixing the name, please add locking information in description as well.

- Mani

> [ ... ]
> 
> >   1184	 */
> >   1185	int pci_enable_link_state_locked(struct pci_dev *pdev, int state)
> 
> Perhaps this can be fixed up when applying, or otherwise I'll respin.
> 
> Johan

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH 1/6] PCI/ASPM: Add locked helper for enabling link state
  2023-11-14 13:55 ` [PATCH 1/6] PCI/ASPM: Add locked helper for enabling link state Johan Hovold
  2023-11-15 14:26   ` kernel test robot
@ 2023-11-17 10:28   ` Manivannan Sadhasivam
  2023-11-18  0:00   ` David E. Box
  2 siblings, 0 replies; 11+ messages in thread
From: Manivannan Sadhasivam @ 2023-11-17 10:28 UTC (permalink / raw)
  To: Johan Hovold
  Cc: Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
	Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Nirmal Patel, Jonathan Derrick, linux-arm-msm, linux-pci,
	linux-kernel, stable, Michael Bottini, David E . Box

On Tue, Nov 14, 2023 at 02:55:48PM +0100, Johan Hovold wrote:
> Add a helper for enabling link states that can be used in contexts where
> a pci_bus_sem read lock is already held (e.g. from pci_walk_bus()).
> 
> This helper will be used to fix a couple of potential deadlocks where
> the current helper is called with the lock already held, hence the CC
> stable tag.
> 
> Fixes: f492edb40b54 ("PCI: vmd: Add quirk to configure PCIe ASPM and LTR")
> Cc: stable@vger.kernel.org	# 6.3
> Cc: Michael Bottini <michael.a.bottini@linux.intel.com>
> Cc: David E. Box <david.e.box@linux.intel.com>
> Signed-off-by: Johan Hovold <johan+linaro@kernel.org>

With the Kdoc comment fixed,

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

- Mani

> ---
>  drivers/pci/pcie/aspm.c | 53 +++++++++++++++++++++++++++++++----------
>  include/linux/pci.h     |  3 +++
>  2 files changed, 43 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
> index 50b04ae5c394..8cf8cc2d6bba 100644
> --- a/drivers/pci/pcie/aspm.c
> +++ b/drivers/pci/pcie/aspm.c
> @@ -1109,17 +1109,7 @@ int pci_disable_link_state(struct pci_dev *pdev, int state)
>  }
>  EXPORT_SYMBOL(pci_disable_link_state);
>  
> -/**
> - * pci_enable_link_state - Clear and set the default device link state so that
> - * the link may be allowed to enter the specified states. Note that if the
> - * BIOS didn't grant ASPM control to the OS, this does nothing because we can't
> - * touch the LNKCTL register. Also note that this does not enable states
> - * disabled by pci_disable_link_state(). Return 0 or a negative errno.
> - *
> - * @pdev: PCI device
> - * @state: Mask of ASPM link states to enable
> - */
> -int pci_enable_link_state(struct pci_dev *pdev, int state)
> +static int __pci_enable_link_state(struct pci_dev *pdev, int state, bool locked)
>  {
>  	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
>  
> @@ -1136,7 +1126,8 @@ int pci_enable_link_state(struct pci_dev *pdev, int state)
>  		return -EPERM;
>  	}
>  
> -	down_read(&pci_bus_sem);
> +	if (!locked)
> +		down_read(&pci_bus_sem);
>  	mutex_lock(&aspm_lock);
>  	link->aspm_default = 0;
>  	if (state & PCIE_LINK_STATE_L0S)
> @@ -1157,12 +1148,48 @@ int pci_enable_link_state(struct pci_dev *pdev, int state)
>  	link->clkpm_default = (state & PCIE_LINK_STATE_CLKPM) ? 1 : 0;
>  	pcie_set_clkpm(link, policy_to_clkpm_state(link));
>  	mutex_unlock(&aspm_lock);
> -	up_read(&pci_bus_sem);
> +	if (!locked)
> +		up_read(&pci_bus_sem);
>  
>  	return 0;
>  }
> +
> +/**
> + * pci_enable_link_state - Clear and set the default device link state so that
> + * the link may be allowed to enter the specified states. Note that if the
> + * BIOS didn't grant ASPM control to the OS, this does nothing because we can't
> + * touch the LNKCTL register. Also note that this does not enable states
> + * disabled by pci_disable_link_state(). Return 0 or a negative errno.
> + *
> + * @pdev: PCI device
> + * @state: Mask of ASPM link states to enable
> + */
> +int pci_enable_link_state(struct pci_dev *pdev, int state)
> +{
> +	return __pci_enable_link_state(pdev, state, false);
> +}
>  EXPORT_SYMBOL(pci_enable_link_state);
>  
> +/**
> + * pci_enable_link_state - Clear and set the default device link state so that
> + * the link may be allowed to enter the specified states. Note that if the
> + * BIOS didn't grant ASPM control to the OS, this does nothing because we can't
> + * touch the LNKCTL register. Also note that this does not enable states
> + * disabled by pci_disable_link_state(). Return 0 or a negative errno.
> + *
> + * @pdev: PCI device
> + * @state: Mask of ASPM link states to enable
> + *
> + * Context: Caller holds pci_bus_sem read lock.
> + */
> +int pci_enable_link_state_locked(struct pci_dev *pdev, int state)
> +{
> +	lockdep_assert_held_read(&pci_bus_sem);
> +
> +	return __pci_enable_link_state(pdev, state, true);
> +}
> +EXPORT_SYMBOL(pci_enable_link_state_locked);
> +
>  static int pcie_aspm_set_policy(const char *val,
>  				const struct kernel_param *kp)
>  {
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 60ca768bc867..dea043bc1e38 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1829,6 +1829,7 @@ extern bool pcie_ports_native;
>  int pci_disable_link_state(struct pci_dev *pdev, int state);
>  int pci_disable_link_state_locked(struct pci_dev *pdev, int state);
>  int pci_enable_link_state(struct pci_dev *pdev, int state);
> +int pci_enable_link_state_locked(struct pci_dev *pdev, int state);
>  void pcie_no_aspm(void);
>  bool pcie_aspm_support_enabled(void);
>  bool pcie_aspm_enabled(struct pci_dev *pdev);
> @@ -1839,6 +1840,8 @@ static inline int pci_disable_link_state_locked(struct pci_dev *pdev, int state)
>  { return 0; }
>  static inline int pci_enable_link_state(struct pci_dev *pdev, int state)
>  { return 0; }
> +static inline int pci_enable_link_state_locked(struct pci_dev *pdev, int state)
> +{ return 0; }
>  static inline void pcie_no_aspm(void) { }
>  static inline bool pcie_aspm_support_enabled(void) { return false; }
>  static inline bool pcie_aspm_enabled(struct pci_dev *pdev) { return false; }
> -- 
> 2.41.0
> 

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH 2/6] PCI: vmd: Fix deadlock when enabling ASPM
  2023-11-14 13:55 ` [PATCH 2/6] PCI: vmd: Fix deadlock when enabling ASPM Johan Hovold
@ 2023-11-17 10:28   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 11+ messages in thread
From: Manivannan Sadhasivam @ 2023-11-17 10:28 UTC (permalink / raw)
  To: Johan Hovold
  Cc: Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
	Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Nirmal Patel, Jonathan Derrick, linux-arm-msm, linux-pci,
	linux-kernel, stable, Michael Bottini, David E . Box

On Tue, Nov 14, 2023 at 02:55:49PM +0100, Johan Hovold wrote:
> The vmd_pm_enable_quirk() helper is called from pci_walk_bus() during
> probe to enable ASPM for controllers with VMD_FEAT_BIOS_PM_QUIRK set.
> 
> Since pci_walk_bus() already holds a pci_bus_sem read lock, use the new
> locked helper to enable link states in order to avoid a potential
> deadlock (e.g. in case someone takes a write lock before reacquiring
> the read lock).
> 
> Fixes: f492edb40b54 ("PCI: vmd: Add quirk to configure PCIe ASPM and LTR")
> Cc: stable@vger.kernel.org      # 6.3
> Cc: Michael Bottini <michael.a.bottini@linux.intel.com>
> Cc: David E. Box <david.e.box@linux.intel.com>
> Signed-off-by: Johan Hovold <johan+linaro@kernel.org>

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

- Mani

> ---
>  drivers/pci/controller/vmd.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
> index 94ba61fe1c44..0452cbc362ee 100644
> --- a/drivers/pci/controller/vmd.c
> +++ b/drivers/pci/controller/vmd.c
> @@ -751,7 +751,7 @@ static int vmd_pm_enable_quirk(struct pci_dev *pdev, void *userdata)
>  	if (!(features & VMD_FEAT_BIOS_PM_QUIRK))
>  		return 0;
>  
> -	pci_enable_link_state(pdev, PCIE_LINK_STATE_ALL);
> +	pci_enable_link_state_locked(pdev, PCIE_LINK_STATE_ALL);
>  
>  	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_LTR);
>  	if (!pos)
> -- 
> 2.41.0
> 

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH 1/6] PCI/ASPM: Add locked helper for enabling link state
  2023-11-17 10:27       ` Manivannan Sadhasivam
@ 2023-11-17 10:30         ` Johan Hovold
  2023-11-17 10:50           ` Manivannan Sadhasivam
  0 siblings, 1 reply; 11+ messages in thread
From: Johan Hovold @ 2023-11-17 10:30 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: kernel test robot, Johan Hovold, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Bjorn Helgaas, oe-kbuild-all,
	Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Nirmal Patel, Jonathan Derrick, linux-arm-msm, linux-pci,
	linux-kernel, stable, Michael Bottini, David E . Box

On Fri, Nov 17, 2023 at 03:57:24PM +0530, Manivannan Sadhasivam wrote:
> On Wed, Nov 15, 2023 at 05:06:23PM +0100, Johan Hovold wrote:
> > On Wed, Nov 15, 2023 at 10:26:40PM +0800, kernel test robot wrote:
> >  
> > > >> drivers/pci/pcie/aspm.c:1186: warning: expecting prototype for pci_enable_link_state(). Prototype was for pci_enable_link_state_locked() instead
> > > 
> > > 
> > > vim +1186 drivers/pci/pcie/aspm.c
> > > 
> > >   1172	
> > >   1173	/**
> > >   1174	 * pci_enable_link_state - Clear and set the default device link state so that
> > 
> > I apparently forgot to update the name here to
> > 
> > 	pci_enable_link_state_locked
> > 
> 
> While fixing the name, please add locking information in description as well.

It's already there:

	Context: Caller holds pci_bus_sem read lock.

Johan

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

* Re: [PATCH 1/6] PCI/ASPM: Add locked helper for enabling link state
  2023-11-17 10:30         ` Johan Hovold
@ 2023-11-17 10:50           ` Manivannan Sadhasivam
  0 siblings, 0 replies; 11+ messages in thread
From: Manivannan Sadhasivam @ 2023-11-17 10:50 UTC (permalink / raw)
  To: Johan Hovold
  Cc: kernel test robot, Johan Hovold, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Bjorn Helgaas, oe-kbuild-all,
	Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Nirmal Patel, Jonathan Derrick, linux-arm-msm, linux-pci,
	linux-kernel, stable, Michael Bottini, David E . Box

On Fri, Nov 17, 2023 at 11:30:39AM +0100, Johan Hovold wrote:
> On Fri, Nov 17, 2023 at 03:57:24PM +0530, Manivannan Sadhasivam wrote:
> > On Wed, Nov 15, 2023 at 05:06:23PM +0100, Johan Hovold wrote:
> > > On Wed, Nov 15, 2023 at 10:26:40PM +0800, kernel test robot wrote:
> > >  
> > > > >> drivers/pci/pcie/aspm.c:1186: warning: expecting prototype for pci_enable_link_state(). Prototype was for pci_enable_link_state_locked() instead
> > > > 
> > > > 
> > > > vim +1186 drivers/pci/pcie/aspm.c
> > > > 
> > > >   1172	
> > > >   1173	/**
> > > >   1174	 * pci_enable_link_state - Clear and set the default device link state so that
> > > 
> > > I apparently forgot to update the name here to
> > > 
> > > 	pci_enable_link_state_locked
> > > 
> > 
> > While fixing the name, please add locking information in description as well.
> 
> It's already there:
> 
> 	Context: Caller holds pci_bus_sem read lock.

Ah, I was looking for it in the description. Fine then!

- Mani

> 
> Johan

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH 1/6] PCI/ASPM: Add locked helper for enabling link state
  2023-11-14 13:55 ` [PATCH 1/6] PCI/ASPM: Add locked helper for enabling link state Johan Hovold
  2023-11-15 14:26   ` kernel test robot
  2023-11-17 10:28   ` Manivannan Sadhasivam
@ 2023-11-18  0:00   ` David E. Box
  2023-11-20  8:33     ` Johan Hovold
  2 siblings, 1 reply; 11+ messages in thread
From: David E. Box @ 2023-11-18  0:00 UTC (permalink / raw)
  To: Johan Hovold, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Bjorn Helgaas
  Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Manivannan Sadhasivam,
	Rob Herring, Nirmal Patel, Jonathan Derrick, linux-arm-msm,
	linux-pci, linux-kernel, stable

On Tue, 2023-11-14 at 14:55 +0100, Johan Hovold wrote:
> Add a helper for enabling link states that can be used in contexts where
> a pci_bus_sem read lock is already held (e.g. from pci_walk_bus()).
> 
> This helper will be used to fix a couple of potential deadlocks where
> the current helper is called with the lock already held, hence the CC
> stable tag.

Thanks for sending a patch to address this. It had fallen off my radar.

> 
> Fixes: f492edb40b54 ("PCI: vmd: Add quirk to configure PCIe ASPM and LTR")
> Cc: stable@vger.kernel.org   # 6.3
> Cc: Michael Bottini <michael.a.bottini@linux.intel.com>
> Cc: David E. Box <david.e.box@linux.intel.com>
> Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
> ---
>  drivers/pci/pcie/aspm.c | 53 +++++++++++++++++++++++++++++++----------
>  include/linux/pci.h     |  3 +++
>  2 files changed, 43 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
> index 50b04ae5c394..8cf8cc2d6bba 100644
> --- a/drivers/pci/pcie/aspm.c
> +++ b/drivers/pci/pcie/aspm.c
> @@ -1109,17 +1109,7 @@ int pci_disable_link_state(struct pci_dev *pdev, int
> state)
>  }
>  EXPORT_SYMBOL(pci_disable_link_state);
>  
> -/**
> - * pci_enable_link_state - Clear and set the default device link state so
> that
> - * the link may be allowed to enter the specified states. Note that if the
> - * BIOS didn't grant ASPM control to the OS, this does nothing because we
> can't
> - * touch the LNKCTL register. Also note that this does not enable states
> - * disabled by pci_disable_link_state(). Return 0 or a negative errno.
> - *
> - * @pdev: PCI device
> - * @state: Mask of ASPM link states to enable
> - */
> -int pci_enable_link_state(struct pci_dev *pdev, int state)
> +static int __pci_enable_link_state(struct pci_dev *pdev, int state, bool
> locked)
>  {
>         struct pcie_link_state *link = pcie_aspm_get_link(pdev);
>  
> @@ -1136,7 +1126,8 @@ int pci_enable_link_state(struct pci_dev *pdev, int
> state)
>                 return -EPERM;
>         }
>  
> -       down_read(&pci_bus_sem);
> +       if (!locked)
> +               down_read(&pci_bus_sem);

This solution is similar to the original one I proposed [1]. It just creates a
separate locked function rather than using a flag. While the API is consistent
with pci_disable_link_state_locked(), its usage is not. The vmd driver calls
pci_enable_link_state() from pci_walk_bus() which was problematic for Bjorn [2].
I owed an attempt to implement this as a fixup. However, now
qcom_pcie_enabled_aspm() is also using it from pci_walk_bus(). The fixup could
make sense for VMD since there it's fixing missing BIOS settings, but I'm not
sure about qcom. Bjorn, do you still see issues with the use in pci_bus_walk()?

[1]
https://lore.kernel.org/lkml/20230321233849.3408339-1-david.e.box@linux.intel.com/

[2] https://lore.kernel.org/lkml/20230322205702.GA2493123@bhelgaas/

David

>         mutex_lock(&aspm_lock);
>         link->aspm_default = 0;
>         if (state & PCIE_LINK_STATE_L0S)
> @@ -1157,12 +1148,48 @@ int pci_enable_link_state(struct pci_dev *pdev, int
> state)
>         link->clkpm_default = (state & PCIE_LINK_STATE_CLKPM) ? 1 : 0;
>         pcie_set_clkpm(link, policy_to_clkpm_state(link));
>         mutex_unlock(&aspm_lock);
> -       up_read(&pci_bus_sem);
> +       if (!locked)
> +               up_read(&pci_bus_sem);
>  
>         return 0;
>  }
> +
> +/**
> + * pci_enable_link_state - Clear and set the default device link state so
> that
> + * the link may be allowed to enter the specified states. Note that if the
> + * BIOS didn't grant ASPM control to the OS, this does nothing because we
> can't
> + * touch the LNKCTL register. Also note that this does not enable states
> + * disabled by pci_disable_link_state(). Return 0 or a negative errno.
> + *
> + * @pdev: PCI device
> + * @state: Mask of ASPM link states to enable
> + */
> +int pci_enable_link_state(struct pci_dev *pdev, int state)
> +{
> +       return __pci_enable_link_state(pdev, state, false);
> +}
>  EXPORT_SYMBOL(pci_enable_link_state);
>  
> +/**
> + * pci_enable_link_state - Clear and set the default device link state so
> that
> + * the link may be allowed to enter the specified states. Note that if the
> + * BIOS didn't grant ASPM control to the OS, this does nothing because we
> can't
> + * touch the LNKCTL register. Also note that this does not enable states
> + * disabled by pci_disable_link_state(). Return 0 or a negative errno.
> + *
> + * @pdev: PCI device
> + * @state: Mask of ASPM link states to enable
> + *
> + * Context: Caller holds pci_bus_sem read lock.
> + */
> +int pci_enable_link_state_locked(struct pci_dev *pdev, int state)
> +{
> +       lockdep_assert_held_read(&pci_bus_sem);
> +
> +       return __pci_enable_link_state(pdev, state, true);
> +}
> +EXPORT_SYMBOL(pci_enable_link_state_locked);
> +
>  static int pcie_aspm_set_policy(const char *val,
>                                 const struct kernel_param *kp)
>  {
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 60ca768bc867..dea043bc1e38 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1829,6 +1829,7 @@ extern bool pcie_ports_native;
>  int pci_disable_link_state(struct pci_dev *pdev, int state);
>  int pci_disable_link_state_locked(struct pci_dev *pdev, int state);
>  int pci_enable_link_state(struct pci_dev *pdev, int state);
> +int pci_enable_link_state_locked(struct pci_dev *pdev, int state);
>  void pcie_no_aspm(void);
>  bool pcie_aspm_support_enabled(void);
>  bool pcie_aspm_enabled(struct pci_dev *pdev);
> @@ -1839,6 +1840,8 @@ static inline int pci_disable_link_state_locked(struct
> pci_dev *pdev, int state)
>  { return 0; }
>  static inline int pci_enable_link_state(struct pci_dev *pdev, int state)
>  { return 0; }
> +static inline int pci_enable_link_state_locked(struct pci_dev *pdev, int
> state)
> +{ return 0; }
>  static inline void pcie_no_aspm(void) { }
>  static inline bool pcie_aspm_support_enabled(void) { return false; }
>  static inline bool pcie_aspm_enabled(struct pci_dev *pdev) { return false; }


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

* Re: [PATCH 1/6] PCI/ASPM: Add locked helper for enabling link state
  2023-11-18  0:00   ` David E. Box
@ 2023-11-20  8:33     ` Johan Hovold
  0 siblings, 0 replies; 11+ messages in thread
From: Johan Hovold @ 2023-11-20  8:33 UTC (permalink / raw)
  To: David E. Box
  Cc: Johan Hovold, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Bjorn Helgaas, Andy Gross, Bjorn Andersson, Konrad Dybcio,
	Manivannan Sadhasivam, Rob Herring, Nirmal Patel,
	Jonathan Derrick, linux-arm-msm, linux-pci, linux-kernel, stable

On Fri, Nov 17, 2023 at 04:00:46PM -0800, David E. Box wrote:
> On Tue, 2023-11-14 at 14:55 +0100, Johan Hovold wrote:
> > Add a helper for enabling link states that can be used in contexts where
> > a pci_bus_sem read lock is already held (e.g. from pci_walk_bus()).
> > 
> > This helper will be used to fix a couple of potential deadlocks where
> > the current helper is called with the lock already held, hence the CC
> > stable tag.

> This solution is similar to the original one I proposed [1]. It just creates a
> separate locked function rather than using a flag. While the API is consistent
> with pci_disable_link_state_locked(), its usage is not. The vmd driver calls
> pci_enable_link_state() from pci_walk_bus() which was problematic for Bjorn [2].
> I owed an attempt to implement this as a fixup. However, now
> qcom_pcie_enabled_aspm() is also using it from pci_walk_bus(). The fixup could
> make sense for VMD since there it's fixing missing BIOS settings, but I'm not
> sure about qcom. Bjorn, do you still see issues with the use in pci_bus_walk()?

We need this for Qualcomm platforms where the boot firmware does not
enable ASPM, and the hotplug inconsistency was also discussed with Bjorn
here:

	https://lore.kernel.org/linux-pci/20231018164731.GA1365588@bhelgaas/

> [1]
> https://lore.kernel.org/lkml/20230321233849.3408339-1-david.e.box@linux.intel.com/
> 
> [2] https://lore.kernel.org/lkml/20230322205702.GA2493123@bhelgaas/

Johan

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

end of thread, other threads:[~2023-11-20  8:33 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20231114135553.32301-1-johan+linaro@kernel.org>
2023-11-14 13:55 ` [PATCH 1/6] PCI/ASPM: Add locked helper for enabling link state Johan Hovold
2023-11-15 14:26   ` kernel test robot
2023-11-15 16:06     ` Johan Hovold
2023-11-17 10:27       ` Manivannan Sadhasivam
2023-11-17 10:30         ` Johan Hovold
2023-11-17 10:50           ` Manivannan Sadhasivam
2023-11-17 10:28   ` Manivannan Sadhasivam
2023-11-18  0:00   ` David E. Box
2023-11-20  8:33     ` Johan Hovold
2023-11-14 13:55 ` [PATCH 2/6] PCI: vmd: Fix deadlock when enabling ASPM Johan Hovold
2023-11-17 10:28   ` Manivannan Sadhasivam

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox