Subject: Re: [PATCH 1/8] mm: Add ptep_try_install() for lockless empty-slot installs

From: "David Hildenbrand (Arm)" <[email-masked]>
Date: Tue, 19 May 2026 10:00:39 +0200

On 5/18/26 21:53, Tejun Heo wrote:
> Hello,
> 
> On Mon, May 18, 2026 at 10:06:29AM +0200, David Hildenbrand (Arm) wrote:
>> On 5/17/26 23:12, Tejun Heo wrote:
>>> +static inline bool ptep_try_install(pte_t *ptep, pte_t new_pte)
>>> +{
>>> +	return false;
>>> +}
>>> +#endif
>>
>> Ehm, what?
>>
>> This is a very, very, very bad generic idea/interface.
>>
>> On which ptes is this supposed to be used? User ptes or kernel ptes?
>>
>> Surely we don't want this on user ptes.
> 
> Yeah, this is only for the BPF arena PTEs which are already managed in their
> own way. I'd be happy to place / gate it however appropriate.

So, we only use it within apply_to_page_range() with init_mm, where we don't use
page table locks.

Usually we seem to grab the &arena->spinlock to protect the kernel page tables.

And you're saying that we might get called from a page fault handler where that
lock can already be held.

Is that really possible? I'd much rather prefer to trylock and retry, unless
that can really result in deadlocks. But I have the feeling that such deadlocks
should be impossible here.

Can you elaborate on the deadlock situation and how that can happen in valid
scenarios?

The thing is that ptep_try_install() relies on other page table walking and
insertion code to do the right thing. Shaky.

For example, staring at apply_range_set_cb(), what prevents:

(1) apply_range_set_cb() finding pte_none(ptep_get(pte)
(2) apply_range_set_scratch_cb() succeeding ptep_try_install()
(3) apply_range_set_cb() overwriting the pte with set_pte_at()

Between (2) and (3) CPUs could access the scratch PTE.

-- 
Cheers,

David