* [RESEND PATCH 1/5] drm/msm/a6xx: Avoid freeing gmu resources multiple times @ 2019-05-22 17:36 Sean Paul 2019-05-22 17:36 ` [PATCH 4/5] drm/msm/a6xx: Remove devm calls from gmu driver Sean Paul [not found] ` <20190522173656.162006-1-sean-p7yTbzM4H96eqtR555YLDQ@public.gmane.org> 0 siblings, 2 replies; 5+ messages in thread From: Sean Paul @ 2019-05-22 17:36 UTC (permalink / raw) To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW Cc: Sean Paul, Rob Clark, Sean Paul, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA From: Sean Paul <seanpaul@chromium.org> The driver checks for gmu->mmio as a sign that the device has been initialized, however there are failures in probe below the mmio init. If one of those is hit, mmio will be non-null but freed. In that case, a6xx_gmu_probe will return an error to a6xx_gpu_init which will in turn call a6xx_gmu_remove which checks gmu->mmio and tries to free resources for a second time. This causes a great boom. Fix this by adding an initialized member to gmu which is set on successful probe and cleared on removal. Signed-off-by: Sean Paul <seanpaul@chromium.org> --- Resending as part of the set since some later patches depend on it drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 14 +++++++++----- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 38e2cfa9cec7..aa84edb25d91 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -74,7 +74,7 @@ bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu) u32 val; /* This can be called from gpu state code so make sure GMU is valid */ - if (IS_ERR_OR_NULL(gmu->mmio)) + if (!gmu->initialized) return false; val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS); @@ -90,7 +90,7 @@ bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu) u32 val; /* This can be called from gpu state code so make sure GMU is valid */ - if (IS_ERR_OR_NULL(gmu->mmio)) + if (!gmu->initialized) return false; val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS); @@ -695,7 +695,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) struct a6xx_gmu *gmu = &a6xx_gpu->gmu; int status, ret; - if (WARN(!gmu->mmio, "The GMU is not set up yet\n")) + if (WARN(!gmu->initialized, "The GMU is not set up yet\n")) return 0; gmu->hung = false; @@ -765,7 +765,7 @@ bool a6xx_gmu_isidle(struct a6xx_gmu *gmu) { u32 reg; - if (!gmu->mmio) + if (!gmu->initialized) return true; reg = gmu_read(gmu, REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS); @@ -1227,7 +1227,7 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) { struct a6xx_gmu *gmu = &a6xx_gpu->gmu; - if (IS_ERR_OR_NULL(gmu->mmio)) + if (!gmu->initialized) return; a6xx_gmu_stop(a6xx_gpu); @@ -1245,6 +1245,8 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) iommu_detach_device(gmu->domain, gmu->dev); iommu_domain_free(gmu->domain); + + gmu->initialized = false; } int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node) @@ -1309,6 +1311,8 @@ int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node) /* Set up the HFI queues */ a6xx_hfi_init(gmu); + gmu->initialized = true; + return 0; err: a6xx_gmu_memory_free(gmu, gmu->hfi); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index bedd8e6a63aa..39a26dd63674 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -75,6 +75,7 @@ struct a6xx_gmu { struct a6xx_hfi_queue queues[2]; + bool initialized; bool hung; }; -- Sean Paul, Software Engineer, Google / Chromium OS _______________________________________________ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 4/5] drm/msm/a6xx: Remove devm calls from gmu driver 2019-05-22 17:36 [RESEND PATCH 1/5] drm/msm/a6xx: Avoid freeing gmu resources multiple times Sean Paul @ 2019-05-22 17:36 ` Sean Paul [not found] ` <20190522173656.162006-1-sean-p7yTbzM4H96eqtR555YLDQ@public.gmane.org> 1 sibling, 0 replies; 5+ messages in thread From: Sean Paul @ 2019-05-22 17:36 UTC (permalink / raw) To: dri-devel, freedreno; +Cc: Sean Paul, Sean Paul, linux-arm-msm From: Sean Paul <seanpaul@chromium.org> The gmu driver is initalized and cleaned up with calls from the gpu driver. As such, the platform device stays valid after a6xx_gmu_remove is called and the device managed resources are not freed. In the case of gpu probe failures or unbind, these resources will remain managed. If the gpu bind is run again (eg: if there's a probe defer somewhere in msm), these resources will be initialized again for the same device, creating multiple references. In the case of irqs, this causes failures since the irqs are not shared (nor should they be). This patch removes all devm_* calls and manually cleans things up in gmu_remove. Signed-off-by: Sean Paul <seanpaul@chromium.org> --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 7465423e9b71..701b813fa38a 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -505,9 +505,9 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) err: if (!IS_ERR_OR_NULL(pdcptr)) - devm_iounmap(gmu->dev, pdcptr); + iounmap(pdcptr); if (!IS_ERR_OR_NULL(seqptr)) - devm_iounmap(gmu->dev, seqptr); + iounmap(seqptr); } /* @@ -1197,7 +1197,7 @@ static void __iomem *a6xx_gmu_get_mmio(struct platform_device *pdev, return ERR_PTR(-EINVAL); } - ret = devm_ioremap(&pdev->dev, res->start, resource_size(res)); + ret = ioremap(res->start, resource_size(res)); if (!ret) { DRM_DEV_ERROR(&pdev->dev, "Unable to map the %s registers\n", name); return ERR_PTR(-EINVAL); @@ -1213,10 +1213,10 @@ static int a6xx_gmu_get_irq(struct a6xx_gmu *gmu, struct platform_device *pdev, irq = platform_get_irq_byname(pdev, name); - ret = devm_request_irq(&pdev->dev, irq, handler, IRQF_TRIGGER_HIGH, - name, gmu); + ret = request_irq(irq, handler, IRQF_TRIGGER_HIGH, name, gmu); if (ret) { - DRM_DEV_ERROR(&pdev->dev, "Unable to get interrupt %s\n", name); + DRM_DEV_ERROR(&pdev->dev, "Unable to get interrupt %s %d\n", + name, ret); return ret; } @@ -1241,12 +1241,18 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) dev_pm_domain_detach(gmu->gxpd, false); } + iounmap(gmu->mmio); + gmu->mmio = NULL; + a6xx_gmu_memory_free(gmu, gmu->hfi); iommu_detach_device(gmu->domain, gmu->dev); iommu_domain_free(gmu->domain); + free_irq(gmu->gmu_irq, gmu); + free_irq(gmu->hfi_irq, gmu); + gmu->initialized = false; } -- Sean Paul, Software Engineer, Google / Chromium OS _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply related [flat|nested] 5+ messages in thread
[parent not found: <20190522173656.162006-1-sean-p7yTbzM4H96eqtR555YLDQ@public.gmane.org>]
* [PATCH 2/5] drm/msm/a6xx: Remove duplicate irq disable from remove [not found] ` <20190522173656.162006-1-sean-p7yTbzM4H96eqtR555YLDQ@public.gmane.org> @ 2019-05-22 17:36 ` Sean Paul 2019-05-22 17:36 ` [PATCH 3/5] drm/msm/a6xx: Check for ERR or NULL before iounmap Sean Paul 2019-05-22 17:36 ` [PATCH 5/5] drm/msm/a6xx: Rename a6xx_gmu_probe to a6xx_gmu_init Sean Paul 2 siblings, 0 replies; 5+ messages in thread From: Sean Paul @ 2019-05-22 17:36 UTC (permalink / raw) To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW Cc: Sean Paul, Rob Clark, Sean Paul, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA From: Sean Paul <seanpaul@chromium.org> a6xx_gmu_stop() already calls this function via shutdown or force_stop, so it's not necessary to call it twice. This also knocks the irq depth count out of sync, so nice to avoid. Signed-off-by: Sean Paul <seanpaul@chromium.org> --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index aa84edb25d91..742c8ff9a61c 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -1239,7 +1239,6 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) dev_pm_domain_detach(gmu->gxpd, false); } - a6xx_gmu_irq_disable(gmu); a6xx_gmu_memory_free(gmu, gmu->hfi); iommu_detach_device(gmu->domain, gmu->dev); -- Sean Paul, Software Engineer, Google / Chromium OS _______________________________________________ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/5] drm/msm/a6xx: Check for ERR or NULL before iounmap [not found] ` <20190522173656.162006-1-sean-p7yTbzM4H96eqtR555YLDQ@public.gmane.org> 2019-05-22 17:36 ` [PATCH 2/5] drm/msm/a6xx: Remove duplicate irq disable from remove Sean Paul @ 2019-05-22 17:36 ` Sean Paul 2019-05-22 17:36 ` [PATCH 5/5] drm/msm/a6xx: Rename a6xx_gmu_probe to a6xx_gmu_init Sean Paul 2 siblings, 0 replies; 5+ messages in thread From: Sean Paul @ 2019-05-22 17:36 UTC (permalink / raw) To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW Cc: Sean Paul, Rob Clark, Sean Paul, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA From: Sean Paul <seanpaul@chromium.org> pdcptr and seqptr aren't necessarily valid, check them before trying to unmap them. Signed-off-by: Sean Paul <seanpaul@chromium.org> --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 742c8ff9a61c..7465423e9b71 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -504,8 +504,10 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) wmb(); err: - devm_iounmap(gmu->dev, pdcptr); - devm_iounmap(gmu->dev, seqptr); + if (!IS_ERR_OR_NULL(pdcptr)) + devm_iounmap(gmu->dev, pdcptr); + if (!IS_ERR_OR_NULL(seqptr)) + devm_iounmap(gmu->dev, seqptr); } /* -- Sean Paul, Software Engineer, Google / Chromium OS _______________________________________________ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 5/5] drm/msm/a6xx: Rename a6xx_gmu_probe to a6xx_gmu_init [not found] ` <20190522173656.162006-1-sean-p7yTbzM4H96eqtR555YLDQ@public.gmane.org> 2019-05-22 17:36 ` [PATCH 2/5] drm/msm/a6xx: Remove duplicate irq disable from remove Sean Paul 2019-05-22 17:36 ` [PATCH 3/5] drm/msm/a6xx: Check for ERR or NULL before iounmap Sean Paul @ 2019-05-22 17:36 ` Sean Paul 2 siblings, 0 replies; 5+ messages in thread From: Sean Paul @ 2019-05-22 17:36 UTC (permalink / raw) To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW Cc: Sean Paul, Rob Clark, Sean Paul, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA From: Sean Paul <seanpaul@chromium.org> This rename makes it more clear that everything initialized in the _init function must be cleaned up in a6xx_gmu_remove. This will hopefully dissuade people from using device managed resources (for reasons laid out in the previous patch). Signed-off-by: Sean Paul <seanpaul@chromium.org> --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 2 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 2 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 701b813fa38a..26f44a187eda 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -1256,7 +1256,7 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) gmu->initialized = false; } -int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node) +int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) { struct a6xx_gmu *gmu = &a6xx_gpu->gmu; struct platform_device *pdev = of_find_device_by_node(node); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index e74dce474250..1f9f4b0a9656 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -854,7 +854,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) /* FIXME: How do we gracefully handle this? */ BUG_ON(!node); - ret = a6xx_gmu_probe(a6xx_gpu, node); + ret = a6xx_gmu_init(a6xx_gpu, node); if (ret) { a6xx_destroy(&(a6xx_gpu->base.base)); return ERR_PTR(ret); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index b46279eb18c5..64399554f2dd 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -53,7 +53,7 @@ bool a6xx_gmu_isidle(struct a6xx_gmu *gmu); int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state); void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state); -int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node); +int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node); void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu); void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq); -- Sean Paul, Software Engineer, Google / Chromium OS _______________________________________________ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2019-05-22 17:37 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-05-22 17:36 [RESEND PATCH 1/5] drm/msm/a6xx: Avoid freeing gmu resources multiple times Sean Paul 2019-05-22 17:36 ` [PATCH 4/5] drm/msm/a6xx: Remove devm calls from gmu driver Sean Paul [not found] ` <20190522173656.162006-1-sean-p7yTbzM4H96eqtR555YLDQ@public.gmane.org> 2019-05-22 17:36 ` [PATCH 2/5] drm/msm/a6xx: Remove duplicate irq disable from remove Sean Paul 2019-05-22 17:36 ` [PATCH 3/5] drm/msm/a6xx: Check for ERR or NULL before iounmap Sean Paul 2019-05-22 17:36 ` [PATCH 5/5] drm/msm/a6xx: Rename a6xx_gmu_probe to a6xx_gmu_init Sean Paul
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).