Re: [RFC PATCH v6 2/5] mm: migrate: Add migrate_misplaced_folios_batch()

Bharata B Rao
2026-04-22T03:27:17Z

On 21-Apr-26 9:35 PM, Gregory Price wrote:
> On Tue, Apr 21, 2026 at 08:55:02PM +0530, Donet Tom wrote:
>>> +/**
>>> + * migrate_misplaced_folios_batch() - Batch variant of migrate_misplaced_folio
>>> + * Attempts to migrate a folio list to the specified destination.
>>> + * @folio_list: Isolated list of folios to be batch-migrated.
>>> + * @node: The NUMA node ID to where the folios should be migrated.
>>> + *
>>> + * Caller is expected to have isolated the folios by calling
>>> + * migrate_misplaced_folio_prepare(), which will result in an
>>> + * elevated reference count on the folio. All the isolated folios
>>> + * in the list must belong to the same memcg so that NUMA_PAGE_MIGRATE
>>> + * stat can be attributed correctly to the memcg.

^ This is the expectation from the caller. pghot caller ensures this.
I could add a debug check in this routine to verify if that is indeed so.

>>> + *
>>> + * This function will un-isolate the folios, drop the elevated reference
>>> + * and remove them from the list before returning. This is called
>>> + * only for batched promotion of hot pages from lower tier nodes.
>>> + *
>>> + * Return: 0 on success and -EAGAIN on failure or partial migration.
>>> + * On return, @folio_list will be empty regardless of success/failure.
>>> + */
>>> +int migrate_misplaced_folios_batch(struct list_head *folio_list, int node)
>>> +{
>>> + pg_data_t *pgdat = NODE_DATA(node);
>>> + struct mem_cgroup *memcg = NULL;
>>> + unsigned int nr_succeeded = 0;
>>> + int nr_remaining;
>>> +
>>> + if (!list_empty(folio_list)) {
>>>
>> We seem to proceed even when the list is empty. Should we instead return
>> early in that case?
>>
>
> Well that seems utterly reasonable, yes you are right.

Right. Earlier migrate_pages() may have handled empty source list, but
with memcg-awareness in this routine, it is better to return right away.

>
>>> + struct folio *first = list_first_entry(folio_list, struct folio, lru);
>>> + memcg = get_mem_cgroup_from_folio(first);
>>
>>
>> I had a small question—are we ensuring that a single list contains folios
>> from the same memcg?
>>
>
> It has been a long while since i originally wrote this commit.
>
> I believe I originally wrote this I used it in the context of
> folio_mark_accessed() driven promotions - trying to get some semblance
> of NUMA balancing for unmapped page cache pages.
>
> These folios got put into a task workqueue that then got processed on
> the way out of the kernel.
>
> I think I made the assumption at the time that the folios would all
> belong to the same memcg - I have since learned that this almost
> certainly is not the case.
>
> That means a bulk migration may have to first process the folios into
> lists by memcg before migrating them.
>
> So this commit likely needs to be redone.

See above.

Regards,
Bharata.