]> Git Repo - linux.git/commitdiff
Merge tag 'locking-core-2020-08-03' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <[email protected]>
Mon, 3 Aug 2020 21:39:35 +0000 (14:39 -0700)
committerLinus Torvalds <[email protected]>
Mon, 3 Aug 2020 21:39:35 +0000 (14:39 -0700)
Pull locking updates from Ingo Molnar:

 - LKMM updates: mostly documentation changes, but also some new litmus
   tests for atomic ops.

 - KCSAN updates: the most important change is that GCC 11 now has all
   fixes in place to support KCSAN, so GCC support can be enabled again.
   Also more annotations.

 - futex updates: minor cleanups and simplifications

 - seqlock updates: merge preparatory changes/cleanups for the
   'associated locks' facilities.

 - lockdep updates:
    - simplify IRQ trace event handling
    - add various new debug checks
    - simplify header dependencies, split out <linux/lockdep_types.h>,
      decouple lockdep from other low level headers some more
    - fix NMI handling

 - misc cleanups and smaller fixes

* tag 'locking-core-2020-08-03' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (60 commits)
  kcsan: Improve IRQ state trace reporting
  lockdep: Refactor IRQ trace events fields into struct
  seqlock: lockdep assert non-preemptibility on seqcount_t write
  lockdep: Add preemption enabled/disabled assertion APIs
  seqlock: Implement raw_seqcount_begin() in terms of raw_read_seqcount()
  seqlock: Add kernel-doc for seqcount_t and seqlock_t APIs
  seqlock: Reorder seqcount_t and seqlock_t API definitions
  seqlock: seqcount_t latch: End read sections with read_seqcount_retry()
  seqlock: Properly format kernel-doc code samples
  Documentation: locking: Describe seqlock design and usage
  locking/qspinlock: Do not include atomic.h from qspinlock_types.h
  locking/atomic: Move ATOMIC_INIT into linux/types.h
  lockdep: Move list.h inclusion into lockdep.h
  locking/lockdep: Fix TRACE_IRQFLAGS vs. NMIs
  futex: Remove unused or redundant includes
  futex: Consistently use fshared as boolean
  futex: Remove needless goto's
  futex: Remove put_futex_key()
  rwsem: fix commas in initialisation
  docs: locking: Replace HTTP links with HTTPS ones
  ...

1  2 
MAINTAINERS
arch/alpha/include/asm/atomic.h
arch/s390/include/asm/smp.h
include/linux/rculist.h
kernel/locking/lockdep.c
tools/memory-model/Documentation/explanation.txt

diff --combined MAINTAINERS
index f1543115cabee462dd274d834a1ce8d3b2d5286e,e8aedeb71f9e5c2b8f0e6ff3cc22a694756f0957..13e323b46f681bd28a1007452faa59cdaae29ff6
@@@ -782,7 -782,7 +782,7 @@@ F: include/dt-bindings/reset/altr,rst-m
  F:    include/linux/mfd/altera-a10sr.h
  
  ALTERA TRIPLE SPEED ETHERNET DRIVER
 -M:    Thor Thayer <thor.thayer@linux.intel.com>
 +M:    Joyce Ooi <joyce.ooi@intel.com>
  L:    [email protected]
  S:    Maintained
  F:    drivers/net/ethernet/altera/
@@@ -830,20 -830,11 +830,20 @@@ F:      include/uapi/rdma/efa-abi.
  
  AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER
  M:    Tom Lendacky <[email protected]>
 +M:    John Allen <[email protected]>
  L:    [email protected]
  S:    Supported
  F:    drivers/crypto/ccp/
  F:    include/linux/ccp.h
  
 +AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER - SEV SUPPORT
 +M:    Brijesh Singh <[email protected]>
 +M:    Tom Lendacky <[email protected]>
 +L:    [email protected]
 +S:    Supported
 +F:    drivers/crypto/ccp/sev*
 +F:    include/uapi/linux/psp-sev.h
 +
  AMD DISPLAY CORE
  M:    Harry Wentland <[email protected]>
  M:    Leo Li <[email protected]>
