rcu: Don't allocate bootmem from rcu_init()
[pandora-kernel.git] / kernel / rcutree_plugin.h
index d084ae3..3db5a37 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/gfp.h>
 #include <linux/oom.h>
 #include <linux/smpboot.h>
+#include <linux/tick.h>
 
 #define RCU_KTHREAD_PRIO 1
 
@@ -87,7 +88,7 @@ static void __init rcu_bootup_announce_oddness(void)
 #ifdef CONFIG_RCU_NOCB_CPU
 #ifndef CONFIG_RCU_NOCB_CPU_NONE
        if (!have_rcu_nocb_mask) {
-               alloc_bootmem_cpumask_var(&rcu_nocb_mask);
+               zalloc_cpumask_var(&rcu_nocb_mask, GFP_KERNEL);
                have_rcu_nocb_mask = true;
        }
 #ifdef CONFIG_RCU_NOCB_CPU_ZERO
@@ -1666,7 +1667,7 @@ int rcu_needs_cpu(int cpu, unsigned long *dj)
        rdtp->last_accelerate = jiffies;
 
        /* Request timer delay depending on laziness, and round. */
-       if (rdtp->all_lazy) {
+       if (!rdtp->all_lazy) {
                *dj = round_up(rcu_idle_gp_delay + jiffies,
                               rcu_idle_gp_delay) - jiffies;
        } else {
@@ -1705,7 +1706,7 @@ static void rcu_prepare_for_idle(int cpu)
                return;
 
        /* If this is a no-CBs CPU, no callbacks, just return. */
-       if (is_nocb_cpu(cpu))
+       if (rcu_is_nocb_cpu(cpu))
                return;
 
        /*
@@ -1747,7 +1748,7 @@ static void rcu_cleanup_after_idle(int cpu)
        struct rcu_data *rdp;
        struct rcu_state *rsp;
 
-       if (is_nocb_cpu(cpu))
+       if (rcu_is_nocb_cpu(cpu))
                return;
        rcu_try_advance_all_cbs();
        for_each_rcu_flavor(rsp) {
@@ -2052,7 +2053,7 @@ static void rcu_init_one_nocb(struct rcu_node *rnp)
 }
 
 /* Is the specified CPU a no-CPUs CPU? */
-static bool is_nocb_cpu(int cpu)
+bool rcu_is_nocb_cpu(int cpu)
 {
        if (have_rcu_nocb_mask)
                return cpumask_test_cpu(cpu, rcu_nocb_mask);
@@ -2110,7 +2111,7 @@ static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
                            bool lazy)
 {
 
-       if (!is_nocb_cpu(rdp->cpu))
+       if (!rcu_is_nocb_cpu(rdp->cpu))
                return 0;
        __call_rcu_nocb_enqueue(rdp, rhp, &rhp->next, 1, lazy);
        if (__is_kfree_rcu_offset((unsigned long)rhp->func))
@@ -2134,7 +2135,7 @@ static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp,
        long qll = rsp->qlen_lazy;
 
        /* If this is not a no-CBs CPU, tell the caller to do it the old way. */
-       if (!is_nocb_cpu(smp_processor_id()))
+       if (!rcu_is_nocb_cpu(smp_processor_id()))
                return 0;
        rsp->qlen = 0;
        rsp->qlen_lazy = 0;
@@ -2306,11 +2307,6 @@ static void rcu_init_one_nocb(struct rcu_node *rnp)
 {
 }
 
-static bool is_nocb_cpu(int cpu)
-{
-       return false;
-}
-
 static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
                            bool lazy)
 {
@@ -2337,3 +2333,20 @@ static bool init_nocb_callback_list(struct rcu_data *rdp)
 }
 
 #endif /* #else #ifdef CONFIG_RCU_NOCB_CPU */
+
+/*
+ * An adaptive-ticks CPU can potentially execute in kernel mode for an
+ * arbitrarily long period of time with the scheduling-clock tick turned
+ * off.  RCU will be paying attention to this CPU because it is in the
+ * kernel, but the CPU cannot be guaranteed to be executing the RCU state
+ * machine because the scheduling-clock tick has been disabled.  Therefore,
+ * if an adaptive-ticks CPU is failing to respond to the current grace
+ * period and has not be idle from an RCU perspective, kick it.
+ */
+static void rcu_kick_nohz_cpu(int cpu)
+{
+#ifdef CONFIG_NO_HZ_FULL
+       if (tick_nohz_full_cpu(cpu))
+               smp_send_reschedule(cpu);
+#endif /* #ifdef CONFIG_NO_HZ_FULL */
+}