diff options
-rw-r--r-- | include/trace/events/rcu.h | 38 | ||||
-rw-r--r-- | kernel/rcutiny.c | 10 | ||||
-rw-r--r-- | kernel/rcutiny_plugin.h | 25 | ||||
-rw-r--r-- | kernel/rcutree.c | 8 |
4 files changed, 68 insertions, 13 deletions
diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h index c75418c3ccb8..d2d88bed891b 100644 --- a/include/trace/events/rcu.h +++ b/include/trace/events/rcu.h | |||
@@ -461,27 +461,46 @@ TRACE_EVENT(rcu_invoke_kfree_callback, | |||
461 | 461 | ||
462 | /* | 462 | /* |
463 | * Tracepoint for exiting rcu_do_batch after RCU callbacks have been | 463 | * Tracepoint for exiting rcu_do_batch after RCU callbacks have been |
464 | * invoked. The first argument is the name of the RCU flavor and | 464 | * invoked. The first argument is the name of the RCU flavor, |
465 | * the second argument is number of callbacks actually invoked. | 465 | * the second argument is number of callbacks actually invoked, |
466 | * the third argument (cb) is whether or not any of the callbacks that | ||
467 | * were ready to invoke at the beginning of this batch are still | ||
468 | * queued, the fourth argument (nr) is the return value of need_resched(), | ||
469 | * the fifth argument (iit) is 1 if the current task is the idle task, | ||
470 | * and the sixth argument (risk) is the return value from | ||
471 | * rcu_is_callbacks_kthread(). | ||
466 | */ | 472 | */ |
467 | TRACE_EVENT(rcu_batch_end, | 473 | TRACE_EVENT(rcu_batch_end, |
468 | 474 | ||
469 | TP_PROTO(char *rcuname, int callbacks_invoked), | 475 | TP_PROTO(char *rcuname, int callbacks_invoked, |
476 | bool cb, bool nr, bool iit, bool risk), | ||
470 | 477 | ||
471 | TP_ARGS(rcuname, callbacks_invoked), | 478 | TP_ARGS(rcuname, callbacks_invoked, cb, nr, iit, risk), |
472 | 479 | ||
473 | TP_STRUCT__entry( | 480 | TP_STRUCT__entry( |
474 | __field(char *, rcuname) | 481 | __field(char *, rcuname) |
475 | __field(int, callbacks_invoked) | 482 | __field(int, callbacks_invoked) |
483 | __field(bool, cb) | ||
484 | __field(bool, nr) | ||
485 | __field(bool, iit) | ||
486 | __field(bool, risk) | ||
476 | ), | 487 | ), |
477 | 488 | ||
478 | TP_fast_assign( | 489 | TP_fast_assign( |
479 | __entry->rcuname = rcuname; | 490 | __entry->rcuname = rcuname; |
480 | __entry->callbacks_invoked = callbacks_invoked; | 491 | __entry->callbacks_invoked = callbacks_invoked; |
481 | ), | 492 | __entry->cb = cb; |
482 | 493 | __entry->nr = nr; | |
483 | TP_printk("%s CBs-invoked=%d", | 494 | __entry->iit = iit; |
484 | __entry->rcuname, __entry->callbacks_invoked) | 495 | __entry->risk = risk; |
496 | ), | ||
497 | |||
498 | TP_printk("%s CBs-invoked=%d idle=%c%c%c%c", | ||
499 | __entry->rcuname, __entry->callbacks_invoked, | ||
500 | __entry->cb ? 'C' : '.', | ||
501 | __entry->nr ? 'S' : '.', | ||
502 | __entry->iit ? 'I' : '.', | ||
503 | __entry->risk ? 'R' : '.') | ||
485 | ); | 504 | ); |
486 | 505 | ||
487 | /* | 506 | /* |
@@ -524,7 +543,8 @@ TRACE_EVENT(rcu_torture_read, | |||
524 | #define trace_rcu_batch_start(rcuname, qlen, blimit) do { } while (0) | 543 | #define trace_rcu_batch_start(rcuname, qlen, blimit) do { } while (0) |
525 | #define trace_rcu_invoke_callback(rcuname, rhp) do { } while (0) | 544 | #define trace_rcu_invoke_callback(rcuname, rhp) do { } while (0) |
526 | #define trace_rcu_invoke_kfree_callback(rcuname, rhp, offset) do { } while (0) | 545 | #define trace_rcu_invoke_kfree_callback(rcuname, rhp, offset) do { } while (0) |
527 | #define trace_rcu_batch_end(rcuname, callbacks_invoked) do { } while (0) | 546 | #define trace_rcu_batch_end(rcuname, callbacks_invoked, cb, nr, iit, risk) \ |
547 | do { } while (0) | ||
528 | #define trace_rcu_torture_read(rcutorturename, rhp) do { } while (0) | 548 | #define trace_rcu_torture_read(rcutorturename, rhp) do { } while (0) |
529 | 549 | ||
530 | #endif /* #else #ifdef CONFIG_RCU_TRACE */ | 550 | #endif /* #else #ifdef CONFIG_RCU_TRACE */ |
diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c index e5bd94954fa3..977296dca0a4 100644 --- a/kernel/rcutiny.c +++ b/kernel/rcutiny.c | |||
@@ -259,7 +259,11 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp) | |||
259 | /* If no RCU callbacks ready to invoke, just return. */ | 259 | /* If no RCU callbacks ready to invoke, just return. */ |
260 | if (&rcp->rcucblist == rcp->donetail) { | 260 | if (&rcp->rcucblist == rcp->donetail) { |
261 | RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, -1)); | 261 | RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, -1)); |
262 | RCU_TRACE(trace_rcu_batch_end(rcp->name, 0)); | 262 | RCU_TRACE(trace_rcu_batch_end(rcp->name, 0, |
263 | ACCESS_ONCE(rcp->rcucblist), | ||
264 | need_resched(), | ||
265 | is_idle_task(current), | ||
266 | rcu_is_callbacks_kthread())); | ||
263 | return; | 267 | return; |
264 | } | 268 | } |
265 | 269 | ||
@@ -288,7 +292,9 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp) | |||
288 | RCU_TRACE(cb_count++); | 292 | RCU_TRACE(cb_count++); |
289 | } | 293 | } |
290 | RCU_TRACE(rcu_trace_sub_qlen(rcp, cb_count)); | 294 | RCU_TRACE(rcu_trace_sub_qlen(rcp, cb_count)); |
291 | RCU_TRACE(trace_rcu_batch_end(rcp->name, cb_count)); | 295 | RCU_TRACE(trace_rcu_batch_end(rcp->name, cb_count, 0, need_resched(), |
296 | is_idle_task(current), | ||
297 | rcu_is_callbacks_kthread())); | ||
292 | } | 298 | } |
293 | 299 | ||
294 | static void rcu_process_callbacks(struct softirq_action *unused) | 300 | static void rcu_process_callbacks(struct softirq_action *unused) |
diff --git a/kernel/rcutiny_plugin.h b/kernel/rcutiny_plugin.h index 2b0484a5dc28..dfa97cbb3910 100644 --- a/kernel/rcutiny_plugin.h +++ b/kernel/rcutiny_plugin.h | |||
@@ -885,6 +885,19 @@ static void invoke_rcu_callbacks(void) | |||
885 | wake_up(&rcu_kthread_wq); | 885 | wake_up(&rcu_kthread_wq); |
886 | } | 886 | } |
887 | 887 | ||
888 | #ifdef CONFIG_RCU_TRACE | ||
889 | |||
890 | /* | ||
891 | * Is the current CPU running the RCU-callbacks kthread? | ||
892 | * Caller must have preemption disabled. | ||
893 | */ | ||
894 | static bool rcu_is_callbacks_kthread(void) | ||
895 | { | ||
896 | return rcu_kthread_task == current; | ||
897 | } | ||
898 | |||
899 | #endif /* #ifdef CONFIG_RCU_TRACE */ | ||
900 | |||
888 | /* | 901 | /* |
889 | * This kthread invokes RCU callbacks whose grace periods have | 902 | * This kthread invokes RCU callbacks whose grace periods have |
890 | * elapsed. It is awakened as needed, and takes the place of the | 903 | * elapsed. It is awakened as needed, and takes the place of the |
@@ -938,6 +951,18 @@ void invoke_rcu_callbacks(void) | |||
938 | raise_softirq(RCU_SOFTIRQ); | 951 | raise_softirq(RCU_SOFTIRQ); |
939 | } | 952 | } |
940 | 953 | ||
954 | #ifdef CONFIG_RCU_TRACE | ||
955 | |||
956 | /* | ||
957 | * There is no callback kthread, so this thread is never it. | ||
958 | */ | ||
959 | static bool rcu_is_callbacks_kthread(void) | ||
960 | { | ||
961 | return false; | ||
962 | } | ||
963 | |||
964 | #endif /* #ifdef CONFIG_RCU_TRACE */ | ||
965 | |||
941 | void rcu_init(void) | 966 | void rcu_init(void) |
942 | { | 967 | { |
943 | open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); | 968 | open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); |
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 2b2e1a996a65..6c4a6722abfd 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -1373,7 +1373,9 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp) | |||
1373 | /* If no callbacks are ready, just return.*/ | 1373 | /* If no callbacks are ready, just return.*/ |
1374 | if (!cpu_has_callbacks_ready_to_invoke(rdp)) { | 1374 | if (!cpu_has_callbacks_ready_to_invoke(rdp)) { |
1375 | trace_rcu_batch_start(rsp->name, 0, 0); | 1375 | trace_rcu_batch_start(rsp->name, 0, 0); |
1376 | trace_rcu_batch_end(rsp->name, 0); | 1376 | trace_rcu_batch_end(rsp->name, 0, !!ACCESS_ONCE(rdp->nxtlist), |
1377 | need_resched(), is_idle_task(current), | ||
1378 | rcu_is_callbacks_kthread()); | ||
1377 | return; | 1379 | return; |
1378 | } | 1380 | } |
1379 | 1381 | ||
@@ -1409,7 +1411,9 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp) | |||
1409 | } | 1411 | } |
1410 | 1412 | ||
1411 | local_irq_save(flags); | 1413 | local_irq_save(flags); |
1412 | trace_rcu_batch_end(rsp->name, count); | 1414 | trace_rcu_batch_end(rsp->name, count, !!list, need_resched(), |
1415 | is_idle_task(current), | ||
1416 | rcu_is_callbacks_kthread()); | ||
1413 | 1417 | ||
1414 | /* Update count, and requeue any remaining callbacks. */ | 1418 | /* Update count, and requeue any remaining callbacks. */ |
1415 | rdp->qlen -= count; | 1419 | rdp->qlen -= count; |