Messages in this thread | | | From | "Joakim Zhang" <> | Subject | 回复: [PATCH V1] dma-mapping: Set dma mem poi nter as NULL after it's freed | Date | Tue, 12 Dec 2023 14:30:12 +0000 |
| |
Hi maintainers,
> -----邮件原件----- > 发件人: Joakim Zhang <joakim.zhang@cixtech.com> > 发送时间: 2023年12月12日 13:22 > 收件人: hch@lst.de; m.szyprowski@samsung.com; robin.murphy@arm.com > 抄送: iommu@lists.linux.dev; linux-kernel@vger.kernel.org; > cix-kernel-upstream <cix-kernel-upstream@cixtech.com>; Joakim Zhang > <joakim.zhang@cixtech.com> > 主题: [PATCH V1] dma-mapping: Set dma_mem pointer as NULL after it's freed > > From: Joakim Zhang <joakim.zhang@cixtech.com> > > Reproduced with below sequence: > dma_declare_coherent_memory()->dma_release_coherent_memory() > ->dma_declare_coherent_memory()->"return -EBUSY" error > > It will return -EBUSY from the dma_assign_coherent_memory() in > dma_declare_coherent_memory(), the reason is that dev->dma_mem pointer > has not been set to NULL after it's freed. > > Go through the driver, found there is a issue in rmem_dma_device_release(), > the reserved memory has not been freed before "dev->dma_mem = NULL;". So > if user call of_reserved_mem_device_release(), will not free reserved mem in > fact. > > Fixes: cf65a0f6f6ff ("dma-mapping: move all DMA mapping code to > kernel/dma") > Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com> > --- > kernel/dma/coherent.c | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > > diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c index > c21abc77c53e..602e055fc1bf 100644 > --- a/kernel/dma/coherent.c > +++ b/kernel/dma/coherent.c > @@ -132,8 +132,10 @@ int dma_declare_coherent_memory(struct device > *dev, phys_addr_t phys_addr, > > void dma_release_coherent_memory(struct device *dev) { > - if (dev) > + if (dev) { > _dma_release_coherent_memory(dev->dma_mem); > + dev->dma_mem = NULL; > + } > } > > static void *__dma_alloc_from_coherent(struct device *dev, @@ -349,8 > +351,10 @@ static int rmem_dma_device_init(struct reserved_mem *rmem, > struct device *dev) static void rmem_dma_device_release(struct > reserved_mem *rmem, > struct device *dev) > { > - if (dev) > + if (dev) { > + _dma_release_coherent_memory(rmem->priv);
Per my understanding, this change may not need, since this is reserved memory from device tree, once calling of_reserved_mem_device_init_by_idx() to initialize, it will be added to "of_rmem_assigned_device_list" list. Even calling of_reserved_mem_device_release() to release it, it's unnecessary to unremap and free it, since it's "reserved memory", only need to unbind from the device. When we call of_reserved_mem_device_init_by_idx() again, just need to find it from the list then bind it.
Right?
Joakim
> dev->dma_mem = NULL; > + } > } > > static const struct reserved_mem_ops rmem_dma_ops = { > -- > 2.25.1
| |