Merge commit 'fixes.2015.02.23a' into core/rcu
authorIngo Molnar <mingo@kernel.org>
Tue, 15 Mar 2016 08:00:12 +0000 (09:00 +0100)
committerIngo Molnar <mingo@kernel.org>
Tue, 15 Mar 2016 08:01:06 +0000 (09:01 +0100)
 Conflicts:
kernel/rcu/tree.c

Signed-off-by: Ingo Molnar <mingo@kernel.org>
1  2 
include/linux/compiler.h
kernel/rcu/tree.c
kernel/rcu/tree.h
kernel/rcu/tree_plugin.h

diff --combined include/linux/compiler.h
  # define __pmem               __attribute__((noderef, address_space(5)))
  #ifdef CONFIG_SPARSE_RCU_POINTER
  # define __rcu                __attribute__((noderef, address_space(4)))
- #else
+ #else /* CONFIG_SPARSE_RCU_POINTER */
  # define __rcu
- #endif
+ #endif /* CONFIG_SPARSE_RCU_POINTER */
+ # define __private    __attribute__((noderef))
  extern void __chk_user_ptr(const volatile void __user *);
  extern void __chk_io_ptr(const volatile void __iomem *);
- #else
+ # define ACCESS_PRIVATE(p, member) (*((typeof((p)->member) __force *) &(p)->member))
+ #else /* __CHECKER__ */
  # define __user
  # define __kernel
  # define __safe
@@@ -44,7 -46,9 +46,9 @@@
  # define __percpu
  # define __rcu
  # define __pmem
- #endif
+ # define __private
+ # define ACCESS_PRIVATE(p, member) ((p)->member)
+ #endif /* __CHECKER__ */
  
  /* Indirect macros required for expanded argument pasting, eg. __LINE__. */
  #define ___PASTE(a,b) a##b
@@@ -144,7 -148,7 +148,7 @@@ void ftrace_likely_update(struct ftrace
   */
  #define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
  #define __trace_if(cond) \
 -      if (__builtin_constant_p((cond)) ? !!(cond) :                   \
 +      if (__builtin_constant_p(!!(cond)) ? !!(cond) :                 \
        ({                                                              \
                int ______r;                                            \
                static struct ftrace_branch_data                        \
@@@ -263,9 -267,8 +267,9 @@@ static __always_inline void __write_onc
   * In contrast to ACCESS_ONCE these two macros will also work on aggregate
   * data types like structs or unions. If the size of the accessed data
   * type exceeds the word size of the machine (e.g., 32 bits or 64 bits)
 - * READ_ONCE() and WRITE_ONCE()  will fall back to memcpy and print a
 - * compile-time warning.
 + * READ_ONCE() and WRITE_ONCE() will fall back to memcpy(). There's at
 + * least two memcpy()s: one for the __builtin_memcpy() and then one for
 + * the macro doing the copy of variable - '__u' allocated on the stack.
   *
   * Their two major use cases are: (1) Mediating communication between
   * process-level code and irq/NMI handlers, all running on the same CPU,
diff --combined kernel/rcu/tree.c
@@@ -108,7 -108,6 +108,6 @@@ RCU_STATE_INITIALIZER(rcu_sched, 's', c
  RCU_STATE_INITIALIZER(rcu_bh, 'b', call_rcu_bh);
  
  static struct rcu_state *const rcu_state_p;
- static struct rcu_data __percpu *const rcu_data_p;
  LIST_HEAD(rcu_struct_flavors);
  
  /* Dump rcu_node combining tree at boot to verify correct setup. */
@@@ -1083,13 -1082,12 +1082,12 @@@ static int dyntick_save_progress_counte
        rcu_sysidle_check_cpu(rdp, isidle, maxj);
        if ((rdp->dynticks_snap & 0x1) == 0) {
                trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("dti"));
-               return 1;
-       } else {
                if (ULONG_CMP_LT(READ_ONCE(rdp->gpnum) + ULONG_MAX / 4,
                                 rdp->mynode->gpnum))
                        WRITE_ONCE(rdp->gpwrap, true);
-               return 0;
+               return 1;
        }
+       return 0;
  }
  
  /*
@@@ -1173,15 -1171,16 +1171,16 @@@ static int rcu_implicit_dynticks_qs(str
                        smp_mb(); /* ->cond_resched_completed before *rcrmp. */
                        WRITE_ONCE(*rcrmp,
                                   READ_ONCE(*rcrmp) + rdp->rsp->flavor_mask);
-                       resched_cpu(rdp->cpu);  /* Force CPU into scheduler. */
-                       rdp->rsp->jiffies_resched += 5; /* Enable beating. */
-               } else if (ULONG_CMP_GE(jiffies, rdp->rsp->jiffies_resched)) {
-                       /* Time to beat on that CPU again! */
-                       resched_cpu(rdp->cpu);  /* Force CPU into scheduler. */
-                       rdp->rsp->jiffies_resched += 5; /* Re-enable beating. */
                }
+               rdp->rsp->jiffies_resched += 5; /* Re-enable beating. */
        }
  
+       /* And if it has been a really long time, kick the CPU as well. */
+       if (ULONG_CMP_GE(jiffies,
+                        rdp->rsp->gp_start + 2 * jiffies_till_sched_qs) ||
+           ULONG_CMP_GE(jiffies, rdp->rsp->gp_start + jiffies_till_sched_qs))
+               resched_cpu(rdp->cpu);  /* Force CPU into scheduler. */
        return 0;
  }
  
@@@ -1246,7 -1245,7 +1245,7 @@@ static void rcu_dump_cpu_stacks(struct 
                                if (rnp->qsmask & (1UL << cpu))
                                        dump_cpu_task(rnp->grplo + cpu);
                }
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
        }
  }
  