@@@ -1434,7 -1425,7 +1434,7 @@@ F:      arch/arm*/include/asm/perf_event.
  F:    arch/arm*/kernel/hw_breakpoint.c
  F:    arch/arm*/kernel/perf_*
  F:    arch/arm/oprofile/common.c
 -F:    drivers/perf/*
 +F:    drivers/perf/
  F:    include/linux/perf/arm_pmu.h
  
  ARM PORT
@@@ -9981,6 -9972,7 +9981,7 @@@ M:      Luc Maranget <[email protected]
  M:    "Paul E. McKenney" <[email protected]>
  R:    Akira Yokosawa <[email protected]>
  R:    Daniel Lustig <[email protected]>
+ R:    Joel Fernandes <[email protected]>
  L:    [email protected]
  L:    [email protected]
  S:    Supported
@@@ -9989,6 -9981,7 +9990,7 @@@ F:      Documentation/atomic_bitops.tx
  F:    Documentation/atomic_t.txt
  F:    Documentation/core-api/atomic_ops.rst
  F:    Documentation/core-api/refcount-vs-atomic.rst
+ F:    Documentation/litmus-tests/
  F:    Documentation/memory-barriers.txt
  F:    tools/memory-model/
  
@@@ -13601,6 -13594,16 +13603,6 @@@ F:  drivers/block/pktcdvd.
  F:    include/linux/pktcdvd.h
  F:    include/uapi/linux/pktcdvd.h
  
 -PKUNITY SOC DRIVERS
 -M:    Guan Xuetao <[email protected]>
 -S:    Maintained
 -W:    http://mprc.pku.edu.cn/~guanxuetao/linux
 -T:    git git://github.com/gxt/linux.git
 -F:    drivers/i2c/busses/i2c-puv3.c
 -F:    drivers/input/serio/i8042-unicore32io.h
 -F:    drivers/rtc/rtc-puv3.c
 -F:    drivers/video/fbdev/fb-puv3.c
 -
  PLANTOWER PMS7003 AIR POLLUTION SENSOR DRIVER
  M:    Tomasz Duszynski <[email protected]>
  S:    Maintained
@@@ -14187,8 -14190,7 +14189,8 @@@ F:   Documentation/devicetree/bindings/ne
  F:    drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
  
  QUALCOMM GENERIC INTERFACE I2C DRIVER
 -M:    Alok Chauhan <[email protected]>
 +M:    Akash Asthana <[email protected]>
 +M:    Mukesh Savaliya <[email protected]>
  L:    [email protected]
  L:    [email protected]
  S:    Supported
@@@ -14449,7 -14451,7 +14451,7 @@@ T:   git git://git.kernel.org/pub/scm/lin
  F:    Documentation/RCU/
  F:    include/linux/rcu*
  F:    kernel/rcu/
 -X:    Documentation/RCU/torture.txt
 +X:    Documentation/RCU/torture.rst
  X:    include/linux/srcu*.h
  X:    kernel/rcu/srcu*.c
  
@@@ -17301,7 -17303,7 +17303,7 @@@ M:   Josh Triplett <[email protected]
  L:    [email protected]
  S:    Supported
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev
 -F:    Documentation/RCU/torture.txt
 +F:    Documentation/RCU/torture.rst
  F:    kernel/locking/locktorture.c
  F:    kernel/rcu/rcuperf.c
  F:    kernel/rcu/rcutorture.c
  S:    Supported
  F:    fs/unicode/
  
 -UNICORE32 ARCHITECTURE
 -M:    Guan Xuetao <[email protected]>
 -S:    Maintained
 -W:    http://mprc.pku.edu.cn/~guanxuetao/linux
 -T:    git git://github.com/gxt/linux.git
 -F:    arch/unicore32/
 -
  UNIFDEF
  M:    Tony Finch <[email protected]>
  S:    Maintained
index 2f8f7e54792f4449e589ea4cb80cbd3cc0ce65e8,e2093994fd0de42a4244848160e80169694098cb..e41c113c668837de3816e0aeee64c1f05b3cd890
  
  /*
   * To ensure dependency ordering is preserved for the _relaxed and
 - * _release atomics, an smp_read_barrier_depends() is unconditionally
 - * inserted into the _relaxed variants, which are used to build the
 - * barriered versions. Avoid redundant back-to-back fences in the
 - * _acquire and _fence versions.
 + * _release atomics, an smp_mb() is unconditionally inserted into the
 + * _relaxed variants, which are used to build the barriered versions.
 + * Avoid redundant back-to-back fences in the _acquire and _fence
 + * versions.
   */
  #define __atomic_acquire_fence()
  #define __atomic_post_full_fence()
  
