On Wed 07-04-21 10:27:49, Oscar Salvador wrote: > On Mon, Apr 05, 2021 at 04:00:40PM -0700, Mike Kravetz wrote: [...] > > @@ -2671,22 +2682,34 @@ static void try_to_free_low(struct hstate *h, unsigned long count, > > nodemask_t *nodes_allowed) > > { > > int i; > > + struct page *page, *next; > > + LIST_HEAD(page_list); > > > > if (hstate_is_gigantic(h)) > > return; > > > > + /* > > + * Collect pages to be freed on a list, and free after dropping lock > > + */ > > for_each_node_mask(i, *nodes_allowed) { > > - struct page *page, *next; > > struct list_head *freel = &h->hugepage_freelists[i]; > > list_for_each_entry_safe(page, next, freel, lru) { > > if (count >= h->nr_huge_pages) > > - return; > > + goto out; > > if (PageHighMem(page)) > > continue; > > remove_hugetlb_page(h, page, false); > > - update_and_free_page(h, page); > > + list_add(&page->lru, &page_list); > > } > > } > > + > > +out: > > + spin_unlock(&hugetlb_lock); > > + list_for_each_entry_safe(page, next, &page_list, lru) { > > + update_and_free_page(h, page); > > + cond_resched(); > > + } > > + spin_lock(&hugetlb_lock); > > Can we get here with an empty list? An emoty page_list? If yes then sure, this can happen but list_for_each_entry_safe will simply not iterate. Or what do you mean? -- Michal Hocko SUSE Labs