Re: [PATCH bpf-next 6/9] uprobes: Don't sleep on mmap_lock with dup_mmap_sem held in dup_mmap()
From: Jann Horn
Date: Thu Oct 22 2026 - 14:51:31 EST
On Thu, Oct 22, 2026 at 3:57 AM Alexei Starovoitov
<alexei.starovoitov@xxxxxxxxx> wrote:
> @@ -1713,8 +1713,22 @@ __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
> LIST_HEAD(uf);
> VMA_ITERATOR(vmi, mm, 0);
>
> - if (mmap_write_lock_killable(oldmm))
> - return -EINTR;
> + /*
> + * Take mmap_lock of oldmm and dup_mmap_sem of uprobes.
> + * Don't sleep on one of them while holding the other.
> + */
> + for (;;) {
> + if (mmap_write_lock_killable(oldmm))
> + return -EINTR;
> + if (uprobe_try_start_dup_mmap())
> + break;
> + mmap_write_unlock(oldmm);
> +
> + uprobe_start_dup_mmap();
> + if (mmap_write_trylock(oldmm))
> + break;
> + uprobe_end_dup_mmap();
> + }
I guess in practice that probably works fine, though in theory this
locking pattern could potentially lead to livelock?
Like, if two threads T1/T2 both try to acquire the locks L1 and L2
with this pattern, you could get something like:
Thread 2: lock L1
Thread 2: trylock L2 [fails due to contention by a third thread]
Thread 2: unlock L1
Thread 1: lock L1
Thread 2: lock L2
Thread 1: trylock L2 fails
Thread 2: trylock L1 fails
Thread 1: unlock L1
Thread 2: unlock L2
Thread 1: lock L2
Thread 2: lock L1
Thread 1: trylock L1 fails
Thread 2: trylock L2 fails
Thread 1: unlock L2
Thread 2: unlock L1
... and so on
In practice, it's probably fine as long as SMP cores don't run in
perfect lockstep...