lkml.org 
[lkml]   [2020]   [Jul]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v4 04/24] seqlock: Reorder seqcount_t and seqlock_t API definitions
    Date
    The seqlock.h seqcount_t and seqlock_t API definitions are presented in
    the chronological order of their development rather than the order that
    makes most sense to readers. This makes it hard to follow and understand
    the header file code.

    Group and reorder all of the exported seqlock.h functions according to
    their function.

    First, group together the seqcount_t standard read path functions:

    - __read_seqcount_begin()
    - raw_read_seqcount_begin()
    - read_seqcount_begin()

    since each function is implemented exactly in terms of the one above
    it. Then, group the special-case seqcount_t readers on their own as:

    - raw_read_seqcount()
    - raw_seqcount_begin()

    since the only difference between the two functions is that the second
    one masks the sequence counter LSB while the first one does not. Note
    that raw_seqcount_begin() can actually be implemented in terms of
    raw_read_seqcount(), which will be done in a follow-up commit.

    Then, group the seqcount_t write path functions, instead of injecting
    unrelated seqcount_t latch functions between them, and order them as:

    - raw_write_seqcount_begin()
    - raw_write_seqcount_end()
    - write_seqcount_begin_nested()
    - write_seqcount_begin()
    - write_seqcount_end()
    - raw_write_seqcount_barrier()
    - write_seqcount_invalidate()

    which is the expected natural order. This also isolates the seqcount_t
    latch functions into their own area, at the end of the sequence counters
    section, and before jumping to the next one: sequential locks
    (seqlock_t).

    Do a similar grouping and reordering for seqlock_t "locking" readers vs.
    the "conditionally locking or lockless" ones.

    No implementation code was changed in any of the reordering above.

    Signed-off-by: Ahmed S. Darwish <a.darwish@linutronix.de>
    ---
    include/linux/seqlock.h | 174 ++++++++++++++++++++--------------------
    1 file changed, 86 insertions(+), 88 deletions(-)

    diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h
    index d724b5e5408d..4c1456008d89 100644
    --- a/include/linux/seqlock.h
    +++ b/include/linux/seqlock.h
    @@ -128,23 +128,6 @@ static inline unsigned __read_seqcount_begin(const seqcount_t *s)
    return ret;
    }

    -/**
    - * raw_read_seqcount - Read the raw seqcount
    - * @s: pointer to seqcount_t
    - * Returns: count to be passed to read_seqcount_retry
    - *
    - * raw_read_seqcount opens a read critical section of the given
    - * seqcount without any lockdep checking and without checking or
    - * masking the LSB. Calling code is responsible for handling that.
    - */
    -static inline unsigned raw_read_seqcount(const seqcount_t *s)
    -{
    - unsigned ret = READ_ONCE(s->sequence);
    - smp_rmb();
    - kcsan_atomic_next(KCSAN_SEQLOCK_REGION_MAX);
    - return ret;
    -}
    -
    /**
    * raw_read_seqcount_begin - start seq-read critical section w/o lockdep
    * @s: pointer to seqcount_t
    @@ -176,6 +159,23 @@ static inline unsigned read_seqcount_begin(const seqcount_t *s)
    return raw_read_seqcount_begin(s);
    }

    +/**
    + * raw_read_seqcount - Read the raw seqcount
    + * @s: pointer to seqcount_t
    + * Returns: count to be passed to read_seqcount_retry
    + *
    + * raw_read_seqcount opens a read critical section of the given
    + * seqcount without any lockdep checking and without checking or
    + * masking the LSB. Calling code is responsible for handling that.
    + */
    +static inline unsigned raw_read_seqcount(const seqcount_t *s)
    +{
    + unsigned ret = READ_ONCE(s->sequence);
    + smp_rmb();
    + kcsan_atomic_next(KCSAN_SEQLOCK_REGION_MAX);
    + return ret;
    +}
    +
    /**
    * raw_seqcount_begin - begin a seq-read critical section
    * @s: pointer to seqcount_t
    @@ -234,8 +234,6 @@ static inline int read_seqcount_retry(const seqcount_t *s, unsigned start)
    return __read_seqcount_retry(s, start);
    }

    -
    -
    static inline void raw_write_seqcount_begin(seqcount_t *s)
    {
    kcsan_nestable_atomic_begin();
    @@ -250,6 +248,23 @@ static inline void raw_write_seqcount_end(seqcount_t *s)
    kcsan_nestable_atomic_end();
    }

    +static inline void write_seqcount_begin_nested(seqcount_t *s, int subclass)
    +{
    + raw_write_seqcount_begin(s);
    + seqcount_acquire(&s->dep_map, subclass, 0, _RET_IP_);
    +}
    +
    +static inline void write_seqcount_begin(seqcount_t *s)
    +{
    + write_seqcount_begin_nested(s, 0);
    +}
    +
    +static inline void write_seqcount_end(seqcount_t *s)
    +{
    + seqcount_release(&s->dep_map, _RET_IP_);
    + raw_write_seqcount_end(s);
    +}
    +
    /**
    * raw_write_seqcount_barrier - do a seq write barrier
    * @s: pointer to seqcount_t
    @@ -300,6 +315,21 @@ static inline void raw_write_seqcount_barrier(seqcount_t *s)
    kcsan_nestable_atomic_end();
    }

    +/**
    + * write_seqcount_invalidate - invalidate in-progress read-side seq operations
    + * @s: pointer to seqcount_t
    + *
    + * After write_seqcount_invalidate, no read-side seq operations will complete
    + * successfully and see data older than this.
    + */
    +static inline void write_seqcount_invalidate(seqcount_t *s)
    +{
    + smp_wmb();
    + kcsan_nestable_atomic_begin();
    + s->sequence+=2;
    + kcsan_nestable_atomic_end();
    +}
    +
    static inline int raw_read_seqcount_latch(seqcount_t *s)
    {
    /* Pairs with the first smp_wmb() in raw_write_seqcount_latch() */
    @@ -395,38 +425,6 @@ static inline void raw_write_seqcount_latch(seqcount_t *s)
    smp_wmb(); /* increment "sequence" before following stores */
    }

    -static inline void write_seqcount_begin_nested(seqcount_t *s, int subclass)
    -{
    - raw_write_seqcount_begin(s);
    - seqcount_acquire(&s->dep_map, subclass, 0, _RET_IP_);
    -}
    -
    -static inline void write_seqcount_begin(seqcount_t *s)
    -{
    - write_seqcount_begin_nested(s, 0);
    -}
    -
    -static inline void write_seqcount_end(seqcount_t *s)
    -{
    - seqcount_release(&s->dep_map, _RET_IP_);
    - raw_write_seqcount_end(s);
    -}
    -
    -/**
    - * write_seqcount_invalidate - invalidate in-progress read-side seq operations
    - * @s: pointer to seqcount_t
    - *
    - * After write_seqcount_invalidate, no read-side seq operations will complete
    - * successfully and see data older than this.
    - */
    -static inline void write_seqcount_invalidate(seqcount_t *s)
    -{
    - smp_wmb();
    - kcsan_nestable_atomic_begin();
    - s->sequence+=2;
    - kcsan_nestable_atomic_end();
    -}
    -
    /*
    * Sequential locks (seqlock_t)
    *
    @@ -555,6 +553,43 @@ static inline void read_sequnlock_excl(seqlock_t *sl)
    spin_unlock(&sl->lock);
    }

    +static inline void read_seqlock_excl_bh(seqlock_t *sl)
    +{
    + spin_lock_bh(&sl->lock);
    +}
    +
    +static inline void read_sequnlock_excl_bh(seqlock_t *sl)
    +{
    + spin_unlock_bh(&sl->lock);
    +}
    +
    +static inline void read_seqlock_excl_irq(seqlock_t *sl)
    +{
    + spin_lock_irq(&sl->lock);
    +}
    +
    +static inline void read_sequnlock_excl_irq(seqlock_t *sl)
    +{
    + spin_unlock_irq(&sl->lock);
    +}
    +
    +static inline unsigned long __read_seqlock_excl_irqsave(seqlock_t *sl)
    +{
    + unsigned long flags;
    +
    + spin_lock_irqsave(&sl->lock, flags);
    + return flags;
    +}
    +
    +#define read_seqlock_excl_irqsave(lock, flags) \
    + do { flags = __read_seqlock_excl_irqsave(lock); } while (0)
    +
    +static inline void
    +read_sequnlock_excl_irqrestore(seqlock_t *sl, unsigned long flags)
    +{
    + spin_unlock_irqrestore(&sl->lock, flags);
    +}
    +
    /**
    * read_seqbegin_or_lock - begin a sequence number check or locking block
    * @lock: sequence lock
    @@ -584,43 +619,6 @@ static inline void done_seqretry(seqlock_t *lock, int seq)
    read_sequnlock_excl(lock);
    }

    -static inline void read_seqlock_excl_bh(seqlock_t *sl)
    -{
    - spin_lock_bh(&sl->lock);
    -}
    -
    -static inline void read_sequnlock_excl_bh(seqlock_t *sl)
    -{
    - spin_unlock_bh(&sl->lock);
    -}
    -
    -static inline void read_seqlock_excl_irq(seqlock_t *sl)
    -{
    - spin_lock_irq(&sl->lock);
    -}
    -
    -static inline void read_sequnlock_excl_irq(seqlock_t *sl)
    -{
    - spin_unlock_irq(&sl->lock);
    -}
    -
    -static inline unsigned long __read_seqlock_excl_irqsave(seqlock_t *sl)
    -{
    - unsigned long flags;
    -
    - spin_lock_irqsave(&sl->lock, flags);
    - return flags;
    -}
    -
    -#define read_seqlock_excl_irqsave(lock, flags) \
    - do { flags = __read_seqlock_excl_irqsave(lock); } while (0)
    -
    -static inline void
    -read_sequnlock_excl_irqrestore(seqlock_t *sl, unsigned long flags)
    -{
    - spin_unlock_irqrestore(&sl->lock, flags);
    -}
    -
    static inline unsigned long
    read_seqbegin_or_lock_irqsave(seqlock_t *lock, int *seq)
    {
    --
    2.20.1
    \
     
     \ /
      Last update: 2020-07-20 17:56    [W:3.933 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site