Laura, On Mon, Dec 17, 2018 at 01:57:37PM -0800, Laura Abbott wrote: > (...) > > The ARM dma layer uses gfpflags_allow_blocking to decide if it should > use CMA vs. the atomic pool: > > static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags) > { > return !!(gfp_flags & __GFP_DIRECT_RECLAIM); > } > > That's not sufficient to cover the writeback case. This is > used in multiple DMA allocations (arm64 and intel-iommu at > first pass) so I think we need a new gfpflags_allow_writeback > for deciding if CMA should be used. > > Thanks, > Laura To let you know, in a first instance, I hacked the function __dma_alloc() to take the GPF_NOIO flag into consideration (which is likely the same fix you mention above; except that it applies only to that function, in order to make sure it does not break things somewherelse that I do not control). *handle = ARM_MAPPING_ERROR; allowblock = gfpflags_allow_blocking(gfp); + /* Following is a work-around to prevent from deadlock in CMA + * allocator when a task triggers for a page migration. Others + * tasks may wants to migrate theirs pages using CMA but get + * locked because the first task already holds the mutex. + * + * Because CMA is blocking, it refuses to go for CMA if GFP_NOIO + * flag is set. + */ + if (allowblock) + allowblock = !!(gfp & GFP_NOIO); cma = allowblock ? dev_get_cma_area(dev) : false; I thought it was not working until I decided to give it a retry today... and it works! Regards, Gael