- #define ATOMIC_INIT(i)                { (i) }
  #define ATOMIC64_INIT(i)      { (i) }
  
  #define atomic_read(v)                READ_ONCE((v)->counter)
@@@ -70,7 -69,7 +69,7 @@@ static inline int atomic_##op##_return_
        ".previous"                                                     \
        :"=&r" (temp), "=m" (v->counter), "=&r" (result)                \
        :"Ir" (i), "m" (v->counter) : "memory");                        \
 -      smp_read_barrier_depends();                                     \
 +      smp_mb();                                                       \
        return result;                                                  \
  }
  
@@@ -88,7 -87,7 +87,7 @@@ static inline int atomic_fetch_##op##_r
        ".previous"                                                     \
        :"=&r" (temp), "=m" (v->counter), "=&r" (result)                \
        :"Ir" (i), "m" (v->counter) : "memory");                        \
 -      smp_read_barrier_depends();                                     \
 +      smp_mb();                                                       \
        return result;                                                  \
  }
  
@@@ -123,7 -122,7 +122,7 @@@ static __inline__ s64 atomic64_##op##_r
        ".previous"                                                     \
        :"=&r" (temp), "=m" (v->counter), "=&r" (result)                \
        :"Ir" (i), "m" (v->counter) : "memory");                        \
 -      smp_read_barrier_depends();                                     \
 +      smp_mb();                                                       \
        return result;                                                  \
  }
  
@@@ -141,7 -140,7 +140,7 @@@ static __inline__ s64 atomic64_fetch_##
        ".previous"                                                     \
        :"=&r" (temp), "=m" (v->counter), "=&r" (result)                \
        :"Ir" (i), "m" (v->counter) : "memory");                        \
 -      smp_read_barrier_depends();                                     \
 +      smp_mb();                                                       \
        return result;                                                  \
  }
  
index 20b37b059e2b41d053081e3ec7eee1c77464de2f,f48a43b63d9e055288482a97bcf5a66fe7f79bb6..7e155fb6c254d93ff57193929abed7ba3d31626d
@@@ -10,6 -10,7 +10,7 @@@
  
  #include <asm/sigp.h>
  #include <asm/lowcore.h>
+ #include <asm/processor.h>
  
  #define raw_smp_processor_id()        (S390_lowcore.cpu_nr)
  
@@@ -54,10 -55,6 +55,10 @@@ static inline int smp_get_base_cpu(int 
        return cpu - (cpu % (smp_cpu_mtid + 1));
  }
  
 +static inline void smp_cpus_done(unsigned int max_cpus)
 +{
 +}
 +
  extern int smp_rescan_cpus(void);
  extern void __noreturn cpu_die(void);
  extern void __cpu_die(unsigned int cpu);
diff --combined include/linux/rculist.h
index 7eed65b5f7130afa58741160340499416af127e1,2ebd112f86f72b6cabb3c6c96ed1e3353cf0d0ad..7a6fc99565104bcc7876a555066ca0579f472c7c
@@@ -248,6 -248,8 +248,8 @@@ static inline void __list_splice_init_r
         */
  
        sync();
+       ASSERT_EXCLUSIVE_ACCESS(*first);
+       ASSERT_EXCLUSIVE_ACCESS(*last);
  
        /*
         * Readers are finished with the source list, so perform splice.
@@@ -512,7 -514,7 +514,7 @@@ static inline void hlist_replace_rcu(st
   * @right: The hlist head on the right
   *
   * The lists start out as [@left  ][node1 ... ] and
 -                          [@right ][node2 ... ]
 + *                        [@right ][node2 ... ]
   * The lists end up as    [@left  ][node2 ... ]
   *                        [@right ][node1 ... ]
   */
