[opensuse-kernel] [PATCH RESEND] drm/tilcdc: Fix the error path in tilcdc_load()
From: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> The current error path calls tilcdc_unload() in case of an error to release the resources. However, this is wrong because not all resources have been allocated by the time an error occurs in tilcdc_load(). To fix it, this commit adds proper labels to bail out at the different stages in the load function, and release only the resources actually allocated. Tested-by: Darren Etheridge <detheridge@ti.com> Tested-by: Johannes Pointner <johannes.pointner@br-automation.com> Signed-off-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> Signed-off-by: Dave Airlie <airlied@redhat.com> Patch-mainline: v3.18-rc1 References: bko#86071 Git-commit: b478e336b3e75505707a11e78ef8b964ef0a03af Signed-off-by: Matwey V. Kornilov <matwey.kornilov@gmail.com> --- Hi, This is to fix kernel OOPS on BeagleBone Black introduced by 3a49012224ca9016658a831a327ff6a7fe5bb4f9 (and its copies in stable trees). See https://bugzilla.kernel.org/show_bug.cgi?id=86071 for reference. Kernal 3.16.3+ and 3.17+ are affected. This commit is for stable and openSUSE-13.2 branches. It also has been sent to upstream stable, but has not been included into 3.16.7 which was the last release in 3.16.x branch. Because of this, it is needed to be applied to openSUSE-13.2 directly. diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index aea4b766..79a34cb 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -84,6 +84,7 @@ static int modeset_init(struct drm_device *dev) if ((priv->num_encoders == 0) || (priv->num_connectors == 0)) { /* oh nos! */ dev_err(dev->dev, "no encoders/connectors found\n"); + drm_mode_config_cleanup(dev); return -ENXIO; } @@ -172,33 +173,37 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) dev->dev_private = priv; priv->wq = alloc_ordered_workqueue("tilcdc", 0); + if (!priv->wq) { + ret = -ENOMEM; + goto fail_free_priv; + } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev->dev, "failed to get memory resource\n"); ret = -EINVAL; - goto fail; + goto fail_free_wq; } priv->mmio = ioremap_nocache(res->start, resource_size(res)); if (!priv->mmio) { dev_err(dev->dev, "failed to ioremap\n"); ret = -ENOMEM; - goto fail; + goto fail_free_wq; } priv->clk = clk_get(dev->dev, "fck"); if (IS_ERR(priv->clk)) { dev_err(dev->dev, "failed to get functional clock\n"); ret = -ENODEV; - goto fail; + goto fail_iounmap; } priv->disp_clk = clk_get(dev->dev, "dpll_disp_ck"); if (IS_ERR(priv->clk)) { dev_err(dev->dev, "failed to get display clock\n"); ret = -ENODEV; - goto fail; + goto fail_put_clk; } #ifdef CONFIG_CPU_FREQ @@ -208,7 +213,7 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) CPUFREQ_TRANSITION_NOTIFIER); if (ret) { dev_err(dev->dev, "failed to register cpufreq notifier\n"); - goto fail; + goto fail_put_disp_clk; } #endif @@ -253,13 +258,13 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) ret = modeset_init(dev); if (ret < 0) { dev_err(dev->dev, "failed to initialize mode setting\n"); - goto fail; + goto fail_cpufreq_unregister; } ret = drm_vblank_init(dev, 1); if (ret < 0) { dev_err(dev->dev, "failed to initialize vblank\n"); - goto fail; + goto fail_mode_config_cleanup; } pm_runtime_get_sync(dev->dev); @@ -267,7 +272,7 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) pm_runtime_put_sync(dev->dev); if (ret < 0) { dev_err(dev->dev, "failed to install IRQ handler\n"); - goto fail; + goto fail_vblank_cleanup; } platform_set_drvdata(pdev, dev); @@ -283,13 +288,48 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) priv->fbdev = drm_fbdev_cma_init(dev, bpp, dev->mode_config.num_crtc, dev->mode_config.num_connector); + if (IS_ERR(priv->fbdev)) { + ret = PTR_ERR(priv->fbdev); + goto fail_irq_uninstall; + } drm_kms_helper_poll_init(dev); return 0; -fail: - tilcdc_unload(dev); +fail_irq_uninstall: + pm_runtime_get_sync(dev->dev); + drm_irq_uninstall(dev); + pm_runtime_put_sync(dev->dev); + +fail_vblank_cleanup: + drm_vblank_cleanup(dev); + +fail_mode_config_cleanup: + drm_mode_config_cleanup(dev); + +fail_cpufreq_unregister: + pm_runtime_disable(dev->dev); +#ifdef CONFIG_CPU_FREQ + cpufreq_unregister_notifier(&priv->freq_transition, + CPUFREQ_TRANSITION_NOTIFIER); +fail_put_disp_clk: + clk_put(priv->disp_clk); +#endif + +fail_put_clk: + clk_put(priv->clk); + +fail_iounmap: + iounmap(priv->mmio); + +fail_free_wq: + flush_workqueue(priv->wq); + destroy_workqueue(priv->wq); + +fail_free_priv: + dev->dev_private = NULL; + kfree(priv); return ret; } -- cgit v0.10.1 -- To unsubscribe, e-mail: opensuse-kernel+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-kernel+owner@opensuse.org
On Thu 30-10-14 20:42:14, matwey.kornilov@gmail.com wrote:
Hi,
This is to fix kernel OOPS on BeagleBone Black introduced by 3a49012224ca9016658a831a327ff6a7fe5bb4f9 (and its copies in stable trees). See https://bugzilla.kernel.org/show_bug.cgi?id=86071 for reference. Kernal 3.16.3+ and 3.17+ are affected. This commit is for stable and openSUSE-13.2 branches.
It also has been sent to upstream stable, but has not been included into 3.16.7 which was the last release in 3.16.x branch. Because of this, it is needed to be applied to openSUSE-13.2 directly.
It seems that Cannonical will be doing 3.16 stable kernels after all. http://thread.gmane.org/gmane.linux.kernel/1818070 So it might be worth reposting. I have pushed the patch into our tree. I've tried both your patch and the one from Linus' tree. I would just note that the default openSUSE-13.2 config doesn't enable CONFIG_DRM_TILCDC. So this is basically a noop for the distribution kernel. I assume you create your own kernel, right? Thanks -- Michal Hocko SUSE Labs -- To unsubscribe, e-mail: opensuse-kernel+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-kernel+owner@opensuse.org
2014-11-05 19:19 GMT+03:00 Michal Hocko <mhocko@suse.cz>:
On Thu 30-10-14 20:42:14, matwey.kornilov@gmail.com wrote:
Hi,
This is to fix kernel OOPS on BeagleBone Black introduced by 3a49012224ca9016658a831a327ff6a7fe5bb4f9 (and its copies in stable trees). See https://bugzilla.kernel.org/show_bug.cgi?id=86071 for reference. Kernal 3.16.3+ and 3.17+ are affected. This commit is for stable and openSUSE-13.2 branches.
It also has been sent to upstream stable, but has not been included into 3.16.7 which was the last release in 3.16.x branch. Because of this, it is needed to be applied to openSUSE-13.2 directly.
It seems that Cannonical will be doing 3.16 stable kernels after all. http://thread.gmane.org/gmane.linux.kernel/1818070 So it might be worth reposting.
I have pushed the patch into our tree. I've tried both your patch and the one from Linus' tree. I would just note that the default openSUSE-13.2 config doesn't enable CONFIG_DRM_TILCDC. So this is basically a noop for the distribution kernel. I assume you create your own kernel, right?
Are you sure? Right now I see CONFIG_DRM_TILCDC=y at http://kernel.opensuse.org/cgit/kernel-source/tree/config/armv7hl/default?h=... -- With best regards, Matwey V. Kornilov http://blog.matwey.name xmpp://0x2207@jabber.ru -- To unsubscribe, e-mail: opensuse-kernel+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-kernel+owner@opensuse.org
On Wed 05-11-14 20:25:16, Matwey V. Kornilov wrote:
2014-11-05 19:19 GMT+03:00 Michal Hocko <mhocko@suse.cz>:
On Thu 30-10-14 20:42:14, matwey.kornilov@gmail.com wrote:
Hi,
This is to fix kernel OOPS on BeagleBone Black introduced by 3a49012224ca9016658a831a327ff6a7fe5bb4f9 (and its copies in stable trees). See https://bugzilla.kernel.org/show_bug.cgi?id=86071 for reference. Kernal 3.16.3+ and 3.17+ are affected. This commit is for stable and openSUSE-13.2 branches.
It also has been sent to upstream stable, but has not been included into 3.16.7 which was the last release in 3.16.x branch. Because of this, it is needed to be applied to openSUSE-13.2 directly.
It seems that Cannonical will be doing 3.16 stable kernels after all. http://thread.gmane.org/gmane.linux.kernel/1818070 So it might be worth reposting.
I have pushed the patch into our tree. I've tried both your patch and the one from Linus' tree. I would just note that the default openSUSE-13.2 config doesn't enable CONFIG_DRM_TILCDC. So this is basically a noop for the distribution kernel. I assume you create your own kernel, right?
Are you sure? Right now I see CONFIG_DRM_TILCDC=y at
http://kernel.opensuse.org/cgit/kernel-source/tree/config/armv7hl/default?h=...
Ahh, OK, my local build was for x86_64. My fault, I should have checked: $ git grep CONFIG_DRM_TILCDC -- config config/armv6hl/default:CONFIG_DRM_TILCDC=y config/armv7hl/default:CONFIG_DRM_TILCDC=y config/armv7hl/lpae:CONFIG_DRM_TILCDC=m -- Michal Hocko SUSE Labs -- To unsubscribe, e-mail: opensuse-kernel+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-kernel+owner@opensuse.org
participants (3)
-
Matwey V. Kornilov
-
matwey.kornilov@gmail.com
-
Michal Hocko