On Thu, Jul 25, 2024 at 8:02 AM Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote: > > On Thu, Jul 25, 2024 at 02:28:27AM +0800, Hailong.Liu wrote: > > > if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMALLOC) || > > > - page_shift == PAGE_SHIFT) > > > - return vmap_small_pages_range_noflush(addr, end, prot, pages); > > > + page_shift == PAGE_SHIFT || > > > + page_private(pages[0]) == VM_AREA_ALLOC_PAGES_FALLBACK) { > > > + int ret = vmap_small_pages_range_noflush(addr, end, prot, pages); > > > + > > > + set_page_private(pages[0], 0); > > > + return ret; > > > + } > > > > > > for (i = 0; i < nr; i += 1U << (page_shift - PAGE_SHIFT)) { > > > int err; > > > @@ -3583,6 +3590,7 @@ vm_area_alloc_pages(gfp_t gfp, int nid, > > > > > > /* fall back to the zero order allocations */ > > > alloc_gfp |= __GFP_NOFAIL; > > > + fallback = true; > > Sry for my mistake, I forget define fallback here. > > BTW, This is not the optimal solution. Does anyone have a better idea? Glad to > > hear:) > > Yeah, I really don't like this approach. You could return a small > struct indicating both nr_allocated and whether you had to fall back. > Or you could pass a bool * parameter. They're both pretty nasty. Yes, I feel returning a bool won't work very well. the result could be a mixture of PMD and PTE if the allocated pages are larger than a PMD. For example, if we allocate 8MB, it might result in the first 4MB being 2* PMD, and the remaining 4MB being PTE order-0 pages. I am also curious what will happen if we allocate 3MB(1PMD + some PTEs), is the below doing the correct mapping? do { ret = vmap_pages_range(addr, addr + size, prot, area->pages, page_shift); if (nofail && (ret < 0)) schedule_timeout_uninterruptible(1); } while (nofail && (ret < 0)); Is it possible we have only mapped the first 2MB if page_shift is PMD? Thanks Barry