diff --combined kernel/locking/lockdep.c
index 0a7549d159edce194d2130a33381c83afbe13a6f,b4d34c9030df08f211c3388d9f4d9e14a6d461ca..f361d75a75ac8984922f971ba4ce46fe1079a0d0
@@@ -395,7 -395,7 +395,7 @@@ void lockdep_init_task(struct task_stru
  
  static __always_inline void lockdep_recursion_finish(void)
  {
-       if (WARN_ON_ONCE(--current->lockdep_recursion))
+       if (WARN_ON_ONCE((--current->lockdep_recursion) & LOCKDEP_RECURSION_MASK))
                current->lockdep_recursion = 0;
  }
  
@@@ -2062,9 -2062,9 +2062,9 @@@ print_bad_irq_dependency(struct task_st
        pr_warn("-----------------------------------------------------\n");
        pr_warn("%s/%d [HC%u[%lu]:SC%u[%lu]:HE%u:SE%u] is trying to acquire:\n",
                curr->comm, task_pid_nr(curr),
-               curr->hardirq_context, hardirq_count() >> HARDIRQ_SHIFT,
+               lockdep_hardirq_context(), hardirq_count() >> HARDIRQ_SHIFT,
                curr->softirq_context, softirq_count() >> SOFTIRQ_SHIFT,
-               curr->hardirqs_enabled,
+               lockdep_hardirqs_enabled(),
                curr->softirqs_enabled);
        print_lock(next);
  
@@@ -3331,9 -3331,9 +3331,9 @@@ print_usage_bug(struct task_struct *cur
  
        pr_warn("%s/%d [HC%u[%lu]:SC%u[%lu]:HE%u:SE%u] takes:\n",
                curr->comm, task_pid_nr(curr),
-               lockdep_hardirq_context(curr), hardirq_count() >> HARDIRQ_SHIFT,
+               lockdep_hardirq_context(), hardirq_count() >> HARDIRQ_SHIFT,
                lockdep_softirq_context(curr), softirq_count() >> SOFTIRQ_SHIFT,
-               lockdep_hardirqs_enabled(curr),
+               lockdep_hardirqs_enabled(),
                lockdep_softirqs_enabled(curr));
        print_lock(this);
  
@@@ -3484,19 -3484,21 +3484,21 @@@ check_usage_backwards(struct task_struc
  
  void print_irqtrace_events(struct task_struct *curr)
  {
-       printk("irq event stamp: %u\n", curr->irq_events);
+       const struct irqtrace_events *trace = &curr->irqtrace;
+       printk("irq event stamp: %u\n", trace->irq_events);
        printk("hardirqs last  enabled at (%u): [<%px>] %pS\n",
-               curr->hardirq_enable_event, (void *)curr->hardirq_enable_ip,
-               (void *)curr->hardirq_enable_ip);
+               trace->hardirq_enable_event, (void *)trace->hardirq_enable_ip,
+               (void *)trace->hardirq_enable_ip);
        printk("hardirqs last disabled at (%u): [<%px>] %pS\n",
-               curr->hardirq_disable_event, (void *)curr->hardirq_disable_ip,
-               (void *)curr->hardirq_disable_ip);
+               trace->hardirq_disable_event, (void *)trace->hardirq_disable_ip,
+               (void *)trace->hardirq_disable_ip);
        printk("softirqs last  enabled at (%u): [<%px>] %pS\n",
-               curr->softirq_enable_event, (void *)curr->softirq_enable_ip,
-               (void *)curr->softirq_enable_ip);
+               trace->softirq_enable_event, (void *)trace->softirq_enable_ip,
+               (void *)trace->softirq_enable_ip);
        printk("softirqs last disabled at (%u): [<%px>] %pS\n",
-               curr->softirq_disable_event, (void *)curr->softirq_disable_ip,
-               (void *)curr->softirq_disable_ip);
+               trace->softirq_disable_event, (void *)trace->softirq_disable_ip,
+               (void *)trace->softirq_disable_ip);
  }
  
  static int HARDIRQ_verbose(struct lock_class *class)