@@@ -1266,12 -1265,12 +1265,12 @@@ static void print_other_cpu_stall(struc
        raw_spin_lock_irqsave_rcu_node(rnp, flags);
        delta = jiffies - READ_ONCE(rsp->jiffies_stall);
        if (delta < RCU_STALL_RAT_DELAY || !rcu_gp_in_progress(rsp)) {
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                return;
        }
        WRITE_ONCE(rsp->jiffies_stall,
                   jiffies + 3 * rcu_jiffies_till_stall_check() + 3);
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
  
        /*
         * OK, time to rat on our buddy...
                                        ndetected++;
                                }
                }
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
        }
  
        print_cpu_stall_info_end();
@@@ -1357,7 -1356,7 +1356,7 @@@ static void print_cpu_stall(struct rcu_
        if (ULONG_CMP_GE(jiffies, READ_ONCE(rsp->jiffies_stall)))
                WRITE_ONCE(rsp->jiffies_stall,
                           jiffies + 3 * rcu_jiffies_till_stall_check() + 3);
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
  
        /*
         * Attempt to revive the RCU machinery by forcing a context switch.
@@@ -1595,7 -1594,7 +1594,7 @@@ rcu_start_future_gp(struct rcu_node *rn
        }
  unlock_out:
        if (rnp != rnp_root)
-               raw_spin_unlock(&rnp_root->lock);
+               raw_spin_unlock_rcu_node(rnp_root);
  out:
        if (c_out != NULL)
                *c_out = c;
@@@ -1614,6 -1613,7 +1613,6 @@@ static int rcu_future_gp_cleanup(struc
        int needmore;
        struct rcu_data *rdp = this_cpu_ptr(rsp->rda);
  
 -      rcu_nocb_gp_cleanup(rsp, rnp);
        rnp->need_future_gp[c & 0x1] = 0;
        needmore = rnp->need_future_gp[(c + 1) & 0x1];
        trace_rcu_future_gp(rnp, rdp, c,
@@@ -1634,7 -1634,7 +1633,7 @@@ static void rcu_gp_kthread_wake(struct 
            !READ_ONCE(rsp->gp_flags) ||
            !rsp->gp_kthread)
                return;
 -      wake_up(&rsp->gp_wq);
 +      swake_up(&rsp->gp_wq);
  }
  
  /*
@@@ -1814,7 -1814,7 +1813,7 @@@ static void note_gp_changes(struct rcu_
                return;
        }
        needwake = __note_gp_changes(rsp, rnp, rdp);
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
        if (needwake)
                rcu_gp_kthread_wake(rsp);
  }
@@@ -1839,7 -1839,7 +1838,7 @@@ static bool rcu_gp_init(struct rcu_stat
        raw_spin_lock_irq_rcu_node(rnp);
        if (!READ_ONCE(rsp->gp_flags)) {
                /* Spurious wakeup, tell caller to go back to sleep.  */
-               raw_spin_unlock_irq(&rnp->lock);
+               raw_spin_unlock_irq_rcu_node(rnp);
                return false;
        }
        WRITE_ONCE(rsp->gp_flags, 0); /* Clear all flags: New grace period. */
                 * Grace period already in progress, don't start another.
                 * Not supposed to be able to happen.
                 */
-               raw_spin_unlock_irq(&rnp->lock);
+               raw_spin_unlock_irq_rcu_node(rnp);
                return false;
        }
  
        /* Record GP times before starting GP, hence smp_store_release(). */
        smp_store_release(&rsp->gpnum, rsp->gpnum + 1);
        trace_rcu_grace_period(rsp->name, rsp->gpnum, TPS("start"));
-       raw_spin_unlock_irq(&rnp->lock);
+       raw_spin_unlock_irq_rcu_node(rnp);
  
        /*
         * Apply per-leaf buffered online and offline operations to the
                if (rnp->qsmaskinit == rnp->qsmaskinitnext &&
                    !rnp->wait_blkd_tasks) {
                        /* Nothing to do on this leaf rcu_node structure. */
-                       raw_spin_unlock_irq(&rnp->lock);
+                       raw_spin_unlock_irq_rcu_node(rnp);
                        continue;
                }
  
                        rcu_cleanup_dead_rnp(rnp);
                }
  
-               raw_spin_unlock_irq(&rnp->lock);
+               raw_spin_unlock_irq_rcu_node(rnp);
        }
  
        /*
                trace_rcu_grace_period_init(rsp->name, rnp->gpnum,
                                            rnp->level, rnp->grplo,
                                            rnp->grphi, rnp->qsmask);
-               raw_spin_unlock_irq(&rnp->lock);
+               raw_spin_unlock_irq_rcu_node(rnp);
                cond_resched_rcu_qs();
                WRITE_ONCE(rsp->gp_activity, jiffies);
        }
@@@ -1995,7 -1995,7 +1994,7 @@@ static void rcu_gp_fqs(struct rcu_stat
                raw_spin_lock_irq_rcu_node(rnp);
                WRITE_ONCE(rsp->gp_flags,
                           READ_ONCE(rsp->gp_flags) & ~RCU_GP_FLAG_FQS);
-               raw_spin_unlock_irq(&rnp->lock);
+               raw_spin_unlock_irq_rcu_node(rnp);
        }
  }
  
@@@ -2009,7 -2009,6 +2008,7 @@@ static void rcu_gp_cleanup(struct rcu_s
        int nocb = 0;
        struct rcu_data *rdp;
        struct rcu_node *rnp = rcu_get_root(rsp);
 +      struct swait_queue_head *sq;
  
        WRITE_ONCE(rsp->gp_activity, jiffies);
        raw_spin_lock_irq_rcu_node(rnp);
         * safe for us to drop the lock in order to mark the grace
         * period as completed in all of the rcu_node structures.
         */
