RE: [PATCH] drivers core: Free dma_range_map when driver probe failed
> -Original Message- > From: Jim Quinlan > Sent: Monday, January 4, 2021 11:56 PM > To: Jim Quinlan ; Li, Meng > ; open list > Cc: Greg Kroah-Hartman ; raf...@kernel.org; > Hao, Kexin ; Jim Quinlan > ; Christoph Hellwig > Subject: Re: [PATCH] drivers core: Free dma_range_map when driver probe > failed > > > Subject: [PATCH] drivers core: Free dma_range_map when driver probe > > failed > > > > There will be memory leak if driver probe failed. Trace as below: > > backtrace: > > [<2415258f>] kmemleak_alloc+0x3c/0x50 > > [<f447ebe4>] __kmalloc+0x208/0x530 > > [<48bc7b3a>] of_dma_get_range+0xe4/0x1b0 > > [<41e39065>] of_dma_configure_id+0x58/0x27c > > [<6356866a>] platform_dma_configure+0x2c/0x40 > > .. > > [<0afcf9b5>] ret_from_fork+0x10/0x3c > > > > This issue is introduced by commit e0d072782c73("dma-mapping: > > introduce DMA range map, supplanting dma_pfn_offset "). It doesn't > > free dma_range_map when driver probe failed and cause above memory > > leak. So, add code to free it in error path. > > > > Fixes: e0d072782c73("dma-mapping: introduce DMA range map, > supplanting > > dma_pfn_offset ") > > Cc: sta...@vger.kernel.org > > Signed-off-by: Meng Li > > --- > > drivers/base/dd.c | 1 + > > 1 file changed, 1 insertion(+) > > > > diff --git a/drivers/base/dd.c b/drivers/base/dd.c index > > 148e81969e04..8e4871aa34bc 100644 > > --- a/drivers/base/dd.c > > +++ b/drivers/base/dd.c > > @@ -612,6 +612,7 @@ static int really_probe(struct device *dev, struct > > device_driver *drv) > > else if (drv->remove) > > drv->remove(dev); > > probe_failed: > > + kfree(dev->dma_range_map); > > if (dev->bus) > > blocking_notifier_call_chain(>bus->p->bus_notifier, > > > > BUS_NOTIFY_DRIVER_NOT_BOUND, dev); > > -- > > 2.17.1 > > > > -- > > Hi Meng, > > Sorry for the delay -- I was on vacation. I agree with you -- thanks. > However, note that in function device_release() in drivers/base/core.c > there is this line: > > kfree(dev->dma_range_map); > > Won't this also be called if all of the appropriate drivers' probes fail for > this > device, effecting a double kfree? Perhaps your patch could also set "dev- > >dma_range_map" to NULL after calling kfree()? > Hi Jim, Please discard my previous reply, because I had a misunderstand about what you suggested. I agree with you total, and I will set dma_range_map as NULL in really_probe() function when driver probe failed. I will sent V2 patch. Thanks, Limeng > Thanks much, > Jim Quinlan > Broadcom STB
RE: [PATCH] drivers core: Free dma_range_map when driver probe failed
> -Original Message- > From: Jim Quinlan > Sent: Monday, January 4, 2021 11:56 PM > To: Jim Quinlan ; Li, Meng > ; open list > Cc: Greg Kroah-Hartman ; raf...@kernel.org; > Hao, Kexin ; Jim Quinlan > ; Christoph Hellwig > Subject: Re: [PATCH] drivers core: Free dma_range_map when driver probe > failed > > > Subject: [PATCH] drivers core: Free dma_range_map when driver probe > > failed > > > > There will be memory leak if driver probe failed. Trace as below: > > backtrace: > > [<2415258f>] kmemleak_alloc+0x3c/0x50 > > [<f447ebe4>] __kmalloc+0x208/0x530 > > [<48bc7b3a>] of_dma_get_range+0xe4/0x1b0 > > [<41e39065>] of_dma_configure_id+0x58/0x27c > > [<6356866a>] platform_dma_configure+0x2c/0x40 > > .. > > [<0afcf9b5>] ret_from_fork+0x10/0x3c > > > > This issue is introduced by commit e0d072782c73("dma-mapping: > > introduce DMA range map, supplanting dma_pfn_offset "). It doesn't > > free dma_range_map when driver probe failed and cause above memory > > leak. So, add code to free it in error path. > > > > Fixes: e0d072782c73("dma-mapping: introduce DMA range map, > supplanting > > dma_pfn_offset ") > > Cc: sta...@vger.kernel.org > > Signed-off-by: Meng Li > > --- > > drivers/base/dd.c | 1 + > > 1 file changed, 1 insertion(+) > > > > diff --git a/drivers/base/dd.c b/drivers/base/dd.c index > > 148e81969e04..8e4871aa34bc 100644 > > --- a/drivers/base/dd.c > > +++ b/drivers/base/dd.c > > @@ -612,6 +612,7 @@ static int really_probe(struct device *dev, struct > > device_driver *drv) > > else if (drv->remove) > > drv->remove(dev); > > probe_failed: > > + kfree(dev->dma_range_map); > > if (dev->bus) > > blocking_notifier_call_chain(>bus->p->bus_notifier, > > > > BUS_NOTIFY_DRIVER_NOT_BOUND, dev); > > -- > > 2.17.1 > > > > -- > > Hi Meng, > > Sorry for the delay -- I was on vacation. I agree with you -- thanks. > However, note that in function device_release() in drivers/base/core.c > there is this line: > > kfree(dev->dma_range_map); > > Won't this also be called if all of the appropriate drivers' probes fail for > this > device, effecting a double kfree? If there are more than one driver compatible with the device, all the drivers will allocate memory for dma_range_map in function dev->bus->dma_configure(). If all the drivers probe failed, they all need to free memory. So, I think there is no double kfree case. Perhaps your patch could also set "dev- > >dma_range_map" to NULL after calling kfree()? I agree with you. Based on all drivers probe failed case, it is need to set dma_range_map as NULL after calling kfree() to avoid the NULL pointer. In additional, could you please help to check whether we also need to set dma_range_map as NULL in device_release()? Because I found out some other cases(for example, all drivers register failed) may free dma_range_map multiple times. Thanks, Limeng > > Thanks much, > Jim Quinlan > Broadcom STB
Re: [PATCH] drivers core: Free dma_range_map when driver probe failed
> Subject: [PATCH] drivers core: Free dma_range_map when driver probe failed > > There will be memory leak if driver probe failed. Trace as below: > backtrace: > [<2415258f>] kmemleak_alloc+0x3c/0x50 > [<f447ebe4>] __kmalloc+0x208/0x530 > [<48bc7b3a>] of_dma_get_range+0xe4/0x1b0 > [<41e39065>] of_dma_configure_id+0x58/0x27c > [<6356866a>] platform_dma_configure+0x2c/0x40 > .. > [<0afcf9b5>] ret_from_fork+0x10/0x3c > > This issue is introduced by commit e0d072782c73("dma-mapping: > introduce DMA range map, supplanting dma_pfn_offset "). It doesn't > free dma_range_map when driver probe failed and cause above > memory leak. So, add code to free it in error path. > > Fixes: e0d072782c73("dma-mapping: introduce DMA range map, supplanting > dma_pfn_offset ") > Cc: sta...@vger.kernel.org > Signed-off-by: Meng Li > --- > drivers/base/dd.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/base/dd.c b/drivers/base/dd.c > index 148e81969e04..8e4871aa34bc 100644 > --- a/drivers/base/dd.c > +++ b/drivers/base/dd.c > @@ -612,6 +612,7 @@ static int really_probe(struct device *dev, struct > device_driver *drv) > else if (drv->remove) > drv->remove(dev); > probe_failed: > + kfree(dev->dma_range_map); > if (dev->bus) > blocking_notifier_call_chain(>bus->p->bus_notifier, > BUS_NOTIFY_DRIVER_NOT_BOUND, > dev); > -- > 2.17.1 > > -- Hi Meng, Sorry for the delay -- I was on vacation. I agree with you -- thanks. However, note that in function device_release() in drivers/base/core.c there is this line: kfree(dev->dma_range_map); Won't this also be called if all of the appropriate drivers' probes fail for this device, effecting a double kfree? Perhaps your patch could also set "dev->dma_range_map" to NULL after calling kfree()? Thanks much, Jim Quinlan Broadcom STB
[PATCH] drivers core: Free dma_range_map when driver probe failed
From: Limeng There will be memory leak if driver probe failed. Trace as below: backtrace: [<2415258f>] kmemleak_alloc+0x3c/0x50 [] __kmalloc+0x208/0x530 [<48bc7b3a>] of_dma_get_range+0xe4/0x1b0 [<41e39065>] of_dma_configure_id+0x58/0x27c [<6356866a>] platform_dma_configure+0x2c/0x40 .. [<0afcf9b5>] ret_from_fork+0x10/0x3c This issue is introduced by commit e0d072782c73("dma-mapping: introduce DMA range map, supplanting dma_pfn_offset "). It doesn't free dma_range_map when driver probe failed and cause above memory leak. So, add code to free it in error path. Fixes: e0d072782c73("dma-mapping: introduce DMA range map, supplanting dma_pfn_offset ") Cc: sta...@vger.kernel.org Signed-off-by: Meng Li --- drivers/base/dd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 148e81969e04..8e4871aa34bc 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -612,6 +612,7 @@ static int really_probe(struct device *dev, struct device_driver *drv) else if (drv->remove) drv->remove(dev); probe_failed: + kfree(dev->dma_range_map); if (dev->bus) blocking_notifier_call_chain(>bus->p->bus_notifier, BUS_NOTIFY_DRIVER_NOT_BOUND, dev); -- 2.17.1