Devicetree
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Anna Maniscalco" <anna.maniscalco2000@gmail.com>
Cc: dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
	robh@kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH RFC v2 03/14] drm/msm: look for lpac from dts
Date: Thu, 29 Oct 2026 14:09:55 +0000	[thread overview]
Message-ID: <sashiko-outbox-189482@kernel.org> (raw)
In-Reply-To: <20261029-descriptive-name-lpac-upstream-v2-3-a21a5c850961@gmail.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] drm/msm: adreno_gpu_init() links parent as consumer of child lpac_pdev
- [High] drm/msm: double put_device() on lpac_pdev when adreno_gpu_init() fails
- [High] drm/msm: adreno_remove() depopulates lpac_pdev before unbinding GPU
- [Medium] drm/msm: adreno_probe() leaks populated child devices on probe failure
--

commit 50cc2a02be0fe4cc4c62cff78b28bf0d3bb92f45
Author: Anna Maniscalco <anna.maniscalco2000@gmail.com>

drm/msm: look for lpac from dts

This commit populates child platform devices from the Adreno GPU device
tree node and looks up the "qcom,lpac" child device during GPU
initialization so its SMMU context bank and IOMMU domain can be wired up.

> diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
> index 7f20320ef66af..4d22223c3323c 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_device.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
[ ... ]
> @@ -271,6 +273,12 @@ static const struct component_ops a3xx_ops = {
>  
>  static int adreno_probe(struct platform_device *pdev)
>  {
> +	int ret = 0;
> +
> +	ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
> +	if (ret)
> +		return ret;
> +
>  	if (of_device_is_compatible(pdev->dev.of_node, "amd,imageon") ||
>  	    msm_gpu_no_components())
>  		return msm_gpu_probe(pdev, &a3xx_ops);

[Severity: Medium]
If msm_gpu_probe() or component_add() fails in adreno_probe() after
of_platform_populate() succeeds, does this leak the populated child
platform_device structures (such as gpu->lpac_pdev) because
of_platform_depopulate(&pdev->dev) is not called on the error path (or via
devm_of_platform_populate())?

> @@ -282,6 +290,8 @@ static void adreno_remove(struct platform_device *pdev)
>  {
>  	struct msm_drm_private *priv = platform_get_drvdata(pdev);
>  
> +	of_platform_depopulate(&pdev->dev);
> +
>  	if (priv->kms_init)
>  		component_del(&pdev->dev, &a3xx_ops);
>  	else

[Severity: High]
In adreno_remove(), shouldn't of_platform_depopulate(&pdev->dev) happen
after component_del() / msm_gpu_remove() rather than before?

Calling of_platform_depopulate(&pdev->dev) first unregisters
gpu->lpac_pdev via platform_device_unregister() -> device_del() while the
GPU is still bound and iommu->lpac_domain is still attached to
&gpu->lpac_pdev->dev.

During device_del(&gpu->lpac_pdev->dev), the bus notifier runs:

  iommu_release_device()
    -> __iommu_group_remove_device()
      -> __iommu_group_free_device()

which triggers WARN_ON(group->owner_cnt || group->domain !=
group->default_domain) and tears down the LPAC SMMU master state before
component_del() or msm_gpu_remove() runs adreno_unbind() ->
adreno_gpu_cleanup() -> msm_gpu_cleanup() to detach the IOMMU domain and
disable runtime PM on &gpu->lpac_pdev->dev.

> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> index f3fc7032fadcd..1dedeb19946ec 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
[ ... ]
> @@ -1200,6 +1205,18 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
>  	gpu->allow_relocs = config->info->family < ADRENO_6XX_GEN1;
>  	gpu->pdev = pdev;
>  
> +	lpac_node = of_get_compatible_child(pdev->dev.of_node, "qcom,lpac");
> +	if (lpac_node)
> +		gpu->lpac_pdev = of_find_device_by_node(lpac_node);
> +	if (gpu->lpac_pdev) {
> +		pm_runtime_enable(&gpu->lpac_pdev->dev);
> +		if (!device_link_add(&pdev->dev, &gpu->lpac_pdev->dev,
> +				     DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_CONSUMER))
> +			dev_err(&gpu->lpac_pdev->dev, "failed to link to lpac device\n");
> +	}
> +	if (lpac_node)
> +		of_node_put(lpac_node);

[Severity: High]
Will device_link_add(&pdev->dev, &gpu->lpac_pdev->dev, ...) always fail and
return NULL here?

In adreno_probe(), of_platform_populate() creates gpu->lpac_pdev with
&pdev->dev as its parent. In adreno_gpu_init(), device_link_add() is called
with &pdev->dev (the parent) as the consumer and &gpu->lpac_pdev->dev (its
child) as the supplier.

Inside drivers/base/core.c:device_link_add():

	if (!device_pm_initialized(supplier)
	    || (!(flags & DL_FLAG_SYNC_STATE_ONLY) &&
		  device_is_dependent(consumer, supplier))) {
		link = NULL;
		goto out;
	}

Because consumer (&pdev->dev) is the parent of supplier
(&gpu->lpac_pdev->dev), device_is_dependent(consumer, supplier) returns 1
via device_is_ancestor(consumer, supplier), rejecting the link as a
circular dependency. In addition, gpu->lpac_pdev has no driver bound to it,
so passing DL_FLAG_AUTOREMOVE_CONSUMER without DL_FLAG_STATELESS is not
valid for a driverless device.

As a result, the device link is never created and &gpu->lpac_pdev->dev
remains in RPM_SUSPENDED with usage_count == 0, causing
msm_iommu_tlb_flush_all() and msm_iommu_tlb_flush_walk() in
drivers/gpu/drm/msm/msm_iommu.c:

	if (pagetable->parent->lpac_dev &&
	    pm_runtime_get_if_in_use(pagetable->parent->lpac_dev)) {
		adreno_smmu = dev_get_drvdata(pagetable->parent->lpac_dev);

		pagetable->tlb->tlb_flush_all((void *)adreno_smmu->cookie);

		pm_runtime_put_autosuspend(pagetable->parent->lpac_dev);
	}

to skip all IOTLB invalidations on the LPAC SMMU context bank when buffers
are unmapped.

[ ... ]
> @@ -1241,6 +1260,10 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
>  
>  	return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base,
>  			gpu_name, &adreno_gpu_config);
> +err_put_lpac_pdev:
> +	if (gpu->lpac_pdev)
> +		put_device(&gpu->lpac_pdev->dev);
> +	return ret;
>  }
>  
>  void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
> @@ -1256,4 +1279,9 @@ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
>  		pm_runtime_disable(&priv->gpu_pdev->dev);
>  
>  	msm_gpu_cleanup(&adreno_gpu->base);
> +
> +	if (gpu->lpac_pdev) {
> +		pm_runtime_disable(&gpu->lpac_pdev->dev);
> +		put_device(&gpu->lpac_pdev->dev);
> +	}
>  }

