diff options
| -rw-r--r-- | Documentation/filesystems/proc.txt | 1 | ||||
| -rw-r--r-- | include/linux/interrupt.h | 1 | ||||
| -rw-r--r-- | include/trace/events/irq.h | 3 | ||||
| -rw-r--r-- | kernel/rcutree.c | 23 | ||||
| -rw-r--r-- | kernel/rcutree.h | 1 | ||||
| -rw-r--r-- | kernel/rcutree_plugin.h | 9 | ||||
| -rw-r--r-- | kernel/softirq.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/trace-event-parse.c | 1 |
8 files changed, 35 insertions, 6 deletions
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index f48178024067..db3b1aba32a3 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt | |||
| @@ -843,6 +843,7 @@ Provides counts of softirq handlers serviced since boot time, for each cpu. | |||
| 843 | TASKLET: 0 0 0 290 | 843 | TASKLET: 0 0 0 290 |
| 844 | SCHED: 27035 26983 26971 26746 | 844 | SCHED: 27035 26983 26971 26746 |
| 845 | HRTIMER: 0 0 0 0 | 845 | HRTIMER: 0 0 0 0 |
| 846 | RCU: 1678 1769 2178 2250 | ||
| 846 | 847 | ||
| 847 | 848 | ||
| 848 | 1.3 IDE devices in /proc/ide | 849 | 1.3 IDE devices in /proc/ide |
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 6c12989839d9..f6efed0039ed 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
| @@ -414,6 +414,7 @@ enum | |||
| 414 | TASKLET_SOFTIRQ, | 414 | TASKLET_SOFTIRQ, |
| 415 | SCHED_SOFTIRQ, | 415 | SCHED_SOFTIRQ, |
| 416 | HRTIMER_SOFTIRQ, | 416 | HRTIMER_SOFTIRQ, |
| 417 | RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */ | ||
| 417 | 418 | ||
| 418 | NR_SOFTIRQS | 419 | NR_SOFTIRQS |
| 419 | }; | 420 | }; |
diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h index ae045ca7d356..1c09820df585 100644 --- a/include/trace/events/irq.h +++ b/include/trace/events/irq.h | |||
| @@ -20,7 +20,8 @@ struct softirq_action; | |||
| 20 | softirq_name(BLOCK_IOPOLL), \ | 20 | softirq_name(BLOCK_IOPOLL), \ |
| 21 | softirq_name(TASKLET), \ | 21 | softirq_name(TASKLET), \ |
| 22 | softirq_name(SCHED), \ | 22 | softirq_name(SCHED), \ |
| 23 | softirq_name(HRTIMER)) | 23 | softirq_name(HRTIMER), \ |
| 24 | softirq_name(RCU)) | ||
| 24 | 25 | ||
| 25 | /** | 26 | /** |
| 26 | * irq_handler_entry - called immediately before the irq action handler | 27 | * irq_handler_entry - called immediately before the irq action handler |
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 0a8ec5b2e208..ae5c9ea68662 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
| @@ -100,6 +100,7 @@ static char rcu_kthreads_spawnable; | |||
| 100 | 100 | ||
| 101 | static void rcu_node_kthread_setaffinity(struct rcu_node *rnp, int outgoingcpu); | 101 | static void rcu_node_kthread_setaffinity(struct rcu_node *rnp, int outgoingcpu); |
| 102 | static void invoke_rcu_cpu_kthread(void); | 102 | static void invoke_rcu_cpu_kthread(void); |
| 103 | static void __invoke_rcu_cpu_kthread(void); | ||
| 103 | 104 | ||
| 104 | #define RCU_KTHREAD_PRIO 1 /* RT priority for per-CPU kthreads. */ | 105 | #define RCU_KTHREAD_PRIO 1 /* RT priority for per-CPU kthreads. */ |
| 105 | 106 | ||
| @@ -1442,13 +1443,21 @@ __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp) | |||
| 1442 | } | 1443 | } |
| 1443 | 1444 | ||
| 1444 | /* If there are callbacks ready, invoke them. */ | 1445 | /* If there are callbacks ready, invoke them. */ |
| 1445 | rcu_do_batch(rsp, rdp); | 1446 | if (cpu_has_callbacks_ready_to_invoke(rdp)) |
| 1447 | __invoke_rcu_cpu_kthread(); | ||
| 1448 | } | ||
| 1449 | |||
| 1450 | static void rcu_kthread_do_work(void) | ||
| 1451 | { | ||
| 1452 | rcu_do_batch(&rcu_sched_state, &__get_cpu_var(rcu_sched_data)); | ||
| 1453 | rcu_do_batch(&rcu_bh_state, &__get_cpu_var(rcu_bh_data)); | ||
| 1454 | rcu_preempt_do_callbacks(); | ||
| 1446 | } | 1455 | } |
| 1447 | 1456 | ||
| 1448 | /* | 1457 | /* |
| 1449 | * Do softirq processing for the current CPU. | 1458 | * Do softirq processing for the current CPU. |
| 1450 | */ | 1459 | */ |
| 1451 | static void rcu_process_callbacks(void) | 1460 | static void rcu_process_callbacks(struct softirq_action *unused) |
| 1452 | { | 1461 | { |
| 1453 | __rcu_process_callbacks(&rcu_sched_state, | 1462 | __rcu_process_callbacks(&rcu_sched_state, |
| 1454 | &__get_cpu_var(rcu_sched_data)); | 1463 | &__get_cpu_var(rcu_sched_data)); |
| @@ -1465,7 +1474,7 @@ static void rcu_process_callbacks(void) | |||
| 1465 | * the current CPU with interrupts disabled, the rcu_cpu_kthread_task | 1474 | * the current CPU with interrupts disabled, the rcu_cpu_kthread_task |
| 1466 | * cannot disappear out from under us. | 1475 | * cannot disappear out from under us. |
| 1467 | */ | 1476 | */ |
| 1468 | static void invoke_rcu_cpu_kthread(void) | 1477 | static void __invoke_rcu_cpu_kthread(void) |
| 1469 | { | 1478 | { |
| 1470 | unsigned long flags; | 1479 | unsigned long flags; |
| 1471 | 1480 | ||
| @@ -1479,6 +1488,11 @@ static void invoke_rcu_cpu_kthread(void) | |||
| 1479 | local_irq_restore(flags); | 1488 | local_irq_restore(flags); |
| 1480 | } | 1489 | } |
| 1481 | 1490 | ||
| 1491 | static void invoke_rcu_cpu_kthread(void) | ||
| 1492 | { | ||
| 1493 | raise_softirq(RCU_SOFTIRQ); | ||
| 1494 | } | ||
| 1495 | |||
| 1482 | /* | 1496 | /* |
| 1483 | * Wake up the specified per-rcu_node-structure kthread. | 1497 | * Wake up the specified per-rcu_node-structure kthread. |
| 1484 | * Because the per-rcu_node kthreads are immortal, we don't need | 1498 | * Because the per-rcu_node kthreads are immortal, we don't need |
| @@ -1613,7 +1627,7 @@ static int rcu_cpu_kthread(void *arg) | |||
| 1613 | *workp = 0; | 1627 | *workp = 0; |
| 1614 | local_irq_restore(flags); | 1628 | local_irq_restore(flags); |
| 1615 | if (work) | 1629 | if (work) |
| 1616 | rcu_process_callbacks(); | 1630 | rcu_kthread_do_work(); |
| 1617 | local_bh_enable(); | 1631 | local_bh_enable(); |
| 1618 | if (*workp != 0) | 1632 | if (*workp != 0) |
| 1619 | spincnt++; | 1633 | spincnt++; |
| @@ -2387,6 +2401,7 @@ void __init rcu_init(void) | |||
| 2387 | rcu_init_one(&rcu_sched_state, &rcu_sched_data); | 2401 | rcu_init_one(&rcu_sched_state, &rcu_sched_data); |
| 2388 | rcu_init_one(&rcu_bh_state, &rcu_bh_data); | 2402 | rcu_init_one(&rcu_bh_state, &rcu_bh_data); |
| 2389 | __rcu_init_preempt(); | 2403 | __rcu_init_preempt(); |
| 2404 | open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); | ||
| 2390 | 2405 | ||
| 2391 | /* | 2406 | /* |
| 2392 | * We don't need protection against CPU-hotplug here because | 2407 | * We don't need protection against CPU-hotplug here because |
diff --git a/kernel/rcutree.h b/kernel/rcutree.h index 7b9a08b4aaea..0fed6b934d2a 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h | |||
| @@ -439,6 +439,7 @@ static void rcu_preempt_offline_cpu(int cpu); | |||
| 439 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | 439 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ |
| 440 | static void rcu_preempt_check_callbacks(int cpu); | 440 | static void rcu_preempt_check_callbacks(int cpu); |
| 441 | static void rcu_preempt_process_callbacks(void); | 441 | static void rcu_preempt_process_callbacks(void); |
| 442 | static void rcu_preempt_do_callbacks(void); | ||
| 442 | void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); | 443 | void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); |
| 443 | #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) | 444 | #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) |
| 444 | static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp); | 445 | static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp); |
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index ea2e2fb79e81..38d09c5f2b41 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h | |||
| @@ -602,6 +602,11 @@ static void rcu_preempt_process_callbacks(void) | |||
| 602 | &__get_cpu_var(rcu_preempt_data)); | 602 | &__get_cpu_var(rcu_preempt_data)); |
| 603 | } | 603 | } |
| 604 | 604 | ||
| 605 | static void rcu_preempt_do_callbacks(void) | ||
| 606 | { | ||
| 607 | rcu_do_batch(&rcu_preempt_state, &__get_cpu_var(rcu_preempt_data)); | ||
| 608 | } | ||
| 609 | |||
| 605 | /* | 610 | /* |
| 606 | * Queue a preemptible-RCU callback for invocation after a grace period. | 611 | * Queue a preemptible-RCU callback for invocation after a grace period. |
| 607 | */ | 612 | */ |
| @@ -997,6 +1002,10 @@ static void rcu_preempt_process_callbacks(void) | |||
| 997 | { | 1002 | { |
| 998 | } | 1003 | } |
| 999 | 1004 | ||
| 1005 | static void rcu_preempt_do_callbacks(void) | ||
| 1006 | { | ||
| 1007 | } | ||
| 1008 | |||
| 1000 | /* | 1009 | /* |
| 1001 | * Wait for an rcu-preempt grace period, but make it happen quickly. | 1010 | * Wait for an rcu-preempt grace period, but make it happen quickly. |
| 1002 | * But because preemptible RCU does not exist, map to rcu-sched. | 1011 | * But because preemptible RCU does not exist, map to rcu-sched. |
diff --git a/kernel/softirq.c b/kernel/softirq.c index 13960170cad4..40cf63ddd4b3 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
| @@ -58,7 +58,7 @@ DEFINE_PER_CPU(struct task_struct *, ksoftirqd); | |||
| 58 | 58 | ||
| 59 | char *softirq_to_name[NR_SOFTIRQS] = { | 59 | char *softirq_to_name[NR_SOFTIRQS] = { |
| 60 | "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL", | 60 | "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL", |
| 61 | "TASKLET", "SCHED", "HRTIMER" | 61 | "TASKLET", "SCHED", "HRTIMER", "RCU" |
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | /* | 64 | /* |
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index 1e88485c16a0..0a7ed5b5e281 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c | |||
| @@ -2187,6 +2187,7 @@ static const struct flag flags[] = { | |||
| 2187 | { "TASKLET_SOFTIRQ", 6 }, | 2187 | { "TASKLET_SOFTIRQ", 6 }, |
| 2188 | { "SCHED_SOFTIRQ", 7 }, | 2188 | { "SCHED_SOFTIRQ", 7 }, |
| 2189 | { "HRTIMER_SOFTIRQ", 8 }, | 2189 | { "HRTIMER_SOFTIRQ", 8 }, |
| 2190 | { "RCU_SOFTIRQ", 9 }, | ||
| 2190 | 2191 | ||
| 2191 | { "HRTIMER_NORESTART", 0 }, | 2192 | { "HRTIMER_NORESTART", 0 }, |
| 2192 | { "HRTIMER_RESTART", 1 }, | 2193 | { "HRTIMER_RESTART", 1 }, |
