I have not yet received a report of the same issue. But I agree that this problem is likely to occur even if it is low probability.
Perhaps I should clarify my setup a little bit more. The issue can be reliably reproduced on my laptop. It has 8 GBs of RAM (pretty common amount nowadays) and runs an unmodified Fedora 32 kernel. Also, I use zswap, which seems to be contributing to fragmentation as
well.
I think it would be more appropriate to use kvcalloc and kvfree instead.
I do not think this is really needed. Upcase table allocation is relatively large (32 pages of 4KB size) and happens only once, when the drive is being mounted. Also, exfat driver does not rely on the fact that the table is physically contiguous. That said, vmalloc/vfree seems to be the best option, according to kernel's "Memory Allocation Guide".
The address range available for vmalloc() allocations is limited on 32-bit systems. If all kernel codes that need non-contiguous memory of the size order 1 or larger try to allocate it by only vmalloc(), the address range for vmalloc() could be insufficient. So, I think it would be better to give kmalloc() "one" chance.
I know that kvmalloc() only tries kmalloc() once (noretry, nowarn) and if it fails, it immediately falls back to vmalloc(). Therefore, I think kvmalloc() and kvfree() are the best solution for solving the problem you are facing and the problem I mentioned above.
Could you send me patch v3 that uses kvcalloc() and kvfree()?
-- Artem