[Severity: High]
When adreno_gpu_init() fails via err_put_lpac_pdev (when devm_kasprintf()
or adreno_get_pwrlevels() fails), doesn't this cause a double
put_device(&gpu->lpac_pdev->dev)?

The err_put_lpac_pdev path drops the reference on &gpu->lpac_pdev->dev
without clearing gpu->lpac_pdev (or disabling runtime PM), and the callers
of adreno_gpu_init() (such as a6xx_gpu_init()) then call their destroy
function on failure:

drivers/gpu/drm/msm/adreno/a6xx_gpu.c:a6xx_gpu_init() {
	...
	ret = adreno_gpu_init(dev, pdev, adreno_gpu, info->funcs, nr_rings);
	if (ret) {
		a6xx_destroy(&(a6xx_gpu->base.base));
		return ERR_PTR(ret);
	}
	...
}

which calls a6xx_destroy() -> adreno_gpu_cleanup(), seeing gpu->lpac_pdev
still non-NULL and calling put_device(&gpu->lpac_pdev->dev) a second time.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261029-descriptive-name-lpac-upstream-v2-0-a21a5c850961@gmail.com?part=3

  reply	other threads:[~2026-10-29 14:09 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-29 13:52 [RFC PATCH v2 00/14] Enable LPAC on a7xx series GPUs Anna Maniscalco
2026-10-29 13:52 ` [PATCH RFC v2 01/14] iommu: arm-smmu-qcom: Configure lpac device with split address space Anna Maniscalco
2026-10-29 14:21   ` sashiko-bot
2026-10-29 13:52 ` [PATCH RFC v2 02/14] drm/msm: add support for lpac_domain in msm_mmu Anna Maniscalco
2026-10-29 14:12   ` sashiko-bot
2026-10-29 13:52 ` [PATCH RFC v2 03/14] drm/msm: look for lpac from dts Anna Maniscalco
2026-10-29 14:09   ` sashiko-bot [this message]
2026-10-29 13:52 ` [PATCH RFC v2 04/14] arm64: dts: qcom: sm8650: move smmu sid 1 to new lpac device Anna Maniscalco
2026-10-29 14:17   ` sashiko-bot
2026-10-29 13:52 ` [PATCH RFC v2 05/14] firmware: qcom: scm: Configure LPAC aperture Anna Maniscalco
2026-10-29 14:08   ` sashiko-bot
2026-10-29 13:52 ` [PATCH RFC v2 06/14] DEBUGGING: print contextbank and other ttbrs on fault Anna Maniscalco
2026-10-29 13:52 ` [PATCH RFC v2 07/14] iommu: arm-smmu-qcom: Fixed mapping between sid and cb for gpu and lpac Anna Maniscalco
2026-10-29 14:13   ` sashiko-bot
2026-10-29 13:52 ` [PATCH RFC v2 08/14] temp: add LPAC regs Anna Maniscalco
2026-10-29 14:13   ` sashiko-bot
2026-10-29 13:52 ` [PATCH RFC v2 09/14] drm/msm: initialize LPAC ring Anna Maniscalco
2026-10-29 14:33   ` sashiko-bot
2026-10-29 13:52 ` [PATCH RFC v2 10/14] drm/msm: Add LPAC submitqueue Anna Maniscalco
2026-10-29 14:25   ` sashiko-bot
2026-10-29 13:52 ` [PATCH RFC v2 11/14] drm/msm: set ctxbank and asid based on ring Anna Maniscalco
2026-10-29 13:52 ` [PATCH RFC v2 12/14] drm/msm: add lpac ring to devcoredump Anna Maniscalco
2026-10-29 13:52 ` [PATCH RFC v2 13/14] drm/msm: gate lpac behind modparam Anna Maniscalco
2026-10-29 14:27   ` sashiko-bot
2026-10-29 13:52 ` [PATCH RFC v2 14/14] drm/msm: enable LPAC on gen70900 Anna Maniscalco
2026-10-29 14:45   ` sashiko-bot

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=sashiko-outbox-189482@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=anna.maniscalco2000@gmail.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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