-       raw_spin_unlock_irq(&rnp->lock);
+       raw_spin_unlock_irq_rcu_node(rnp);
  
        /*
         * Propagate new ->completed value to rcu_node structures so
                        needgp = __note_gp_changes(rsp, rnp, rdp) || needgp;
                /* smp_mb() provided by prior unlock-lock pair. */
                nocb += rcu_future_gp_cleanup(rsp, rnp);
-               raw_spin_unlock_irq(&rnp->lock);
 +              sq = rcu_nocb_gp_get(rnp);
+               raw_spin_unlock_irq_rcu_node(rnp);
 +              rcu_nocb_gp_cleanup(sq);
                cond_resched_rcu_qs();
                WRITE_ONCE(rsp->gp_activity, jiffies);
                rcu_gp_slow(rsp, gp_cleanup_delay);
                                       READ_ONCE(rsp->gpnum),
                                       TPS("newreq"));
        }
-       raw_spin_unlock_irq(&rnp->lock);
+       raw_spin_unlock_irq_rcu_node(rnp);
  }
  
  /*
@@@ -2094,7 -2091,7 +2093,7 @@@ static int __noreturn rcu_gp_kthread(vo
                                               READ_ONCE(rsp->gpnum),
                                               TPS("reqwait"));
                        rsp->gp_state = RCU_GP_WAIT_GPS;
 -                      wait_event_interruptible(rsp->gp_wq,
 +                      swait_event_interruptible(rsp->gp_wq,
                                                 READ_ONCE(rsp->gp_flags) &
                                                 RCU_GP_FLAG_INIT);
                        rsp->gp_state = RCU_GP_DONE_GPS;
                                               READ_ONCE(rsp->gpnum),
                                               TPS("fqswait"));
                        rsp->gp_state = RCU_GP_WAIT_FQS;
 -                      ret = wait_event_interruptible_timeout(rsp->gp_wq,
 +                      ret = swait_event_interruptible_timeout(rsp->gp_wq,
                                        rcu_gp_fqs_check_wake(rsp, &gf), j);
                        rsp->gp_state = RCU_GP_DOING_FQS;
                        /* Locking provides needed memory barriers. */
@@@ -2236,19 -2233,21 +2235,21 @@@ static bool rcu_start_gp(struct rcu_sta
  }
  
  /*
-  * Report a full set of quiescent states to the specified rcu_state
-  * data structure.  This involves cleaning up after the prior grace
-  * period and letting rcu_start_gp() start up the next grace period
-  * if one is needed.  Note that the caller must hold rnp->lock, which
-  * is released before return.
+  * Report a full set of quiescent states to the specified rcu_state data
+  * structure.  Invoke rcu_gp_kthread_wake() to awaken the grace-period
+  * kthread if another grace period is required.  Whether we wake
+  * the grace-period kthread or it awakens itself for the next round
+  * of quiescent-state forcing, that kthread will clean up after the
+  * just-completed grace period.  Note that the caller must hold rnp->lock,
+  * which is released before return.
   */
  static void rcu_report_qs_rsp(struct rcu_state *rsp, unsigned long flags)
        __releases(rcu_get_root(rsp)->lock)
  {
        WARN_ON_ONCE(!rcu_gp_in_progress(rsp));
        WRITE_ONCE(rsp->gp_flags, READ_ONCE(rsp->gp_flags) | RCU_GP_FLAG_FQS);
-       raw_spin_unlock_irqrestore(&rcu_get_root(rsp)->lock, flags);
+       raw_spin_unlock_irqrestore_rcu_node(rcu_get_root(rsp), flags);
 -      rcu_gp_kthread_wake(rsp);
 +      swake_up(&rsp->gp_wq);  /* Memory barrier implied by swake_up() path. */
  }
  
  /*
@@@ -2277,7 -2276,7 +2278,7 @@@ rcu_report_qs_rnp(unsigned long mask, s
                         * Our bit has already been cleared, or the
                         * relevant grace period is already over, so done.
                         */
-                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+                       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                        return;
                }
                WARN_ON_ONCE(oldmask); /* Any child must be all zeroed! */
                if (rnp->qsmask != 0 || rcu_preempt_blocked_readers_cgp(rnp)) {
  
                        /* Other bits still set at this level, so done. */
-                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+                       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                        return;
                }
                mask = rnp->grpmask;
  
                        break;
                }
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                rnp_c = rnp;
                rnp = rnp->parent;
                raw_spin_lock_irqsave_rcu_node(rnp, flags);
