* [PATCH v5 0/5] soc: qcom: ice: Fix race between qcom_ice_probe() and of_qcom_ice_get()
@ 2026-03-08 6:27 Manivannan Sadhasivam via B4 Relay
2026-03-08 6:27 ` [PATCH v5 1/5] " Manivannan Sadhasivam via B4 Relay
0 siblings, 1 reply; 3+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2026-03-08 6:27 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Adrian Hunter, Ulf Hansson,
Manivannan Sadhasivam, James E.J. Bottomley, Martin K. Petersen,
Abel Vesa, Abel Vesa
Cc: linux-arm-msm, linux-kernel, linux-mmc, linux-scsi, Sumit Garg,
mani, Neeraj Soni, Manivannan Sadhasivam, stable, Konrad Dybcio
Hi,
This series fixes the race betwen qcom_ice_probe() and of_qcom_ice_get()
but synchronizing the two APIs and properly propagating the error codes to
clients.
Merge Strategy
==============
Due to dependency, all patches should go through Qcom SoC tree.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
Changes in v5:
- Used Xarray instead of platform drvdata for passing the pointer since driver
core frees drvdata on probe failure.
- Link to v4: https://lore.kernel.org/r/20260302-qcom-ice-fix-v4-0-0e65740a5dcc@oss.qualcomm.com
Changes in v4:
- For supporting multi-ice instances in a SoC, stored the err ptr in platform
drvdata instead of in a global pointer.
- Link to v3: https://lore.kernel.org/r/20260223-qcom-ice-fix-v3-0-6ca5846329f7@oss.qualcomm.com
Changes in v3:
- Dropped the platform driver removal patch and used the ice_handle to pass
error codes. This was done as I learned that we need to have the platform
driver design going forward and also removing it introduces other issues.
- Link to v2: https://lore.kernel.org/r/20260210-qcom-ice-fix-v2-0-9c1ab5d6502c@oss.qualcomm.com
Changes in v2:
- Added MODULE_* macros back
- Removed spurious platform_device_put()
- Added patches to remove NULL return
---
Manivannan Sadhasivam (5):
soc: qcom: ice: Fix race between qcom_ice_probe() and of_qcom_ice_get()
soc: qcom: ice: Return -ENODEV if the ICE platform device is not found
soc: qcom: ice: Return proper error codes from devm_of_qcom_ice_get() instead of NULL
mmc: sdhci-msm: Remove NULL check from devm_of_qcom_ice_get()
scsi: ufs: ufs-qcom: Remove NULL check from devm_of_qcom_ice_get()
drivers/mmc/host/sdhci-msm.c | 10 ++++-----
drivers/soc/qcom/ice.c | 49 ++++++++++++++++++++++++++++++++------------
drivers/ufs/host/ufs-qcom.c | 10 ++++-----
3 files changed, 46 insertions(+), 23 deletions(-)
---
base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
change-id: 20260210-qcom-ice-fix-d2a3a045b32d
Best regards,
--
Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH v5 1/5] soc: qcom: ice: Fix race between qcom_ice_probe() and of_qcom_ice_get() 2026-03-08 6:27 [PATCH v5 0/5] soc: qcom: ice: Fix race between qcom_ice_probe() and of_qcom_ice_get() Manivannan Sadhasivam via B4 Relay @ 2026-03-08 6:27 ` Manivannan Sadhasivam via B4 Relay 2026-03-08 18:21 ` kernel test robot 0 siblings, 1 reply; 3+ messages in thread From: Manivannan Sadhasivam via B4 Relay @ 2026-03-08 6:27 UTC (permalink / raw) To: Bjorn Andersson, Konrad Dybcio, Adrian Hunter, Ulf Hansson, Manivannan Sadhasivam, James E.J. Bottomley, Martin K. Petersen, Abel Vesa, Abel Vesa Cc: linux-arm-msm, linux-kernel, linux-mmc, linux-scsi, Sumit Garg, mani, Neeraj Soni, Manivannan Sadhasivam, stable From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com> The current platform driver design causes probe ordering races with consumers (UFS, eMMC) due to ICE's dependency on SCM firmware calls. If ICE probe fails (missing ICE SCM or DT registers), devm_of_qcom_ice_get() loops with -EPROBE_DEFER, leaving consumers non-functional even when ICE should be gracefully disabled. devm_of_qcom_ice_get() doesn't know if the ICE driver probe has failed due to above reasons or it is waiting for the SCM driver. Moreover, there is no devlink dependency between ICE and consumer drivers as 'qcom,ice' is not considered as a DT 'supplier'. So the consumer drivers have no idea of when the ICE driver is going to probe. To address these issues, store the error pointer in a global xarray with ice node phandle as a key during probe in addition to the valid ice pointer and synchronize both qcom_ice_probe() and of_qcom_ice_get() using a mutex. If the xarray entry is NULL, then it implies that the driver is not probed yet, so return -EPROBE_DEFER. If it has any error pointer, return that error pointer directly. Otherwise, add the devlink as usual and return the valid pointer to the consumer. Xarray is used instead of platform drvdata, since driver core frees the drvdata during probe failure. So it cannot be used to pass the error pointer to the consumers. Note that this change only fixes the standalone ICE DT node bindings and not the ones with 'ice' range embedded in the consumer nodes, where there is no issue. Cc: <stable@vger.kernel.org> # 6.4 Fixes: 2afbf43a4aec ("soc: qcom: Make the Qualcomm UFS/SDCC ICE a dedicated driver") Reported-by: Sumit Garg <sumit.garg@oss.qualcomm.com> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com> --- drivers/soc/qcom/ice.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c index b203bc685cad..50da5a3e8073 100644 --- a/drivers/soc/qcom/ice.c +++ b/drivers/soc/qcom/ice.c @@ -16,6 +16,7 @@ #include <linux/of.h> #include <linux/of_platform.h> #include <linux/platform_device.h> +#include <linux/xarray.h> #include <linux/firmware/qcom/qcom_scm.h> @@ -113,6 +114,9 @@ struct qcom_ice { u8 hwkm_version; }; +DEFINE_XARRAY(ice_handles); +static DEFINE_MUTEX(ice_mutex); + static bool qcom_ice_check_supported(struct qcom_ice *ice) { u32 regval = qcom_ice_readl(ice, QCOM_ICE_REG_VERSION); @@ -631,6 +635,8 @@ static struct qcom_ice *of_qcom_ice_get(struct device *dev) return qcom_ice_create(&pdev->dev, base); } + guard(mutex)(&ice_mutex); + /* * If the consumer node does not provider an 'ice' reg range * (legacy DT binding), then it must at least provide a phandle @@ -647,12 +653,13 @@ static struct qcom_ice *of_qcom_ice_get(struct device *dev) return ERR_PTR(-EPROBE_DEFER); } - ice = platform_get_drvdata(pdev); - if (!ice) { - dev_err(dev, "Cannot get ice instance from %s\n", - dev_name(&pdev->dev)); + ice = xa_load(&ice_handles, pdev->dev.of_node->phandle); + if (IS_ERR_OR_NULL(ice)) { platform_device_put(pdev); - return ERR_PTR(-EPROBE_DEFER); + if (!ice) + return ERR_PTR(-EPROBE_DEFER); + else + return ice; } link = device_link_add(dev, &pdev->dev, DL_FLAG_AUTOREMOVE_SUPPLIER); @@ -716,24 +723,40 @@ EXPORT_SYMBOL_GPL(devm_of_qcom_ice_get); static int qcom_ice_probe(struct platform_device *pdev) { + unsigned long phandle = pdev->dev.of_node->phandle; struct qcom_ice *engine; void __iomem *base; + guard(mutex)(&ice_mutex); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) { dev_warn(&pdev->dev, "ICE registers not found\n"); + /* Store the error pointer for devm_of_qcom_ice_get() */ + xa_store(&ice_handles, phandle, base, GFP_KERNEL); return PTR_ERR(base); } engine = qcom_ice_create(&pdev->dev, base); - if (IS_ERR(engine)) + if (IS_ERR(engine)) { + /* Store the error pointer for devm_of_qcom_ice_get() */ + xa_store(&ice_handles, phandle, engine, GFP_KERNEL); return PTR_ERR(engine); + } - platform_set_drvdata(pdev, engine); + xa_store(&ice_handles, phandle, engine, GFP_KERNEL); return 0; } +static void qcom_ice_remove(struct platform_device *pdev) +{ + unsigned long phandle = pdev->dev.of_node->phandle; + + guard(mutex)(&ice_mutex); + xa_store(&ice_handles, phandle, NULL, GFP_KERNEL); +} + static const struct of_device_id qcom_ice_of_match_table[] = { { .compatible = "qcom,inline-crypto-engine" }, { }, @@ -742,6 +765,7 @@ MODULE_DEVICE_TABLE(of, qcom_ice_of_match_table); static struct platform_driver qcom_ice_driver = { .probe = qcom_ice_probe, + .remove = qcom_ice_remove, .driver = { .name = "qcom-ice", .of_match_table = qcom_ice_of_match_table, -- 2.51.0 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v5 1/5] soc: qcom: ice: Fix race between qcom_ice_probe() and of_qcom_ice_get() 2026-03-08 6:27 ` [PATCH v5 1/5] " Manivannan Sadhasivam via B4 Relay @ 2026-03-08 18:21 ` kernel test robot 0 siblings, 0 replies; 3+ messages in thread From: kernel test robot @ 2026-03-08 18:21 UTC (permalink / raw) To: Manivannan Sadhasivam via B4 Relay, Bjorn Andersson, Konrad Dybcio, Adrian Hunter, Ulf Hansson, Manivannan Sadhasivam, James E.J. Bottomley, Martin K. Petersen, Abel Vesa Cc: oe-kbuild-all, linux-arm-msm, linux-kernel, linux-mmc, linux-scsi, Sumit Garg, Neeraj Soni, stable Hi Manivannan, kernel test robot noticed the following build warnings: [auto build test WARNING on 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f] url: https://github.com/intel-lab-lkp/linux/commits/Manivannan-Sadhasivam-via-B4-Relay/soc-qcom-ice-Fix-race-between-qcom_ice_probe-and-of_qcom_ice_get/20260308-143016 base: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f patch link: https://lore.kernel.org/r/20260308-qcom-ice-fix-v5-1-e47e8a44b6c4%40oss.qualcomm.com patch subject: [PATCH v5 1/5] soc: qcom: ice: Fix race between qcom_ice_probe() and of_qcom_ice_get() config: arm-randconfig-r111-20260308 (https://download.01.org/0day-ci/archive/20260309/202603090214.7xup4lZa-lkp@intel.com/config) compiler: arm-linux-gnueabi-gcc (GCC) 10.5.0 sparse: v0.6.5-rc1 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260309/202603090214.7xup4lZa-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/202603090214.7xup4lZa-lkp@intel.com/ sparse warnings: (new ones prefixed by >>) >> drivers/soc/qcom/ice.c:117:1: sparse: sparse: symbol 'ice_handles' was not declared. Should it be static? >> drivers/soc/qcom/ice.c:736:49: sparse: sparse: incorrect type in argument 3 (different address spaces) @@ expected void *entry @@ got void [noderef] __iomem *[assigned] base @@ drivers/soc/qcom/ice.c:736:49: sparse: expected void *entry drivers/soc/qcom/ice.c:736:49: sparse: got void [noderef] __iomem *[assigned] base vim +/ice_handles +117 drivers/soc/qcom/ice.c 116 > 117 DEFINE_XARRAY(ice_handles); 118 static DEFINE_MUTEX(ice_mutex); 119 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-03-08 18:21 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-03-08 6:27 [PATCH v5 0/5] soc: qcom: ice: Fix race between qcom_ice_probe() and of_qcom_ice_get() Manivannan Sadhasivam via B4 Relay 2026-03-08 6:27 ` [PATCH v5 1/5] " Manivannan Sadhasivam via B4 Relay 2026-03-08 18:21 ` 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