Re: [PATCH 3.4 088/125] ser_gigaset: fix deallocation of platform device structure
flat view
From: Paul Bolle <hidden>
Date: 2016-10-12 12:53:46
Also in:
lkml
Zefan Li, On Wed, 2016-10-12 at 20:33 +0800, lizf@kernel.org wrote:
When shutting down the device, the struct ser_cardstate must not be
kfree()d immediately after the call to platform_device_unregister()
since the embedded struct platform_device is still in use.
Move the kfree() call to the release method instead.
Signed-off-by: Tilman Schmidt <redacted>
Fixes: 2869b23e4b95 ("drivers/isdn/gigaset: new M101 driver (v2)")
Reported-by: Sasha Levin <redacted>
Signed-off-by: Paul Bolle <redacted>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Zefan Li <redacted>There has been a follow up for this fix. I'll have to dive into my archive to see why that was needed. It was complicated, because there has been a short period in which this fix was correct. Something like that, I'm speaking from memory. (Perhaps Tilman's memory is less imperfect.) I'll try get back to this shortly (in a day or so). Thanks, Paul Bolle
quoted hunk ↗ jump to hunk
--- drivers/isdn/gigaset/ser-gigaset.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)diff --git a/drivers/isdn/gigaset/ser-gigaset.cb/drivers/isdn/gigaset/ser-gigaset.c index 6f3fd4c..3cdfcd0 100644--- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c@@ -371,19 +371,23 @@ static void gigaset_freecshw(struct cardstate*cs) tasklet_kill(&cs->write_tasklet); if (!cs->hw.ser) return; - dev_set_drvdata(&cs->hw.ser->dev.dev, NULL); platform_device_unregister(&cs->hw.ser->dev); - kfree(cs->hw.ser); - cs->hw.ser = NULL; } static void gigaset_device_release(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); + struct cardstate *cs = dev_get_drvdata(dev); /* adapted from platform_device_release() in drivers/base/platform.c */ kfree(dev->platform_data); kfree(pdev->resource); + + if (!cs) + return; + dev_set_drvdata(dev, NULL); + kfree(cs->hw.ser); + cs->hw.ser = NULL; } /*