Re: [PATCH v2 1/5] mm/memory-failure: keep the folio, not the poisoned subpage, locked across split

From: Zi Yan

Date: Tue Jul 14 2026 - 13:37:44 EST


On Tue Jul 14, 2026 at 12:40 PM EDT, Kiryl Shutsemau wrote:
> On Tue, Jul 14, 2026 at 11:44:39AM -0400, Zi Yan wrote:
>> There is an alternative, only igrab() when @lock_at is at or beyond the EOF,
>> as I was bouncing ideas with Codex.
>
> I saw this option too, but I wound rather not go this path.
>
> iput() still can lead to inode eviction an bunch of random filesystem
> complexity under us. I don't think we want to think about other
> fs-related locking issues in split context.

Your reasoning makes sense to me. Let's ignore this option.

For your patch 2, we might want something like below to avoid over
rejecting splits. WDYT?

offset = folio_page_idx(folio, lock_at);

if (split_type == SPLIT_TYPE_UNIFORM)
lock_at_index = folio->index + round_down(offset, 1UL << new_order);
else
/* @lock_at in non uniform split is always @folio */
lock_at_index = folio->index;

if (lock_at_index >= end) {
ret = -EBUSY;
goto out_unlock;
}


Also to keep a record in case we want to have @lock_at pointing to any
tail page for non uniform split in the future, something like below is
going to be useful (assisted by Codex).

static pgoff_t split_lock_at_index(struct folio *folio,
unsigned int new_order, struct page *split_at,
struct page *lock_at, enum split_type split_type)
{
unsigned long lock = folio_page_idx(folio, lock_at);
unsigned long split = folio_page_idx(folio, split_at);
int order;

if (split_type == SPLIT_TYPE_UNIFORM)
return folio->index + round_down(lock, 1UL << new_order);

for (order = folio_order(folio) - 1; order >= new_order; order--) {
unsigned long size = 1UL << order;
unsigned long lock_base = round_down(lock, size);
unsigned long split_base = round_down(split, size);

/* folio containing @lock_at will not be split any more */
if (lock_base != split_base)
return folio->index + lock_base;
}

return folio->index + round_down(lock, 1UL << new_order);
}

if (split_lock_at_index(folio, new_order, split_at, lock_at, split_type) >= end) {
ret = -EBUSY;
goto out_unlock;
}

--
Best Regards,
Yan, Zi