1. 10 Sep, 2020 4 commits
    • Ahmed S. Darwish's avatar
      time/sched_clock: Use seqcount_latch_t · a690ed07
      Ahmed S. Darwish authored
      Latch sequence counters have unique read and write APIs, and thus
      seqcount_latch_t was recently introduced at seqlock.h.
      
      Use that new data type instead of plain seqcount_t. This adds the
      necessary type-safety and ensures only latching-safe seqcount APIs are
      to be used.
      Signed-off-by: default avatarAhmed S. Darwish <a.darwish@linutronix.de>
      Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
      Link: https://lkml.kernel.org/r/20200827114044.11173-5-a.darwish@linutronix.de
      a690ed07
    • Ahmed S. Darwish's avatar
      seqlock: Introduce seqcount_latch_t · 80793c34
      Ahmed S. Darwish authored
      Latch sequence counters are a multiversion concurrency control mechanism
      where the seqcount_t counter even/odd value is used to switch between
      two copies of protected data. This allows the seqcount_t read path to
      safely interrupt its write side critical section (e.g. from NMIs).
      
      Initially, latch sequence counters were implemented as a single write
      function above plain seqcount_t: raw_write_seqcount_latch(). The read
      side was expected to use plain seqcount_t raw_read_seqcount().
      
      A specialized latch read function, raw_read_seqcount_latch(), was later
      added. It became the standardized way for latch read paths.  Due to the
      dependent load, it has one read memory barrier less than the plain
      seqcount_t raw_read_seqcount() API.
      
      Only raw_write_seqcount_latch() and raw_read_seqcount_latch() should be
      used with latch sequence counters. Having *unique* read and write path
      APIs means that latch sequence counters are actually a data type of
      their own -- just inappropriately overloading plain seqcount_t.
      
      Introduce seqcount_latch_t. This adds type-safety and ensures that only
      the correct latch-safe APIs are to be used.
      
      Not to break bisection, let the latch APIs also accept plain seqcount_t
      or seqcount_raw_spinlock_t. After converting all call sites to
      seqcount_latch_t, only that new data type will be allowed.
      
      References: 9b0fd802 ("seqcount: Add raw_write_seqcount_latch()")
      References: 7fc26327 ("seqlock: Introduce raw_read_seqcount_latch()")
      References: aadd6e5c ("time/sched_clock: Use raw_read_seqcount_latch()")
      Signed-off-by: default avatarAhmed S. Darwish <a.darwish@linutronix.de>
      Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
      Link: https://lkml.kernel.org/r/20200827114044.11173-4-a.darwish@linutronix.de
      80793c34
    • Ahmed S. Darwish's avatar
      mm/swap: Do not abuse the seqcount_t latching API · 6446a513
      Ahmed S. Darwish authored
      Commit eef1a429 ("mm/swap.c: piggyback lru_add_drain_all() calls")
      implemented an optimization mechanism to exit the to-be-started LRU
      drain operation (name it A) if another drain operation *started and
      finished* while (A) was blocked on the LRU draining mutex.
      
      This was done through a seqcount_t latch, which is an abuse of its
      semantics:
      
        1. seqcount_t latching should be used for the purpose of switching
           between two storage places with sequence protection to allow
           interruptible, preemptible, writer sections. The referenced
           optimization mechanism has absolutely nothing to do with that.
      
        2. The used raw_write_seqcount_latch() has two SMP write memory
           barriers to insure one consistent storage place out of the two
           storage places available. A full memory barrier is required
           instead: to guarantee that the pagevec counter stores visible by
           local CPU are visible to other CPUs -- before loading the current
           drain generation.
      
      Beside the seqcount_t API abuse, the semantics of a latch sequence
      counter was force-fitted into the referenced optimization. What was
      meant is to track "generations" of LRU draining operations, where
      "global lru draining generation = x" implies that all generations
      0 < n <= x are already *scheduled* for draining -- thus nothing needs
      to be done if the current generation number n <= x.
      
      Remove the conceptually-inappropriate seqcount_t latch usage. Manually
      implement the referenced optimization using a counter and SMP memory
      barriers.
      
      Note, while at it, use the non-atomic variant of cpumask_set_cpu(),
      __cpumask_set_cpu(), due to the already existing mutex protection.
      Signed-off-by: default avatarAhmed S. Darwish <a.darwish@linutronix.de>
      Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
      Link: https://lkml.kernel.org/r/87y2pg9erj.fsf@vostro.fn.ogness.net
      6446a513
    • Ahmed S. Darwish's avatar
      time/sched_clock: Use raw_read_seqcount_latch() during suspend · 58faf20a
      Ahmed S. Darwish authored
      sched_clock uses seqcount_t latching to switch between two storage
      places protected by the sequence counter. This allows it to have
      interruptible, NMI-safe, seqcount_t write side critical sections.
      
      Since 7fc26327 ("seqlock: Introduce raw_read_seqcount_latch()"),
      raw_read_seqcount_latch() became the standardized way for seqcount_t
      latch read paths. Due to the dependent load, it has one read memory
      barrier less than the currently used raw_read_seqcount() API.
      
      Use raw_read_seqcount_latch() for the suspend path.
      
      Commit aadd6e5c ("time/sched_clock: Use raw_read_seqcount_latch()")
      missed changing that instance of raw_read_seqcount().
      
      References: 1809bfa4 ("timers, sched/clock: Avoid deadlock during read from NMI")
      Signed-off-by: default avatarAhmed S. Darwish <a.darwish@linutronix.de>
      Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
      Link: https://lkml.kernel.org/r/20200715092345.GA231464@debian-buster-darwi.lab.linutronix.de
      58faf20a
  2. 26 Aug, 2020 35 commits
  3. 23 Aug, 2020 1 commit