@@@ -2331,7 -2330,7 +2332,7 @@@ static void rcu_report_unblock_qs_rnp(s
  
        if (rcu_state_p == &rcu_sched_state || rsp != rcu_state_p ||
            rnp->qsmask != 0 || rcu_preempt_blocked_readers_cgp(rnp)) {
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                return;  /* Still need more quiescent states! */
        }
  
        /* Report up the rest of the hierarchy, tracking current ->gpnum. */
        gps = rnp->gpnum;
        mask = rnp->grpmask;
-       raw_spin_unlock(&rnp->lock);    /* irqs remain disabled. */
+       raw_spin_unlock_rcu_node(rnp);  /* irqs remain disabled. */
        raw_spin_lock_rcu_node(rnp_p);  /* irqs already disabled. */
        rcu_report_qs_rnp(mask, rsp, rnp_p, gps, flags);
  }
  
  /*
   * Record a quiescent state for the specified CPU to that CPU's rcu_data
-  * structure.  This must be either called from the specified CPU, or
-  * called when the specified CPU is known to be offline (and when it is
-  * also known that no other CPU is concurrently trying to help the offline
-  * CPU).  The lastcomp argument is used to make sure we are still in the
-  * grace period of interest.  We don't want to end the current grace period
-  * based on quiescent states detected in an earlier grace period!
+  * structure.  This must be called from the specified CPU.
   */
  static void
  rcu_report_qs_rdp(int cpu, struct rcu_state *rsp, struct rcu_data *rdp)
                 */
                rdp->cpu_no_qs.b.norm = true;   /* need qs for new gp. */
                rdp->rcu_qs_ctr_snap = __this_cpu_read(rcu_qs_ctr);
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                return;
        }
        mask = rdp->grpmask;
        if ((rnp->qsmask & mask) == 0) {
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
        } else {
-               rdp->core_needs_qs = 0;
+               rdp->core_needs_qs = false;
  
                /*
                 * This GP can't end until cpu checks in, so all of our
@@@ -2601,10 -2595,11 +2597,11 @@@ static void rcu_cleanup_dead_rnp(struc
                rnp->qsmaskinit &= ~mask;
                rnp->qsmask &= ~mask;
                if (rnp->qsmaskinit) {
-                       raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
+                       raw_spin_unlock_rcu_node(rnp);
+                       /* irqs remain disabled. */
                        return;
                }
-               raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
+               raw_spin_unlock_rcu_node(rnp); /* irqs remain disabled. */
        }
  }
  
@@@ -2627,7 -2622,7 +2624,7 @@@ static void rcu_cleanup_dying_idle_cpu(
        mask = rdp->grpmask;
        raw_spin_lock_irqsave_rcu_node(rnp, flags); /* Enforce GP memory-order guarantee. */
        rnp->qsmaskinitnext &= ~mask;
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
  }
  
  /*
@@@ -2861,7 -2856,7 +2858,7 @@@ static void force_qs_rnp(struct rcu_sta
                        rcu_report_qs_rnp(mask, rsp, rnp, rnp->gpnum, flags);
                } else {
                        /* Nothing to do here, so just drop the lock. */
-                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+                       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                }
        }
  }
@@@ -2897,12 -2892,12 +2894,12 @@@ static void force_quiescent_state(struc
        raw_spin_unlock(&rnp_old->fqslock);
        if (READ_ONCE(rsp->gp_flags) & RCU_GP_FLAG_FQS) {
                rsp->n_force_qs_lh++;
-               raw_spin_unlock_irqrestore(&rnp_old->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp_old, flags);
                return;  /* Someone beat us to it. */
        }
        WRITE_ONCE(rsp->gp_flags, READ_ONCE(rsp->gp_flags) | RCU_GP_FLAG_FQS);
-       raw_spin_unlock_irqrestore(&rnp_old->lock, flags);
+       raw_spin_unlock_irqrestore_rcu_node(rnp_old, flags);
 -      rcu_gp_kthread_wake(rsp);
 +      swake_up(&rsp->gp_wq); /* Memory barrier implied by swake_up() path. */
  }
  
  /*
@@@ -2927,7 -2922,7 +2924,7 @@@ __rcu_process_callbacks(struct rcu_stat
        if (cpu_needs_another_gp(rsp, rdp)) {
                raw_spin_lock_rcu_node(rcu_get_root(rsp)); /* irqs disabled. */
                needwake = rcu_start_gp(rsp);
