Re: [PATCH 1/4] mm: migrate: use a folio in add_page_for_migration()

From: Kefeng Wang
Date: Wed Aug 09 2023 - 08:37:23 EST


Hi Mike

On 2023/8/8 2:45, Zi Yan wrote:
On 7 Aug 2023, at 8:20, Kefeng Wang wrote:

Hi Zi Yan and Matthew and Naoya,

On 2023/8/4 13:54, Kefeng Wang wrote:


On 2023/8/4 10:42, Zi Yan wrote:
On 3 Aug 2023, at 21:45, Kefeng Wang wrote:

On 2023/8/3 20:30, Matthew Wilcox wrote:
On Thu, Aug 03, 2023 at 03:13:21PM +0800, Kefeng Wang wrote:


...



   if (PageHuge(page))  // page must be a hugetlb page
    if (PageHead(page)) // page must be a head page, not tail
              isolate_hugetlb() // isolate the hugetlb page if head

After using folio,

   if (folio_test_hugetlb(folio)) // only check folio is hugetlb or not

I don't check the page is head or not, since the follow_page could
return a sub-page, so the check PageHead need be retained, right?

Right. It will prevent the kernel from trying to isolate the same hugetlb page
twice when two pages are in the same hugetlb folio. But looking at the
code, if you try to isolate an already-isolated hugetlb folio, isolate_hugetlb()
would return false, no error would show up. But it changes err value
from -EACCES to -EBUSY and user will see a different page status than before.


Before e66f17ff7177 ("mm/hugetlb: take page table lock in follow_huge_pmd()")
in v4.0, follow_page() will return NULL on tail page for Huagetlb page,
and move_pages() will return -ENOENT errno,but after that commit,
-EACCES is returned, which not match the manual,


When check man[1], the current -EACCES is not right, -EBUSY is not
precise but more suitable for this scenario,

     -EACCES
              The page is mapped by multiple processes and can be moved
              only if MPOL_MF_MOVE_ALL is specified.

     -EBUSY The page is currently busy and cannot be moved.  Try again
              later.  This occurs if a page is undergoing I/O or another
              kernel subsystem is holding a reference to the page.
    -ENOENT
              The page is not present.


I wonder why we do not have follow_folio() and returns -ENOENT error pointer
when addr points to a non head page. It would make this patch more folio if
follow_folio() can be used in place of follow_page(). One caveat is that
user will see -ENOENT instead of -EACCES after this change.


-ENOENT is ok, but maybe the man need to be updated too.

According to above analysis, -ENOENT is suitable when introduce the
follow_folio(), but when THP migrate support is introduced by
e8db67eb0ded ("mm: migrate: move_pages() supports thp migration") in
v4.14, the tail page will be turned into head page and return -EBUSY,

So should we unify errno(maybe use -ENOENT) about the tail page?





[1] https://man7.org/linux/man-pages/man2/move_pages.2.html

I think so. I think -EBUSY is more reasonable for tail pages. But there is
some subtle difference between THP and hugetlb from current code:

For THP, compound_head() is used to get the head page for isolation, this means
if user specifies a tail page address in move_pages(), the whole THP can be
migrated.

For hugetlb, only if user specifies the head page address of a hugetlb page,
the hugetlb page will be migrated. Otherwise, an error would show up.

Cc Mike to help us clarify the expected behavior of hugetlb.

Hi Mike, what is the expected behavior, if a user tries to use move_pages()
to migrate a non head page of a hugetlb page?

Could you give some advise, thanks


--
Best Regards,
Yan, Zi