On Sun, Oct 27, 2024 at 06:08:16PM -0700, Andrii Nakryiko wrote: > From: Suren Baghdasaryan <surenb@xxxxxxxxxx> > > Add helper functions to speculatively perform operations without > read-locking mmap_lock, expecting that mmap_lock will not be > write-locked and mm is not modified from under us. > > Suggested-by: Peter Zijlstra <peterz@xxxxxxxxxxxxx> > Signed-off-by: Suren Baghdasaryan <surenb@xxxxxxxxxx> > Signed-off-by: Andrii Nakryiko <andrii@xxxxxxxxxx> > --- > include/linux/mmap_lock.h | 29 +++++++++++++++++++++++++++-- > 1 file changed, 27 insertions(+), 2 deletions(-) > > @@ -86,11 +87,35 @@ static inline void mm_lock_seqcount_end(struct mm_struct *mm) > do_raw_write_seqcount_end(&mm->mm_lock_seq); > } > > -#else > +static inline bool mmap_lock_speculation_begin(struct mm_struct *mm, unsigned int *seq) > +{ > + *seq = raw_read_seqcount(&mm->mm_lock_seq); > + /* Allow speculation if mmap_lock is not write-locked */ > + return (*seq & 1) == 0; > +} At the very least this should have more comment; I don't think it adequately explains the reason for being weird. Perhaps: /* * Since mmap_lock is a sleeping lock, and waiting for it to * become unlocked is more or less equivalent with taking it * ourselves, don't bother with the speculative path and take * the slow path, which takes the lock. */ *seq = raw_read_seqcount(&mm->mm_lock_seq); return !(*seq & 1); But perhaps it makes even more sense to add this functionality to seqcount itself. The same argument can be made for seqcount_mutex and seqcount_rwlock users. > +static inline bool mmap_lock_speculation_end(struct mm_struct *mm, unsigned int seq) > +{ > + return !do_read_seqcount_retry(&mm->mm_lock_seq, seq); > +} This naming is somewhare weird, begin/end do not typically imply boolean return values. Perhaps something like? can_speculate, or speculate_try_begin, paired with speculated_success or speculate_retry ?