Rafael Aquini <aquini@xxxxxxxxxx> writes: >> >> If there's a race, we should fix the race. But the code path for >> swapcache insertion is, >> >> add_to_swap() >> get_swap_page() /* Return if fails to allocate */ >> add_to_swap_cache() >> SetPageSwapCache() >> >> While the code path to split THP is, >> >> split_huge_page_to_list() >> if PageSwapCache() >> split_swap_cluster() >> >> Both code paths are protected by the page lock. So there should be some >> other reasons to trigger the bug. > > As mentioned above, no they seem to not be protected (at least, not the > same page, depending on the case). While add_to_swap() will assure a > page_lock on the compound head, split_huge_page_to_list() does not. > int split_huge_page_to_list(struct page *page, struct list_head *list) { struct page *head = compound_head(page); struct pglist_data *pgdata = NODE_DATA(page_to_nid(head)); struct deferred_split *ds_queue = get_deferred_split_queue(head); struct anon_vma *anon_vma = NULL; struct address_space *mapping = NULL; int count, mapcount, extra_pins, ret; unsigned long flags; pgoff_t end; VM_BUG_ON_PAGE(is_huge_zero_page(head), head); VM_BUG_ON_PAGE(!PageLocked(head), head); I found there's page lock checking in split_huge_page_to_list(). Best Regards, Huang, Ying