Commit 4d831f53 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'core-fixes-for-linus' of...

Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  kernel/softirq.c: fix sparse warning
  rcu: Make hierarchical RCU less IPI-happy
parents 20d92078 79d381c9
...@@ -161,9 +161,8 @@ struct rcu_data { ...@@ -161,9 +161,8 @@ struct rcu_data {
unsigned long offline_fqs; /* Kicked due to being offline. */ unsigned long offline_fqs; /* Kicked due to being offline. */
unsigned long resched_ipi; /* Sent a resched IPI. */ unsigned long resched_ipi; /* Sent a resched IPI. */
/* 5) state to allow this CPU to force_quiescent_state on others */ /* 5) For future __rcu_pending statistics. */
long n_rcu_pending; /* rcu_pending() calls since boot. */ long n_rcu_pending; /* rcu_pending() calls since boot. */
long n_rcu_pending_force_qs; /* when to force quiescent states. */
int cpu; int cpu;
}; };
......
...@@ -530,8 +530,6 @@ static void note_new_gpnum(struct rcu_state *rsp, struct rcu_data *rdp) ...@@ -530,8 +530,6 @@ static void note_new_gpnum(struct rcu_state *rsp, struct rcu_data *rdp)
rdp->qs_pending = 1; rdp->qs_pending = 1;
rdp->passed_quiesc = 0; rdp->passed_quiesc = 0;
rdp->gpnum = rsp->gpnum; rdp->gpnum = rsp->gpnum;
rdp->n_rcu_pending_force_qs = rdp->n_rcu_pending +
RCU_JIFFIES_TILL_FORCE_QS;
} }
/* /*
...@@ -578,8 +576,6 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags) ...@@ -578,8 +576,6 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
rsp->gpnum++; rsp->gpnum++;
rsp->signaled = RCU_GP_INIT; /* Hold off force_quiescent_state. */ rsp->signaled = RCU_GP_INIT; /* Hold off force_quiescent_state. */
rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS; rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS;
rdp->n_rcu_pending_force_qs = rdp->n_rcu_pending +
RCU_JIFFIES_TILL_FORCE_QS;
record_gp_stall_check_time(rsp); record_gp_stall_check_time(rsp);
dyntick_record_completed(rsp, rsp->completed - 1); dyntick_record_completed(rsp, rsp->completed - 1);
note_new_gpnum(rsp, rdp); note_new_gpnum(rsp, rdp);
...@@ -1055,7 +1051,6 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed) ...@@ -1055,7 +1051,6 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
{ {
unsigned long flags; unsigned long flags;
long lastcomp; long lastcomp;
struct rcu_data *rdp = rsp->rda[smp_processor_id()];
struct rcu_node *rnp = rcu_get_root(rsp); struct rcu_node *rnp = rcu_get_root(rsp);
u8 signaled; u8 signaled;
...@@ -1066,16 +1061,13 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed) ...@@ -1066,16 +1061,13 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
return; /* Someone else is already on the job. */ return; /* Someone else is already on the job. */
} }
if (relaxed && if (relaxed &&
(long)(rsp->jiffies_force_qs - jiffies) >= 0 && (long)(rsp->jiffies_force_qs - jiffies) >= 0)
(rdp->n_rcu_pending_force_qs - rdp->n_rcu_pending) >= 0)
goto unlock_ret; /* no emergency and done recently. */ goto unlock_ret; /* no emergency and done recently. */
rsp->n_force_qs++; rsp->n_force_qs++;
spin_lock(&rnp->lock); spin_lock(&rnp->lock);
lastcomp = rsp->completed; lastcomp = rsp->completed;
signaled = rsp->signaled; signaled = rsp->signaled;
rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS; rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS;
rdp->n_rcu_pending_force_qs = rdp->n_rcu_pending +
RCU_JIFFIES_TILL_FORCE_QS;
if (lastcomp == rsp->gpnum) { if (lastcomp == rsp->gpnum) {
rsp->n_force_qs_ngp++; rsp->n_force_qs_ngp++;
spin_unlock(&rnp->lock); spin_unlock(&rnp->lock);
...@@ -1144,8 +1136,7 @@ __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp) ...@@ -1144,8 +1136,7 @@ __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp)
* If an RCU GP has gone long enough, go check for dyntick * If an RCU GP has gone long enough, go check for dyntick
* idle CPUs and, if needed, send resched IPIs. * idle CPUs and, if needed, send resched IPIs.
*/ */
if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0 || if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0)
(rdp->n_rcu_pending_force_qs - rdp->n_rcu_pending) < 0)
force_quiescent_state(rsp, 1); force_quiescent_state(rsp, 1);
/* /*
...@@ -1230,8 +1221,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), ...@@ -1230,8 +1221,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
if (unlikely(++rdp->qlen > qhimark)) { if (unlikely(++rdp->qlen > qhimark)) {
rdp->blimit = LONG_MAX; rdp->blimit = LONG_MAX;
force_quiescent_state(rsp, 0); force_quiescent_state(rsp, 0);
} else if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0 || } else if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0)
(rdp->n_rcu_pending_force_qs - rdp->n_rcu_pending) < 0)
force_quiescent_state(rsp, 1); force_quiescent_state(rsp, 1);
local_irq_restore(flags); local_irq_restore(flags);
} }
...@@ -1290,8 +1280,7 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp) ...@@ -1290,8 +1280,7 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
/* Has an RCU GP gone long enough to send resched IPIs &c? */ /* Has an RCU GP gone long enough to send resched IPIs &c? */
if (ACCESS_ONCE(rsp->completed) != ACCESS_ONCE(rsp->gpnum) && if (ACCESS_ONCE(rsp->completed) != ACCESS_ONCE(rsp->gpnum) &&
((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0 || ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0))
(rdp->n_rcu_pending_force_qs - rdp->n_rcu_pending) < 0))
return 1; return 1;
/* nothing to do */ /* nothing to do */
......
...@@ -49,14 +49,12 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) ...@@ -49,14 +49,12 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)
{ {
if (!rdp->beenonline) if (!rdp->beenonline)
return; return;
seq_printf(m, "%3d%cc=%ld g=%ld pq=%d pqc=%ld qp=%d rpfq=%ld rp=%x", seq_printf(m, "%3d%cc=%ld g=%ld pq=%d pqc=%ld qp=%d",
rdp->cpu, rdp->cpu,
cpu_is_offline(rdp->cpu) ? '!' : ' ', cpu_is_offline(rdp->cpu) ? '!' : ' ',
rdp->completed, rdp->gpnum, rdp->completed, rdp->gpnum,
rdp->passed_quiesc, rdp->passed_quiesc_completed, rdp->passed_quiesc, rdp->passed_quiesc_completed,
rdp->qs_pending, rdp->qs_pending);
rdp->n_rcu_pending_force_qs - rdp->n_rcu_pending,
(int)(rdp->n_rcu_pending & 0xffff));
#ifdef CONFIG_NO_HZ #ifdef CONFIG_NO_HZ
seq_printf(m, " dt=%d/%d dn=%d df=%lu", seq_printf(m, " dt=%d/%d dn=%d df=%lu",
rdp->dynticks->dynticks, rdp->dynticks->dynticks,
...@@ -102,14 +100,12 @@ static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp) ...@@ -102,14 +100,12 @@ static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp)
{ {
if (!rdp->beenonline) if (!rdp->beenonline)
return; return;
seq_printf(m, "%d,%s,%ld,%ld,%d,%ld,%d,%ld,%ld", seq_printf(m, "%d,%s,%ld,%ld,%d,%ld,%d",
rdp->cpu, rdp->cpu,
cpu_is_offline(rdp->cpu) ? "\"Y\"" : "\"N\"", cpu_is_offline(rdp->cpu) ? "\"Y\"" : "\"N\"",
rdp->completed, rdp->gpnum, rdp->completed, rdp->gpnum,
rdp->passed_quiesc, rdp->passed_quiesc_completed, rdp->passed_quiesc, rdp->passed_quiesc_completed,
rdp->qs_pending, rdp->qs_pending);
rdp->n_rcu_pending_force_qs - rdp->n_rcu_pending,
rdp->n_rcu_pending);
#ifdef CONFIG_NO_HZ #ifdef CONFIG_NO_HZ
seq_printf(m, ",%d,%d,%d,%lu", seq_printf(m, ",%d,%d,%d,%lu",
rdp->dynticks->dynticks, rdp->dynticks->dynticks,
...@@ -123,7 +119,7 @@ static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp) ...@@ -123,7 +119,7 @@ static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp)
static int show_rcudata_csv(struct seq_file *m, void *unused) static int show_rcudata_csv(struct seq_file *m, void *unused)
{ {
seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pqc\",\"pq\",\"rpfq\",\"rp\","); seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pqc\",\"pq\",");
#ifdef CONFIG_NO_HZ #ifdef CONFIG_NO_HZ
seq_puts(m, "\"dt\",\"dt nesting\",\"dn\",\"df\","); seq_puts(m, "\"dt\",\"dt nesting\",\"dn\",\"df\",");
#endif /* #ifdef CONFIG_NO_HZ */ #endif /* #ifdef CONFIG_NO_HZ */
......
...@@ -472,9 +472,9 @@ void tasklet_kill(struct tasklet_struct *t) ...@@ -472,9 +472,9 @@ void tasklet_kill(struct tasklet_struct *t)
printk("Attempt to kill tasklet from interrupt\n"); printk("Attempt to kill tasklet from interrupt\n");
while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) { while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
do do {
yield(); yield();
while (test_bit(TASKLET_STATE_SCHED, &t->state)); } while (test_bit(TASKLET_STATE_SCHED, &t->state));
} }
tasklet_unlock_wait(t); tasklet_unlock_wait(t);
clear_bit(TASKLET_STATE_SCHED, &t->state); clear_bit(TASKLET_STATE_SCHED, &t->state);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment