在 2024/6/4 下午9:47, David Hildenbrand 写道:
On 04.06.24 12:48, yangge1116@xxxxxxx wrote:
From: yangge <yangge1116@xxxxxxx>
If a page is added in pagevec, its ref count increases one, remove
the page from pagevec decreases one. Page migration requires the
page is not referenced by others except page mapping. Before
migrating a page, we should try to drain the page from pagevec in
case the page is in it, however, folio_test_lru() is not sufficient
to tell whether the page is in pagevec or not, if the page is in
pagevec, the migration will fail.
Remove the condition and drain lru once to ensure the page is not
referenced by pagevec.
What you are saying is that we might have a page on which
folio_test_lru() succeeds, that was added to one of the cpu_fbatches,
correct?
Yes
Can you describe under which circumstances that happens?
If we call folio_activate() to move a page from inactive LRU list to
active LRU list, the page is not only in LRU list, but also in one of
the cpu_fbatches.
void folio_activate(struct folio *folio)
{
if (folio_test_lru(folio) && !folio_test_active(folio) &&
!folio_test_unevictable(folio)) {
struct folio_batch *fbatch;
folio_get(folio);
//After this, folio is in LRU list, and its ref count have
increased one.
local_lock(&cpu_fbatches.lock);
fbatch = this_cpu_ptr(&cpu_fbatches.activate);
folio_batch_add_and_move(fbatch, folio, folio_activate_fn);
local_unlock(&cpu_fbatches.lock);
}
}