@@@ -3646,10 -3648,19 +3648,19 @@@ static void __trace_hardirqs_on_caller(
   */
  void lockdep_hardirqs_on_prepare(unsigned long ip)
  {
-       if (unlikely(!debug_locks || current->lockdep_recursion))
+       if (unlikely(!debug_locks))
+               return;
+       /*
+        * NMIs do not (and cannot) track lock dependencies, nothing to do.
+        */
+       if (unlikely(in_nmi()))
+               return;
+       if (unlikely(current->lockdep_recursion & LOCKDEP_RECURSION_MASK))
                return;
  
-       if (unlikely(current->hardirqs_enabled)) {
+       if (unlikely(lockdep_hardirqs_enabled())) {
                /*
                 * Neither irq nor preemption are disabled here
                 * so this is racy by nature but losing one hit
         * Can't allow enabling interrupts while in an interrupt handler,
         * that's general bad form and such. Recursion, limited stack etc..
         */
-       if (DEBUG_LOCKS_WARN_ON(current->hardirq_context))
+       if (DEBUG_LOCKS_WARN_ON(lockdep_hardirq_context()))
                return;
  
        current->hardirq_chain_key = current->curr_chain_key;
@@@ -3690,12 -3701,35 +3701,35 @@@ EXPORT_SYMBOL_GPL(lockdep_hardirqs_on_p
  
  void noinstr lockdep_hardirqs_on(unsigned long ip)
  {
-       struct task_struct *curr = current;
+       struct irqtrace_events *trace = &current->irqtrace;
+       if (unlikely(!debug_locks))
+               return;
+       /*
+        * NMIs can happen in the middle of local_irq_{en,dis}able() where the
+        * tracking state and hardware state are out of sync.
+        *
+        * NMIs must save lockdep_hardirqs_enabled() to restore IRQ state from,
+        * and not rely on hardware state like normal interrupts.
+        */
+       if (unlikely(in_nmi())) {
+               if (!IS_ENABLED(CONFIG_TRACE_IRQFLAGS_NMI))
+                       return;
+               /*
+                * Skip:
+                *  - recursion check, because NMI can hit lockdep;
+                *  - hardware state check, because above;
+                *  - chain_key check, see lockdep_hardirqs_on_prepare().
+                */
+               goto skip_checks;
+       }
  
-       if (unlikely(!debug_locks || curr->lockdep_recursion))
+       if (unlikely(current->lockdep_recursion & LOCKDEP_RECURSION_MASK))
                return;
  
-       if (curr->hardirqs_enabled) {
+       if (lockdep_hardirqs_enabled()) {
                /*
                 * Neither irq nor preemption are disabled here
                 * so this is racy by nature but losing one hit
        DEBUG_LOCKS_WARN_ON(current->hardirq_chain_key !=
                            current->curr_chain_key);
  
+ skip_checks:
        /* we'll do an OFF -> ON transition: */
-       curr->hardirqs_enabled = 1;
-       curr->hardirq_enable_ip = ip;
-       curr->hardirq_enable_event = ++curr->irq_events;
+       this_cpu_write(hardirqs_enabled, 1);
+       trace->hardirq_enable_ip = ip;
+       trace->hardirq_enable_event = ++trace->irq_events;
        debug_atomic_inc(hardirqs_on_events);
  }
  EXPORT_SYMBOL_GPL(lockdep_hardirqs_on);
   */
  void noinstr lockdep_hardirqs_off(unsigned long ip)
  {
-       struct task_struct *curr = current;
+       if (unlikely(!debug_locks))
+               return;
  
-       if (unlikely(!debug_locks || curr->lockdep_recursion))
+       /*
+        * Matching lockdep_hardirqs_on(), allow NMIs in the middle of lockdep;
+        * they will restore the software state. This ensures the software
+        * state is consistent inside NMIs as well.
+        */
+       if (in_nmi()) {
+               if (!IS_ENABLED(CONFIG_TRACE_IRQFLAGS_NMI))
+                       return;
+       } else if (current->lockdep_recursion & LOCKDEP_RECURSION_MASK)
                return;
  
        /*
        if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
                return;
  
-       if (curr->hardirqs_enabled) {
+       if (lockdep_hardirqs_enabled()) {
+               struct irqtrace_events *trace = &current->irqtrace;
                /*
                 * We have done an ON -> OFF transition:
                 */
-               curr->hardirqs_enabled = 0;
-               curr->hardirq_disable_ip = ip;
-               curr->hardirq_disable_event = ++curr->irq_events;
+               this_cpu_write(hardirqs_enabled, 0);
+               trace->hardirq_disable_ip = ip;
+               trace->hardirq_disable_event = ++trace->irq_events;
                debug_atomic_inc(hardirqs_off_events);
        } else {
                debug_atomic_inc(redundant_hardirqs_off);
@@@ -3764,7 -3810,7 +3810,7 @@@ EXPORT_SYMBOL_GPL(lockdep_hardirqs_off)
   */
  void lockdep_softirqs_on(unsigned long ip)
  {
-       struct task_struct *curr = current;
+       struct irqtrace_events *trace = &current->irqtrace;
  
        if (unlikely(!debug_locks || current->lockdep_recursion))
                return;
        if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
                return;
  
-       if (curr->softirqs_enabled) {
+       if (current->softirqs_enabled) {
                debug_atomic_inc(redundant_softirqs_on);
                return;
        }
        /*
         * We'll do an OFF -> ON transition:
         */
-       curr->softirqs_enabled = 1;
-       curr->softirq_enable_ip = ip;
-       curr->softirq_enable_event = ++curr->irq_events;
+       current->softirqs_enabled = 1;
+       trace->softirq_enable_ip = ip;
+       trace->softirq_enable_event = ++trace->irq_events;
        debug_atomic_inc(softirqs_on_events);
        /*
         * We are going to turn softirqs on, so set the
         * usage bit for all held locks, if hardirqs are
         * enabled too:
         */
-       if (curr->hardirqs_enabled)
-               mark_held_locks(curr, LOCK_ENABLED_SOFTIRQ);
+       if (lockdep_hardirqs_enabled())
+               mark_held_locks(current, LOCK_ENABLED_SOFTIRQ);
        lockdep_recursion_finish();
  }
  
   */
  void lockdep_softirqs_off(unsigned long ip)
  {
-       struct task_struct *curr = current;
        if (unlikely(!debug_locks || current->lockdep_recursion))
                return;
  
        if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
                return;
  
-       if (curr->softirqs_enabled) {
+       if (current->softirqs_enabled) {
+               struct irqtrace_events *trace = &current->irqtrace;
                /*
                 * We have done an ON -> OFF transition:
                 */
-               curr->softirqs_enabled = 0;
-               curr->softirq_disable_ip = ip;
-               curr->softirq_disable_event = ++curr->irq_events;
+               current->softirqs_enabled = 0;
+               trace->softirq_disable_ip = ip;
+               trace->softirq_disable_event = ++trace->irq_events;
                debug_atomic_inc(softirqs_off_events);
                /*
                 * Whoops, we wanted softirqs off, so why aren't they?
@@@ -3843,7 -3889,7 +3889,7 @@@ mark_usage(struct task_struct *curr, st
         */
        if (!hlock->trylock) {
                if (hlock->read) {
-                       if (curr->hardirq_context)
+                       if (lockdep_hardirq_context())
                                if (!mark_lock(curr, hlock,
                                                LOCK_USED_IN_HARDIRQ_READ))
                                        return 0;
                                                LOCK_USED_IN_SOFTIRQ_READ))
                                        return 0;
                } else {
-                       if (curr->hardirq_context)
+                       if (lockdep_hardirq_context())
                                if (!mark_lock(curr, hlock, LOCK_USED_IN_HARDIRQ))
                                        return 0;
                        if (curr->softirq_context)
@@@ -3890,7 -3936,7 +3936,7 @@@ lock_used
  
  static inline unsigned int task_irq_context(struct task_struct *task)
  {
-       return LOCK_CHAIN_HARDIRQ_CONTEXT * !!task->hardirq_context +
+       return LOCK_CHAIN_HARDIRQ_CONTEXT * !!lockdep_hardirq_context() +
               LOCK_CHAIN_SOFTIRQ_CONTEXT * !!task->softirq_context;
  }
  
@@@ -3983,7 -4029,7 +4029,7 @@@ static inline short task_wait_context(s
         * Set appropriate wait type for the context; for IRQs we have to take
         * into account force_irqthread as that is implied by PREEMPT_RT.
         */
-       if (curr->hardirq_context) {
+       if (lockdep_hardirq_context()) {
                /*
                 * Check if force_irqthreads will run us threaded.
                 */
@@@ -4826,11 -4872,11 +4872,11 @@@ static void check_flags(unsigned long f
                return;
  
        if (irqs_disabled_flags(flags)) {
-               if (DEBUG_LOCKS_WARN_ON(current->hardirqs_enabled)) {
+               if (DEBUG_LOCKS_WARN_ON(lockdep_hardirqs_enabled())) {
                        printk("possible reason: unannotated irqs-off.\n");
                }
        } else {
-               if (DEBUG_LOCKS_WARN_ON(!current->hardirqs_enabled)) {
+               if (DEBUG_LOCKS_WARN_ON(!lockdep_hardirqs_enabled())) {
                        printk("possible reason: unannotated irqs-on.\n");
                }
        }
@@@ -5851,7 -5897,9 +5897,7 @@@ void lockdep_rcu_suspicious(const char 
        pr_warn("\n%srcu_scheduler_active = %d, debug_locks = %d\n",
               !rcu_lockdep_current_cpu_online()
                        ? "RCU used illegally from offline CPU!\n"
 -                      : !rcu_is_watching()
 -                              ? "RCU used illegally from idle CPU!\n"
 -                              : "",
 +                      : "",
               rcu_scheduler_active, debug_locks);
  
        /*
index 01adf9e0ebac6b4c9f0a1cfe04f8d04268353d94,993f800659c6a01bc47e3663d0352ad9ce42949e..f9d610d5a1a4cddd6058cdcb3acef991eb15bceb
@@@ -1122,10 -1122,12 +1122,10 @@@ maintain at least the appearance of FIF
  In practice, this difficulty is solved by inserting a special fence
  between P1's two loads when the kernel is compiled for the Alpha
  architecture.  In fact, as of version 4.15, the kernel automatically
 -adds this fence (called smp_read_barrier_depends() and defined as
 -nothing at all on non-Alpha builds) after every READ_ONCE() and atomic
 -load.  The effect of the fence is to cause the CPU not to execute any
 -po-later instructions until after the local cache has finished
 -processing all the stores it has already received.  Thus, if the code
 -was changed to:
 +adds this fence after every READ_ONCE() and atomic load on Alpha.  The
 +effect of the fence is to cause the CPU not to execute any po-later
 +instructions until after the local cache has finished processing all
 +the stores it has already received.  Thus, if the code was changed to:
  
        P1()
        {
@@@ -1144,14 -1146,14 +1144,14 @@@ READ_ONCE() or another synchronization 
  directly.
  
  The LKMM requires that smp_rmb(), acquire fences, and strong fences
 -share this property with smp_read_barrier_depends(): They do not allow
 -the CPU to execute any po-later instructions (or po-later loads in the
 -case of smp_rmb()) until all outstanding stores have been processed by
 -the local cache.  In the case of a strong fence, the CPU first has to
 -wait for all of its po-earlier stores to propagate to every other CPU
 -in the system; then it has to wait for the local cache to process all
 -the stores received as of that time -- not just the stores received
 -when the strong fence began.
 +share this property: They do not allow the CPU to execute any po-later
 +instructions (or po-later loads in the case of smp_rmb()) until all
 +outstanding stores have been processed by the local cache.  In the
 +case of a strong fence, the CPU first has to wait for all of its
 +po-earlier stores to propagate to every other CPU in the system; then
 +it has to wait for the local cache to process all the stores received
 +as of that time -- not just the stores received when the strong fence
 +began.
  
  And of course, none of this matters for any architecture other than
  Alpha.
@@@ -1985,28 -1987,36 +1985,36 @@@ outcome undefined
  
  In technical terms, the compiler is allowed to assume that when the
  program executes, there will not be any data races.  A "data race"
- occurs when two conflicting memory accesses execute concurrently;
- two memory accesses "conflict" if:
+ occurs when there are two memory accesses such that:
  
      they access the same location,
1.    they access the same location,
  
-       they occur on different CPUs (or in different threads on the
-       same CPU),
+ 2.    at least one of them is a store,
  
      at least one of them is a plain access,
3.    at least one of them is plain,
  
-       and at least one of them is a store.
+ 4.    they occur on different CPUs (or in different threads on the
+       same CPU), and
  
- The LKMM tries to determine whether a program contains two conflicting
- accesses which may execute concurrently; if it does then the LKMM says
- there is a potential data race and makes no predictions about the
- program's outcome.
+ 5.    they execute concurrently.
  
- Determining whether two accesses conflict is easy; you can see that
- all the concepts involved in the definition above are already part of
- the memory model.  The hard part is telling whether they may execute
- concurrently.  The LKMM takes a conservative attitude, assuming that
- accesses may be concurrent unless it can prove they cannot.
+ In the literature, two accesses are said to "conflict" if they satisfy
+ 1 and 2 above.  We'll go a little farther and say that two accesses
+ are "race candidates" if they satisfy 1 - 4.  Thus, whether or not two
+ race candidates actually do race in a given execution depends on
+ whether they are concurrent.
+ The LKMM tries to determine whether a program contains race candidates
+ which may execute concurrently; if it does then the LKMM says there is
+ a potential data race and makes no predictions about the program's
+ outcome.
+ Determining whether two accesses are race candidates is easy; you can
+ see that all the concepts involved in the definition above are already
+ part of the memory model.  The hard part is telling whether they may
+ execute concurrently.  The LKMM takes a conservative attitude,
+ assuming that accesses may be concurrent unless it can prove they
+ are not.
  
  If two memory accesses aren't concurrent then one must execute before
  the other.  Therefore the LKMM decides two accesses aren't concurrent
@@@ -2169,8 -2179,8 +2177,8 @@@ again, now using plain accesses for buf
        }
  
  This program does not contain a data race.  Although the U and V
- accesses conflict, the LKMM can prove they are not concurrent as
- follows:
+ accesses are race candidates, the LKMM can prove they are not
concurrent as follows:
  
        The smp_wmb() fence in P0 is both a compiler barrier and a
        cumul-fence.  It guarantees that no matter what hash of
@@@ -2324,12 -2334,11 +2332,11 @@@ could now perform the load of x before 
  a control dependency but no address dependency at the machine level).
  
  Finally, it turns out there is a situation in which a plain write does
- not need to be w-post-bounded: when it is separated from the
- conflicting access by a fence.  At first glance this may seem
- impossible.  After all, to be conflicting the second access has to be
- on a different CPU from the first, and fences don't link events on
- different CPUs.  Well, normal fences don't -- but rcu-fence can!
- Here's an example:
+ not need to be w-post-bounded: when it is separated from the other
+ race-candidate access by a fence.  At first glance this may seem
+ impossible.  After all, to be race candidates the two accesses must
+ be on different CPUs, and fences don't link events on different CPUs.
+ Well, normal fences don't -- but rcu-fence can!  Here's an example:
  
        int x, y;
  
@@@ -2365,7 -2374,7 +2372,7 @@@ concurrent and there is no race, even t
  isn't w-post-bounded by any marked accesses.
  
  Putting all this material together yields the following picture.  For
two conflicting stores W and W', where W ->co W', the LKMM says the
race-candidate stores W and W', where W ->co W', the LKMM says the
  stores don't race if W can be linked to W' by a
  
        w-post-bounded ; vis ; w-pre-bounded
@@@ -2378,8 -2387,8 +2385,8 @@@ sequence, and if W' is plain then they 
  
        w-post-bounded ; vis ; r-pre-bounded
  
- sequence.  For a conflicting load R and store W, the LKMM says the two
- accesses don't race if R can be linked to W by an
+ sequence.  For race-candidate load R and store W, the LKMM says the
two accesses don't race if R can be linked to W by an
  
        r-post-bounded ; xb* ; w-pre-bounded
  
@@@ -2411,20 -2420,20 +2418,20 @@@ is, the rules governing the memory subs
  satisfy a load request and its determination of where a store will
  fall in the coherence order):
  
-       If R and W conflict and it is possible to link R to W by one
-       of the xb* sequences listed above, then W ->rfe R is not
-       allowed (i.e., a load cannot read from a store that it
+       If R and W are race candidates and it is possible to link R to
+       W by one of the xb* sequences listed above, then W ->rfe R is
+       not allowed (i.e., a load cannot read from a store that it
        executes before, even if one or both is plain).
  
-       If W and R conflict and it is possible to link W to R by one
-       of the vis sequences listed above, then R ->fre W is not
-       allowed (i.e., if a store is visible to a load then the load
-       must read from that store or one coherence-after it).
+       If W and R are race candidates and it is possible to link W to
+       R by one of the vis sequences listed above, then R ->fre W is
+       not allowed (i.e., if a store is visible to a load then the
+       load must read from that store or one coherence-after it).
  
-       If W and W' conflict and it is possible to link W to W' by one
-       of the vis sequences listed above, then W' ->co W is not
-       allowed (i.e., if one store is visible to a second then the
-       second must come after the first in the coherence order).
+       If W and W' are race candidates and it is possible to link W
+       to W' by one of the vis sequences listed above, then W' ->co W
+       is not allowed (i.e., if one store is visible to a second then
+       the second must come after the first in the coherence order).
  
  This is the extent to which the LKMM deals with plain accesses.
  Perhaps it could say more (for example, plain accesses might
This page took 0.190298 seconds and 4 git commands to generate.