-               raw_spin_unlock_irqrestore(&rcu_get_root(rsp)->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rcu_get_root(rsp), flags);
                if (needwake)
                        rcu_gp_kthread_wake(rsp);
        } else {
@@@ -3018,7 -3013,7 +3015,7 @@@ static void __call_rcu_core(struct rcu_
  
                        raw_spin_lock_rcu_node(rnp_root);
                        needwake = rcu_start_gp(rsp);
-                       raw_spin_unlock(&rnp_root->lock);
+                       raw_spin_unlock_rcu_node(rnp_root);
                        if (needwake)
                                rcu_gp_kthread_wake(rsp);
                } else {
@@@ -3438,14 -3433,14 +3435,14 @@@ static void sync_exp_reset_tree_hotplug
        rcu_for_each_leaf_node(rsp, rnp) {
                raw_spin_lock_irqsave_rcu_node(rnp, flags);
                if (rnp->expmaskinit == rnp->expmaskinitnext) {
-                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+                       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                        continue;  /* No new CPUs, nothing to do. */
                }
  
                /* Update this node's mask, track old value for propagation. */
                oldmask = rnp->expmaskinit;
                rnp->expmaskinit = rnp->expmaskinitnext;
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
  
                /* If was already nonzero, nothing to propagate. */
                if (oldmask)
                        if (rnp_up->expmaskinit)
                                done = true;
                        rnp_up->expmaskinit |= mask;
-                       raw_spin_unlock_irqrestore(&rnp_up->lock, flags);
+                       raw_spin_unlock_irqrestore_rcu_node(rnp_up, flags);
                        if (done)
                                break;
                        mask = rnp_up->grpmask;
@@@ -3483,7 -3478,7 +3480,7 @@@ static void __maybe_unused sync_exp_res
                raw_spin_lock_irqsave_rcu_node(rnp, flags);
                WARN_ON_ONCE(rnp->expmask);
                rnp->expmask = rnp->expmaskinit;
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
        }
  }
  
@@@ -3524,19 -3519,19 +3521,19 @@@ static void __rcu_report_exp_rnp(struc
                        if (!rnp->expmask)
                                rcu_initiate_boost(rnp, flags);
                        else
-                               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+                               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                        break;
                }
                if (rnp->parent == NULL) {
-                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+                       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                        if (wake) {
                                smp_mb(); /* EGP done before wake_up(). */
 -                              wake_up(&rsp->expedited_wq);
 +                              swake_up(&rsp->expedited_wq);
                        }
                        break;
                }
                mask = rnp->grpmask;
-               raw_spin_unlock(&rnp->lock); /* irqs remain disabled */
+               raw_spin_unlock_rcu_node(rnp); /* irqs remain disabled */
                rnp = rnp->parent;
                raw_spin_lock_rcu_node(rnp); /* irqs already disabled */
                WARN_ON_ONCE(!(rnp->expmask & mask));
@@@ -3571,7 -3566,7 +3568,7 @@@ static void rcu_report_exp_cpu_mult(str
  
        raw_spin_lock_irqsave_rcu_node(rnp, flags);
        if (!(rnp->expmask & mask)) {
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                return;
        }
        rnp->expmask &= ~mask;
@@@ -3732,7 -3727,7 +3729,7 @@@ static void sync_rcu_exp_select_cpus(st
                 */
                if (rcu_preempt_has_tasks(rnp))
                        rnp->exp_tasks = rnp->blkd_tasks.next;
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
  
                /* IPI the remaining CPUs for expedited quiescent state. */
                mask = 1;
@@@ -3749,7 -3744,7 +3746,7 @@@ retry_ipi
                        raw_spin_lock_irqsave_rcu_node(rnp, flags);
                        if (cpu_online(cpu) &&
                            (rnp->expmask & mask)) {
-                               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+                               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                                schedule_timeout_uninterruptible(1);
                                if (cpu_online(cpu) &&
                                    (rnp->expmask & mask))
                        }
                        if (!(rnp->expmask & mask))
                                mask_ofl_ipi &= ~mask;
-                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+                       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                }
                /* Report quiescent states for those that went offline. */
                mask_ofl_test |= mask_ofl_ipi;
@@@ -3782,7 -3777,7 +3779,7 @@@ static void synchronize_sched_expedited
        jiffies_start = jiffies;
  
        for (;;) {
 -              ret = wait_event_interruptible_timeout(
 +              ret = swait_event_timeout(
                                rsp->expedited_wq,
                                sync_rcu_preempt_exp_done(rnp_root),
                                jiffies_stall);
                        return;
                if (ret < 0) {
                        /* Hit a signal, disable CPU stall warnings. */
 -                      wait_event(rsp->expedited_wq,
 +                      swait_event(rsp->expedited_wq,
                                   sync_rcu_preempt_exp_done(rnp_root));
                        return;
                }
@@@ -4165,7 -4160,7 +4162,7 @@@ static void rcu_init_new_rnp(struct rcu
                        return;
                raw_spin_lock_rcu_node(rnp); /* Interrupts already disabled. */
                rnp->qsmaskinit |= mask;
-               raw_spin_unlock(&rnp->lock); /* Interrupts remain disabled. */
+               raw_spin_unlock_rcu_node(rnp); /* Interrupts remain disabled. */
        }
  }
  
@@@ -4189,7 -4184,7 +4186,7 @@@ rcu_boot_init_percpu_data(int cpu, stru
        rdp->rsp = rsp;
        mutex_init(&rdp->exp_funnel_mutex);
        rcu_boot_init_nocb_percpu_data(rdp);
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
  }
  
  /*
@@@ -4217,7 -4212,7 +4214,7 @@@ rcu_init_percpu_data(int cpu, struct rc
        rcu_sysidle_init_percpu_data(rdp->dynticks);
        atomic_set(&rdp->dynticks->dynticks,
                   (atomic_read(&rdp->dynticks->dynticks) & ~0x1) + 1);
-       raw_spin_unlock(&rnp->lock);            /* irqs remain disabled. */
+       raw_spin_unlock_rcu_node(rnp);          /* irqs remain disabled. */
  
        /*
         * Add CPU to leaf rcu_node pending-online bitmask.  Any needed
        rdp->rcu_qs_ctr_snap = per_cpu(rcu_qs_ctr, cpu);
        rdp->core_needs_qs = false;
        trace_rcu_grace_period(rsp->name, rdp->gpnum, TPS("cpuonl"));
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
  }
  
  static void rcu_prepare_cpu(int cpu)
@@@ -4360,7 -4355,7 +4357,7 @@@ static int __init rcu_spawn_gp_kthread(
                        sp.sched_priority = kthread_prio;
                        sched_setscheduler_nocheck(t, SCHED_FIFO, &sp);
                }
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                wake_up_process(t);
        }
        rcu_spawn_nocb_kthreads();
@@@ -4451,8 -4446,8 +4448,8 @@@ static void __init rcu_init_one(struct 
                cpustride *= levelspread[i];
                rnp = rsp->level[i];
                for (j = 0; j < levelcnt[i]; j++, rnp++) {
-                       raw_spin_lock_init(&rnp->lock);
-                       lockdep_set_class_and_name(&rnp->lock,
+                       raw_spin_lock_init(&ACCESS_PRIVATE(rnp, lock));
+                       lockdep_set_class_and_name(&ACCESS_PRIVATE(rnp, lock),
                                                   &rcu_node_class[i], buf[i]);
                        raw_spin_lock_init(&rnp->fqslock);
                        lockdep_set_class_and_name(&rnp->fqslock,
                }
        }
  
 -      init_waitqueue_head(&rsp->gp_wq);
 -      init_waitqueue_head(&rsp->expedited_wq);
 +      init_swait_queue_head(&rsp->gp_wq);
 +      init_swait_queue_head(&rsp->expedited_wq);
        rnp = rsp->level[rcu_num_lvls - 1];
        for_each_possible_cpu(i) {
                while (i > rnp->grphi)
diff --combined kernel/rcu/tree.h
@@@ -27,7 -27,6 +27,7 @@@
  #include <linux/threads.h>
  #include <linux/cpumask.h>
  #include <linux/seqlock.h>
 +#include <linux/swait.h>
  #include <linux/stop_machine.h>
  
  /*
@@@ -150,8 -149,9 +150,9 @@@ struct rcu_dynticks 
   * Definition for node within the RCU grace-period-detection hierarchy.
   */
  struct rcu_node {
-       raw_spinlock_t lock;    /* Root rcu_node's lock protects some */
-                               /*  rcu_state fields as well as following. */
+       raw_spinlock_t __private lock;  /* Root rcu_node's lock protects */
+                                       /*  some rcu_state fields as well as */
+                                       /*  following. */
        unsigned long gpnum;    /* Current grace period for this node. */
                                /*  This will either be equal to or one */
                                /*  behind the root rcu_node's gpnum. */
                                /* Refused to boost: not sure why, though. */
                                /*  This can happen due to race conditions. */
  #ifdef CONFIG_RCU_NOCB_CPU
 -      wait_queue_head_t nocb_gp_wq[2];
 +      struct swait_queue_head nocb_gp_wq[2];
                                /* Place for rcu_nocb_kthread() to wait GP. */
  #endif /* #ifdef CONFIG_RCU_NOCB_CPU */
        int need_future_gp[2];
@@@ -400,7 -400,7 +401,7 @@@ struct rcu_data 
        atomic_long_t nocb_q_count_lazy; /*  invocation (all stages). */
        struct rcu_head *nocb_follower_head; /* CBs ready to invoke. */
        struct rcu_head **nocb_follower_tail;
 -      wait_queue_head_t nocb_wq;      /* For nocb kthreads to sleep on. */
 +      struct swait_queue_head nocb_wq; /* For nocb kthreads to sleep on. */
        struct task_struct *nocb_kthread;
        int nocb_defer_wakeup;          /* Defer wakeup of nocb_kthread. */
  
@@@ -479,7 -479,7 +480,7 @@@ struct rcu_state 
        unsigned long gpnum;                    /* Current gp number. */
        unsigned long completed;                /* # of last completed gp. */
        struct task_struct *gp_kthread;         /* Task for grace periods. */
 -      wait_queue_head_t gp_wq;                /* Where GP task waits. */
 +      struct swait_queue_head gp_wq;          /* Where GP task waits. */
        short gp_flags;                         /* Commands for GP task. */
        short gp_state;                         /* GP kthread sleep state. */
  
        unsigned long expedited_sequence;       /* Take a ticket. */
        atomic_long_t expedited_normal;         /* # fallbacks to normal. */
        atomic_t expedited_need_qs;             /* # CPUs left to check in. */
 -      wait_queue_head_t expedited_wq;         /* Wait for check-ins. */
 +      struct swait_queue_head expedited_wq;   /* Wait for check-ins. */
        int ncpus_snap;                         /* # CPUs seen last time. */
  
        unsigned long jiffies_force_qs;         /* Time at which to invoke */
@@@ -622,8 -622,7 +623,8 @@@ static void zero_cpu_stall_ticks(struc
  static void increment_cpu_stall_ticks(void);
  static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu);
  static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq);
 -static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp);
 +static struct swait_queue_head *rcu_nocb_gp_get(struct rcu_node *rnp);
 +static void rcu_nocb_gp_cleanup(struct swait_queue_head *sq);
  static void rcu_init_one_nocb(struct rcu_node *rnp);
  static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
                            bool lazy, unsigned long flags);
@@@ -682,7 -681,7 +683,7 @@@ static inline void rcu_nocb_q_lengths(s
  #endif /* #else #ifdef CONFIG_PPC */
  
  /*
-  * Wrappers for the rcu_node::lock acquire.
+  * Wrappers for the rcu_node::lock acquire and release.
   *
   * Because the rcu_nodes form a tree, the tree traversal locking will observe
   * different lock values, this in turn means that an UNLOCK of one level
   *
   * In order to restore full ordering between tree levels, augment the regular
   * lock acquire functions with smp_mb__after_unlock_lock().
+  *
+  * As ->lock of struct rcu_node is a __private field, therefore one should use
+  * these wrappers rather than directly call raw_spin_{lock,unlock}* on ->lock.
   */
  static inline void raw_spin_lock_rcu_node(struct rcu_node *rnp)
  {
-       raw_spin_lock(&rnp->lock);
+       raw_spin_lock(&ACCESS_PRIVATE(rnp, lock));
        smp_mb__after_unlock_lock();
  }
  
+ static inline void raw_spin_unlock_rcu_node(struct rcu_node *rnp)
+ {
+       raw_spin_unlock(&ACCESS_PRIVATE(rnp, lock));
+ }
  static inline void raw_spin_lock_irq_rcu_node(struct rcu_node *rnp)
  {
-       raw_spin_lock_irq(&rnp->lock);
+       raw_spin_lock_irq(&ACCESS_PRIVATE(rnp, lock));
        smp_mb__after_unlock_lock();
  }
  
- #define raw_spin_lock_irqsave_rcu_node(rnp, flags)    \
- do {                                                  \
-       typecheck(unsigned long, flags);                \
-       raw_spin_lock_irqsave(&(rnp)->lock, flags);     \
-       smp_mb__after_unlock_lock();                    \
+ static inline void raw_spin_unlock_irq_rcu_node(struct rcu_node *rnp)
+ {
+       raw_spin_unlock_irq(&ACCESS_PRIVATE(rnp, lock));
+ }
+ #define raw_spin_lock_irqsave_rcu_node(rnp, flags)                    \
+ do {                                                                  \
+       typecheck(unsigned long, flags);                                \
+       raw_spin_lock_irqsave(&ACCESS_PRIVATE(rnp, lock), flags);       \
+       smp_mb__after_unlock_lock();                                    \
+ } while (0)
+ #define raw_spin_unlock_irqrestore_rcu_node(rnp, flags)                       \
+ do {                                                                  \
+       typecheck(unsigned long, flags);                                \
+       raw_spin_unlock_irqrestore(&ACCESS_PRIVATE(rnp, lock), flags);  \
  } while (0)
  
  static inline bool raw_spin_trylock_rcu_node(struct rcu_node *rnp)
  {
-       bool locked = raw_spin_trylock(&rnp->lock);
+       bool locked = raw_spin_trylock(&ACCESS_PRIVATE(rnp, lock));
  
        if (locked)
                smp_mb__after_unlock_lock();
diff --combined kernel/rcu/tree_plugin.h
@@@ -235,7 -235,7 +235,7 @@@ static void rcu_preempt_ctxt_queue(stru
                rnp->gp_tasks = &t->rcu_node_entry;
        if (!rnp->exp_tasks && (blkd_state & RCU_EXP_BLKD))
                rnp->exp_tasks = &t->rcu_node_entry;
-       raw_spin_unlock(&rnp->lock); /* rrupts remain disabled. */
+       raw_spin_unlock_rcu_node(rnp); /* interrupts remain disabled. */
  
        /*
         * Report the quiescent state for the expedited GP.  This expedited
@@@ -489,7 -489,7 +489,7 @@@ void rcu_read_unlock_special(struct tas
                                                         !!rnp->gp_tasks);
                        rcu_report_unblock_qs_rnp(rcu_state_p, rnp, flags);
                } else {
-                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+                       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                }
  
                /* Unboost if we were boosted. */
@@@ -518,14 -518,14 +518,14 @@@ static void rcu_print_detail_task_stall
  
        raw_spin_lock_irqsave_rcu_node(rnp, flags);
        if (!rcu_preempt_blocked_readers_cgp(rnp)) {
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                return;
        }
        t = list_entry(rnp->gp_tasks->prev,
                       struct task_struct, rcu_node_entry);
        list_for_each_entry_continue(t, &rnp->blkd_tasks, rcu_node_entry)
                sched_show_task(t);
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
  }
  
  /*
@@@ -807,7 -807,6 +807,6 @@@ void exit_rcu(void
  #else /* #ifdef CONFIG_PREEMPT_RCU */
  
  static struct rcu_state *const rcu_state_p = &rcu_sched_state;
- static struct rcu_data __percpu *const rcu_data_p = &rcu_sched_data;
  
  /*
   * Tell them what RCU they are running.
@@@ -991,7 -990,7 +990,7 @@@ static int rcu_boost(struct rcu_node *r
         * might exit their RCU read-side critical sections on their own.
         */
        if (rnp->exp_tasks == NULL && rnp->boost_tasks == NULL) {
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                return 0;
        }
  
         */
        t = container_of(tb, struct task_struct, rcu_node_entry);
        rt_mutex_init_proxy_locked(&rnp->boost_mtx, t);
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
        /* Lock only for side effect: boosts task t's priority. */
        rt_mutex_lock(&rnp->boost_mtx);
        rt_mutex_unlock(&rnp->boost_mtx);  /* Then keep lockdep happy. */
@@@ -1088,7 -1087,7 +1087,7 @@@ static void rcu_initiate_boost(struct r
  
        if (!rcu_preempt_blocked_readers_cgp(rnp) && rnp->exp_tasks == NULL) {
                rnp->n_balk_exp_gp_tasks++;
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                return;
        }
        if (rnp->exp_tasks != NULL ||
             ULONG_CMP_GE(jiffies, rnp->boost_time))) {
                if (rnp->exp_tasks == NULL)
                        rnp->boost_tasks = rnp->gp_tasks;
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
                t = rnp->boost_kthread_task;
                if (t)
                        rcu_wake_cond(t, rnp->boost_kthread_status);
        } else {
                rcu_initiate_boost_trace(rnp);
-               raw_spin_unlock_irqrestore(&rnp->lock, flags);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
        }
  }
  
@@@ -1172,7 -1171,7 +1171,7 @@@ static int rcu_spawn_one_boost_kthread(
                return PTR_ERR(t);
        raw_spin_lock_irqsave_rcu_node(rnp, flags);
        rnp->boost_kthread_task = t;
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
        sp.sched_priority = kthread_prio;
        sched_setscheduler_nocheck(t, SCHED_FIFO, &sp);
        wake_up_process(t); /* get to TASK_INTERRUPTIBLE quickly. */
@@@ -1308,7 -1307,7 +1307,7 @@@ static void rcu_prepare_kthreads(int cp
  static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags)
        __releases(rnp->lock)
  {
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
  }
  
  static void invoke_rcu_callbacks_kthread(void)
@@@ -1559,7 -1558,7 +1558,7 @@@ static void rcu_prepare_for_idle(void
                rnp = rdp->mynode;
                raw_spin_lock_rcu_node(rnp); /* irqs already disabled. */
                needwake = rcu_accelerate_cbs(rsp, rnp, rdp);
-               raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
+               raw_spin_unlock_rcu_node(rnp); /* irqs remain disabled. */
                if (needwake)
                        rcu_gp_kthread_wake(rsp);
        }
@@@ -1811,9 -1810,9 +1810,9 @@@ early_param("rcu_nocb_poll", parse_rcu_
   * Wake up any no-CBs CPUs' kthreads that were waiting on the just-ended
   * grace period.
   */
 -static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
 +static void rcu_nocb_gp_cleanup(struct swait_queue_head *sq)
  {
 -      wake_up_all(&rnp->nocb_gp_wq[rnp->completed & 0x1]);
 +      swake_up_all(sq);
  }
  
  /*
@@@ -1829,15 -1828,10 +1828,15 @@@ static void rcu_nocb_gp_set(struct rcu_
        rnp->need_future_gp[(rnp->completed + 1) & 0x1] += nrq;
  }
  
 +static struct swait_queue_head *rcu_nocb_gp_get(struct rcu_node *rnp)
 +{
 +      return &rnp->nocb_gp_wq[rnp->completed & 0x1];
 +}
 +
  static void rcu_init_one_nocb(struct rcu_node *rnp)
  {
 -      init_waitqueue_head(&rnp->nocb_gp_wq[0]);
 -      init_waitqueue_head(&rnp->nocb_gp_wq[1]);
 +      init_swait_queue_head(&rnp->nocb_gp_wq[0]);
 +      init_swait_queue_head(&rnp->nocb_gp_wq[1]);
  }
  
  #ifndef CONFIG_RCU_NOCB_CPU_ALL
@@@ -1862,7 -1856,7 +1861,7 @@@ static void wake_nocb_leader(struct rcu
        if (READ_ONCE(rdp_leader->nocb_leader_sleep) || force) {
                /* Prior smp_mb__after_atomic() orders against prior enqueue. */
                WRITE_ONCE(rdp_leader->nocb_leader_sleep, false);
 -              wake_up(&rdp_leader->nocb_wq);
 +              swake_up(&rdp_leader->nocb_wq);
        }
  }
  
@@@ -2064,7 -2058,7 +2063,7 @@@ static void rcu_nocb_wait_gp(struct rcu
  
        raw_spin_lock_irqsave_rcu_node(rnp, flags);
        needwake = rcu_start_future_gp(rnp, rdp, &c);
-       raw_spin_unlock_irqrestore(&rnp->lock, flags);
+       raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
        if (needwake)
                rcu_gp_kthread_wake(rdp->rsp);
  
         */
        trace_rcu_future_gp(rnp, rdp, c, TPS("StartWait"));
        for (;;) {
 -              wait_event_interruptible(
 +              swait_event_interruptible(
                        rnp->nocb_gp_wq[c & 0x1],
                        (d = ULONG_CMP_GE(READ_ONCE(rnp->completed), c)));
                if (likely(d))
@@@ -2102,7 -2096,7 +2101,7 @@@ wait_again
        /* Wait for callbacks to appear. */
        if (!rcu_nocb_poll) {
                trace_rcu_nocb_wake(my_rdp->rsp->name, my_rdp->cpu, "Sleep");
 -              wait_event_interruptible(my_rdp->nocb_wq,
 +              swait_event_interruptible(my_rdp->nocb_wq,
                                !READ_ONCE(my_rdp->nocb_leader_sleep));
                /* Memory barrier handled by smp_mb() calls below and repoll. */
        } else if (firsttime) {
                         * List was empty, wake up the follower.
                         * Memory barriers supplied by atomic_long_add().
                         */
 -                      wake_up(&rdp->nocb_wq);
 +                      swake_up(&rdp->nocb_wq);
                }
        }
  
@@@ -2198,7 -2192,7 +2197,7 @@@ static void nocb_follower_wait(struct r
                if (!rcu_nocb_poll) {
                        trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
                                            "FollowerSleep");
 -                      wait_event_interruptible(rdp->nocb_wq,
 +                      swait_event_interruptible(rdp->nocb_wq,
                                                 READ_ONCE(rdp->nocb_follower_head));
                } else if (firsttime) {
                        /* Don't drown trace log with "Poll"! */
@@@ -2357,7 -2351,7 +2356,7 @@@ void __init rcu_init_nohz(void
  static void __init rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp)
  {
        rdp->nocb_tail = &rdp->nocb_head;
 -      init_waitqueue_head(&rdp->nocb_wq);
 +      init_swait_queue_head(&rdp->nocb_wq);
        rdp->nocb_follower_tail = &rdp->nocb_follower_head;
  }
  
@@@ -2507,7 -2501,7 +2506,7 @@@ static bool rcu_nocb_cpu_needs_barrier(
        return false;
  }
  
 -static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
 +static void rcu_nocb_gp_cleanup(struct swait_queue_head *sq)
  {
  }
  
@@@ -2515,11 -2509,6 +2514,11 @@@ static void rcu_nocb_gp_set(struct rcu_
  {
  }
  
 +static struct swait_queue_head *rcu_nocb_gp_get(struct rcu_node *rnp)
 +{
 +      return NULL;
 +}
 +
  static void rcu_init_one_nocb(struct rcu_node *rnp)
  {
  }