On Mon, May 04, 2020 at 03:10:46PM -0700, Alexander Duyck wrote: > So we cannot stop in the middle of a max order block. That shouldn't > be possible as part of the issue is that the buddy allocator will > attempt to access the buddy for the page which could cause issues if > it tries to merge the page with one that is not initialized. So if > your code supports that then it is definitely broken. That was one of > the reasons for all of the variable weirdness in > deferred_init_maxorder. I was going through and making certain that > while we were initializing the range we were freeing the pages in > MAX_ORDER aligned blocks and skipping over whatever reserved blocks > were there. Basically it was handling the case where a single > MAX_ORDER block could span multiple ranges. > > On x86 this was all pretty straightforward and I don't believe we > needed the code, but I seem to recall there were some other > architectures that had more complex memory layouts at the time and > that was one of the reasons why I had to be careful to wait until I > had processed the full MAX_ORDER block before I could start freeing > the pages, otherwise it would start triggering memory corruptions. Yes, thanks, I missed the case where deferred_grow_zone could stop mid-max-order-block. Maybe it's better to leave deferred_init_maxorder alone and adapt the multithreading to the existing implementation. That'd mean dealing with the pesky opaque index somehow, so deferred_init_mem_pfn_range_in_zone() could be generalized to find it in the thread function based on the start/end range, or it could be maintained as part of the range that padata passes to the thread function. Or, keep this patch but make sure deferred_grow_zone stops on a max-order-aligned boundary.