On Thu, Oct 22, 2026 at 3:57 AM Alexei Starovoitov <[email protected]> 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...
