I have a code that fails calling ioremap()
for 4M region. Trying to debug the reason, I've found out that if you call ioremap
it will try to allocate continuous addresses with a very large alignment (depending on the size of the area you want to allocate). The code that computes this alignment is in __get_vm_area_node()
function (mm/vmalloc.c
) and it looks like this:
if (flags & VM_IOREMAP) {
int bit = fls(size);
if (bit > IOREMAP_MAX_ORDER)
bit = IOREMAP_MAX_ORDER;
else if (bit < PAGE_SHIFT)
bit = PAGE_SHIFT;
align = 1ul << bit;
}
On ARM, IOREMAP_MAX_ORDER
is defined as 23
. This means that in my case, ioremap
needs not only 4M of continues addressing in vmalloc
area but it also has to be aligned to 4M.
I wasn't able to find any information on why this alignment is needed. I even tried using git blame to see the commit that introduces this change but it seems the code is older than git history so I couldn't find anything.