Re: Possible bug when using dmam_alloc_coherent in conjonction with of_reserved_mem_device_release

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





Le sam., mai 22 2021 at 13:42:54 +0200, Olivier Dautricourt <olivier.dautricourt@xxxxxxxxxx> a écrit :
Hello Paul,

The 05/22/2021 11:28, Paul Cercueil wrote:
 Hi Olivier,


 Le ven., mai 21 2021 at 20:15:42 +0200, Olivier Dautricourt
 <olivier.dautricourt@xxxxxxxxxx> a écrit :
 > Hello all,
 >
 > I am facing a problem when using dmam_alloc_coherent (the managed
> version of dma_alloc_coherent) along with a device-specific reserved
 > memory
 > region using the CMA.
 >
 > My observation is on a kernel 5.10.19 (arm), as i'm unable to test
 > the exact
 > same configuration on a newer kernel. However it seems that the
 > relevent code
 > did not change too much since, so i think it's still applicable.
 >
 >
 > ....
 > The issue:
 >
 > I declare a reserved region on my board such as:
 >
 > mydevice_reserved: linux,cma {
 >         compatible = "shared-dma-pool";
 >         reusable;
 >         size = <0x2400000>;
 > };
 >
> and start the kernel with cma=0, i want my region to be reserved to
 > my device.
 >
 > My driver basically does:
 >
 > probe(dev):
 >       of_reserved_mem_device_init(dev)
 >       dmam_alloc_coherent(...)
 >
 > release(dev):
 >       of_reserved_mem_device_release(dev)

You must make sure that whatever is allocated or initialized is freed
 or deinitialized in the reverse order, which is not what will happen
 here: release(dev) will be called before the dev-managed cleanups.

 To fix your issue, either use dma_alloc_coherent() and call
 dma_free_coherent() in release(), or register
 of_reserved_mem_device_release() as a dev-managed cleanup function
 (which is what my driver does).

 Cheers,
 -Paul

as i was saying in my previous mail, i tried to register a devm action
to trigger of_reserved_mem_device_release on cleanup but it was still
called before dmam_alloc_coherent_memory's cleanup.

So my question is: How do you make sure that the managed cleanup routines
are executed in the right order ?

And when exactly do you register the devm action?

If you register it right after of_reserved_mem_device_init() and before dmam_alloc_coherent(), like in my driver, it should work fine (provided your .release doesn't call of_reserved_mem_device_release() itself) and you shouldn't have to do anything more than that.

-Paul


Should we have to care about that when using a managed
function that belongs to the core ?


Olivier

 > On driver detach, of_reserved_mem_device_release will call
 > rmem_cma_device_release which sets dev->cma_area = NULL;
 > Then the manager will try to free the dma memory allocated in the
 > probe:
 >
 > __free_from_contiguous -> dma_release_from_contiguous ->
 > cma_release(dev_get_cma_area(dev), ...);
 >
 > Except that now dev_get_cma_area will return
 > dma_contiguous_default_area
 > which is null in my setup:
 >
 > static inline struct cma *dev_get_cma_area(struct device *dev)
 > {
 >       if (dev && dev->cma_area) // dev->cma_area is null
 >               return dev->cma_area;
 >
 >       return dma_contiguous_default_area; // null in my setup
 > }
 >
 > and so cma_release will do nothing.
 >
> bool cma_release(struct cma *cma, const struct page *pages, unsigned
 > int count)
 > {
 >       unsigned long pfn;
 >
 >       if (!cma || !pages) // cma is NULL
 >               return false;
 >
 > __free_from_contiguous will fail silently because it ignores
 > dma_release_from_contiguous boolean result.
 >
> The driver will be unable to load and allocate memory again because
 > the
 > area allocated with dmam_alloc_coherent is not freed.
 > ...
 >
 > So i started to look at drivers using both dmam_alloc_coherent and
 > of_reserved_mem_device_release and found this driver:
 > (gpu/drm/ingenic/ingenic-drm-drv.c).
 > This is why i included the original author, Paul Cercueil, in the
 > loop.
 >
 > Q:
 >
 > I noticed that Paul used devm_add_action_or_reset to trigger
> of_reserved_mem_device_release on driver detach, is this because of
 > this
 > problem that we use a devm trigger here ?
 >
> I tried to do the same in my driver, but rmem_cma_device_release is
 > still
 > called before dmam_release, is there a way to force the order ?
 >
 > Is what i described a bug that needs fixing ?
 >
 >
 > Thank you,
 >
 >
 > Olivier
 >
 >







[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux PCI]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux