aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2013-10-15 15:47:04 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2013-10-15 15:47:04 -0400
commit25e03a74e4a14e0d52a66fb56c728f049a6a26d3 (patch)
tree7302bd505a14a05e0ad1f9c595259a54e6bff66f
parent460aebac739df78b0e40a347934fdea377310577 (diff)
parent15f5191b6acbbb38029b06284e8fd20275e7cfe8 (diff)
Merge branch 'gp.2013.09.25a' into HEAD
gp.2013.09.25a: Topic branch for grace-period updates.
-rw-r--r--include/trace/events/rcu.h80
-rw-r--r--kernel/rcutiny.c2
-rw-r--r--kernel/rcutree.c56
-rw-r--r--kernel/rcutree_plugin.h35
4 files changed, 144 insertions, 29 deletions
diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h
index ee2376cfaab3..aca382266411 100644
--- a/include/trace/events/rcu.h
+++ b/include/trace/events/rcu.h
@@ -39,15 +39,26 @@ TRACE_EVENT(rcu_utilization,
39#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) 39#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
40 40
41/* 41/*
42 * Tracepoint for grace-period events: starting and ending a grace 42 * Tracepoint for grace-period events. Takes a string identifying the
43 * period ("start" and "end", respectively), a CPU noting the start 43 * RCU flavor, the grace-period number, and a string identifying the
44 * of a new grace period or the end of an old grace period ("cpustart" 44 * grace-period-related event as follows:
45 * and "cpuend", respectively), a CPU passing through a quiescent 45 *
46 * state ("cpuqs"), a CPU coming online or going offline ("cpuonl" 46 * "AccReadyCB": CPU acclerates new callbacks to RCU_NEXT_READY_TAIL.
47 * and "cpuofl", respectively), a CPU being kicked for being too 47 * "AccWaitCB": CPU accelerates new callbacks to RCU_WAIT_TAIL.
48 * long in dyntick-idle mode ("kick"), a CPU accelerating its new 48 * "newreq": Request a new grace period.
49 * callbacks to RCU_NEXT_READY_TAIL ("AccReadyCB"), and a CPU 49 * "start": Start a grace period.
50 * accelerating its new callbacks to RCU_WAIT_TAIL ("AccWaitCB"). 50 * "cpustart": CPU first notices a grace-period start.
51 * "cpuqs": CPU passes through a quiescent state.
52 * "cpuonl": CPU comes online.
53 * "cpuofl": CPU goes offline.
54 * "reqwait": GP kthread sleeps waiting for grace-period request.
55 * "reqwaitsig": GP kthread awakened by signal from reqwait state.
56 * "fqswait": GP kthread waiting until time to force quiescent states.
57 * "fqsstart": GP kthread starts forcing quiescent states.
58 * "fqsend": GP kthread done forcing quiescent states.
59 * "fqswaitsig": GP kthread awakened by signal from fqswait state.
60 * "end": End a grace period.
61 * "cpuend": CPU first notices a grace-period end.
51 */ 62 */
52TRACE_EVENT(rcu_grace_period, 63TRACE_EVENT(rcu_grace_period,
53 64
@@ -161,6 +172,46 @@ TRACE_EVENT(rcu_grace_period_init,
161); 172);
162 173
163/* 174/*
175 * Tracepoint for RCU no-CBs CPU callback handoffs. This event is intended
176 * to assist debugging of these handoffs.
177 *
178 * The first argument is the name of the RCU flavor, and the second is
179 * the number of the offloaded CPU are extracted. The third and final
180 * argument is a string as follows:
181 *
182 * "WakeEmpty": Wake rcuo kthread, first CB to empty list.
183 * "WakeOvf": Wake rcuo kthread, CB list is huge.
184 * "WakeNot": Don't wake rcuo kthread.
185 * "WakeNotPoll": Don't wake rcuo kthread because it is polling.
186 * "Poll": Start of new polling cycle for rcu_nocb_poll.
187 * "Sleep": Sleep waiting for CBs for !rcu_nocb_poll.
188 * "WokeEmpty": rcuo kthread woke to find empty list.
189 * "WokeNonEmpty": rcuo kthread woke to find non-empty list.
190 * "WaitQueue": Enqueue partially done, timed wait for it to complete.
191 * "WokeQueue": Partial enqueue now complete.
192 */
193TRACE_EVENT(rcu_nocb_wake,
194
195 TP_PROTO(const char *rcuname, int cpu, const char *reason),
196
197 TP_ARGS(rcuname, cpu, reason),
198
199 TP_STRUCT__entry(
200 __field(const char *, rcuname)
201 __field(int, cpu)
202 __field(const char *, reason)
203 ),
204
205 TP_fast_assign(
206 __entry->rcuname = rcuname;
207 __entry->cpu = cpu;
208 __entry->reason = reason;
209 ),
210
211 TP_printk("%s %d %s", __entry->rcuname, __entry->cpu, __entry->reason)
212);
213
214/*
164 * Tracepoint for tasks blocking within preemptible-RCU read-side 215 * Tracepoint for tasks blocking within preemptible-RCU read-side
165 * critical sections. Track the type of RCU (which one day might 216 * critical sections. Track the type of RCU (which one day might
166 * include SRCU), the grace-period number that the task is blocking 217 * include SRCU), the grace-period number that the task is blocking
@@ -540,17 +591,17 @@ TRACE_EVENT(rcu_invoke_kfree_callback,
540TRACE_EVENT(rcu_batch_end, 591TRACE_EVENT(rcu_batch_end,
541 592
542 TP_PROTO(const char *rcuname, int callbacks_invoked, 593 TP_PROTO(const char *rcuname, int callbacks_invoked,
543 bool cb, bool nr, bool iit, bool risk), 594 char cb, char nr, char iit, char risk),
544 595
545 TP_ARGS(rcuname, callbacks_invoked, cb, nr, iit, risk), 596 TP_ARGS(rcuname, callbacks_invoked, cb, nr, iit, risk),
546 597
547 TP_STRUCT__entry( 598 TP_STRUCT__entry(
548 __field(const char *, rcuname) 599 __field(const char *, rcuname)
549 __field(int, callbacks_invoked) 600 __field(int, callbacks_invoked)
550 __field(bool, cb) 601 __field(char, cb)
551 __field(bool, nr) 602 __field(char, nr)
552 __field(bool, iit) 603 __field(char, iit)
553 __field(bool, risk) 604 __field(char, risk)
554 ), 605 ),
555 606
556 TP_fast_assign( 607 TP_fast_assign(
@@ -656,6 +707,7 @@ TRACE_EVENT(rcu_barrier,
656#define trace_rcu_future_grace_period(rcuname, gpnum, completed, c, \ 707#define trace_rcu_future_grace_period(rcuname, gpnum, completed, c, \
657 level, grplo, grphi, event) \ 708 level, grplo, grphi, event) \
658 do { } while (0) 709 do { } while (0)
710#define trace_rcu_nocb_wake(rcuname, cpu, reason) do { } while (0)
659#define trace_rcu_preempt_task(rcuname, pid, gpnum) do { } while (0) 711#define trace_rcu_preempt_task(rcuname, pid, gpnum) do { } while (0)
660#define trace_rcu_unlock_preempted_task(rcuname, gpnum, pid) do { } while (0) 712#define trace_rcu_unlock_preempted_task(rcuname, gpnum, pid) do { } while (0)
661#define trace_rcu_quiescent_state_report(rcuname, gpnum, mask, qsmask, level, \ 713#define trace_rcu_quiescent_state_report(rcuname, gpnum, mask, qsmask, level, \
diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c
index e99eb5fb10af..7e3b0d6fc6e2 100644
--- a/kernel/rcutiny.c
+++ b/kernel/rcutiny.c
@@ -275,7 +275,7 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
275 if (&rcp->rcucblist == rcp->donetail) { 275 if (&rcp->rcucblist == rcp->donetail) {
276 RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, 0, -1)); 276 RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, 0, -1));
277 RCU_TRACE(trace_rcu_batch_end(rcp->name, 0, 277 RCU_TRACE(trace_rcu_batch_end(rcp->name, 0,
278 ACCESS_ONCE(rcp->rcucblist), 278 !!ACCESS_ONCE(rcp->rcucblist),
279 need_resched(), 279 need_resched(),
280 is_idle_task(current), 280 is_idle_task(current),
281 false)); 281 false));
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 62aab5ceefe9..a06d172c75e0 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -1326,7 +1326,7 @@ static void note_gp_changes(struct rcu_state *rsp, struct rcu_data *rdp)
1326} 1326}
1327 1327
1328/* 1328/*
1329 * Initialize a new grace period. 1329 * Initialize a new grace period. Return 0 if no grace period required.
1330 */ 1330 */
1331static int rcu_gp_init(struct rcu_state *rsp) 1331static int rcu_gp_init(struct rcu_state *rsp)
1332{ 1332{
@@ -1335,10 +1335,18 @@ static int rcu_gp_init(struct rcu_state *rsp)
1335 1335
1336 rcu_bind_gp_kthread(); 1336 rcu_bind_gp_kthread();
1337 raw_spin_lock_irq(&rnp->lock); 1337 raw_spin_lock_irq(&rnp->lock);
1338 if (rsp->gp_flags == 0) {
1339 /* Spurious wakeup, tell caller to go back to sleep. */
1340 raw_spin_unlock_irq(&rnp->lock);
1341 return 0;
1342 }
1338 rsp->gp_flags = 0; /* Clear all flags: New grace period. */ 1343 rsp->gp_flags = 0; /* Clear all flags: New grace period. */
1339 1344
1340 if (rcu_gp_in_progress(rsp)) { 1345 if (WARN_ON_ONCE(rcu_gp_in_progress(rsp))) {
1341 /* Grace period already in progress, don't start another. */ 1346 /*
1347 * Grace period already in progress, don't start another.
1348 * Not supposed to be able to happen.
1349 */
1342 raw_spin_unlock_irq(&rnp->lock); 1350 raw_spin_unlock_irq(&rnp->lock);
1343 return 0; 1351 return 0;
1344 } 1352 }
@@ -1481,8 +1489,12 @@ static void rcu_gp_cleanup(struct rcu_state *rsp)
1481 rsp->fqs_state = RCU_GP_IDLE; 1489 rsp->fqs_state = RCU_GP_IDLE;
1482 rdp = this_cpu_ptr(rsp->rda); 1490 rdp = this_cpu_ptr(rsp->rda);
1483 rcu_advance_cbs(rsp, rnp, rdp); /* Reduce false positives below. */ 1491 rcu_advance_cbs(rsp, rnp, rdp); /* Reduce false positives below. */
1484 if (cpu_needs_another_gp(rsp, rdp)) 1492 if (cpu_needs_another_gp(rsp, rdp)) {
1485 rsp->gp_flags = RCU_GP_FLAG_INIT; 1493 rsp->gp_flags = RCU_GP_FLAG_INIT;
1494 trace_rcu_grace_period(rsp->name,
1495 ACCESS_ONCE(rsp->gpnum),
1496 TPS("newreq"));
1497 }
1486 raw_spin_unlock_irq(&rnp->lock); 1498 raw_spin_unlock_irq(&rnp->lock);
1487} 1499}
1488 1500
@@ -1492,6 +1504,7 @@ static void rcu_gp_cleanup(struct rcu_state *rsp)
1492static int __noreturn rcu_gp_kthread(void *arg) 1504static int __noreturn rcu_gp_kthread(void *arg)
1493{ 1505{
1494 int fqs_state; 1506 int fqs_state;
1507 int gf;
1495 unsigned long j; 1508 unsigned long j;
1496 int ret; 1509 int ret;
1497 struct rcu_state *rsp = arg; 1510 struct rcu_state *rsp = arg;
@@ -1501,14 +1514,19 @@ static int __noreturn rcu_gp_kthread(void *arg)
1501 1514
1502 /* Handle grace-period start. */ 1515 /* Handle grace-period start. */
1503 for (;;) { 1516 for (;;) {
1517 trace_rcu_grace_period(rsp->name,
1518 ACCESS_ONCE(rsp->gpnum),
1519 TPS("reqwait"));
1504 wait_event_interruptible(rsp->gp_wq, 1520 wait_event_interruptible(rsp->gp_wq,
1505 rsp->gp_flags & 1521 ACCESS_ONCE(rsp->gp_flags) &
1506 RCU_GP_FLAG_INIT); 1522 RCU_GP_FLAG_INIT);
1507 if ((rsp->gp_flags & RCU_GP_FLAG_INIT) && 1523 if (rcu_gp_init(rsp))
1508 rcu_gp_init(rsp))
1509 break; 1524 break;
1510 cond_resched(); 1525 cond_resched();
1511 flush_signals(current); 1526 flush_signals(current);
1527 trace_rcu_grace_period(rsp->name,
1528 ACCESS_ONCE(rsp->gpnum),
1529 TPS("reqwaitsig"));
1512 } 1530 }
1513 1531
1514 /* Handle quiescent-state forcing. */ 1532 /* Handle quiescent-state forcing. */
@@ -1518,10 +1536,16 @@ static int __noreturn rcu_gp_kthread(void *arg)
1518 j = HZ; 1536 j = HZ;
1519 jiffies_till_first_fqs = HZ; 1537 jiffies_till_first_fqs = HZ;
1520 } 1538 }
1539 ret = 0;
1521 for (;;) { 1540 for (;;) {
1522 rsp->jiffies_force_qs = jiffies + j; 1541 if (!ret)
1542 rsp->jiffies_force_qs = jiffies + j;
1543 trace_rcu_grace_period(rsp->name,
1544 ACCESS_ONCE(rsp->gpnum),
1545 TPS("fqswait"));
1523 ret = wait_event_interruptible_timeout(rsp->gp_wq, 1546 ret = wait_event_interruptible_timeout(rsp->gp_wq,
1524 (rsp->gp_flags & RCU_GP_FLAG_FQS) || 1547 ((gf = ACCESS_ONCE(rsp->gp_flags)) &
1548 RCU_GP_FLAG_FQS) ||
1525 (!ACCESS_ONCE(rnp->qsmask) && 1549 (!ACCESS_ONCE(rnp->qsmask) &&
1526 !rcu_preempt_blocked_readers_cgp(rnp)), 1550 !rcu_preempt_blocked_readers_cgp(rnp)),
1527 j); 1551 j);
@@ -1530,13 +1554,23 @@ static int __noreturn rcu_gp_kthread(void *arg)
1530 !rcu_preempt_blocked_readers_cgp(rnp)) 1554 !rcu_preempt_blocked_readers_cgp(rnp))
1531 break; 1555 break;
1532 /* If time for quiescent-state forcing, do it. */ 1556 /* If time for quiescent-state forcing, do it. */
1533 if (ret == 0 || (rsp->gp_flags & RCU_GP_FLAG_FQS)) { 1557 if (ULONG_CMP_GE(jiffies, rsp->jiffies_force_qs) ||
1558 (gf & RCU_GP_FLAG_FQS)) {
1559 trace_rcu_grace_period(rsp->name,
1560 ACCESS_ONCE(rsp->gpnum),
1561 TPS("fqsstart"));
1534 fqs_state = rcu_gp_fqs(rsp, fqs_state); 1562 fqs_state = rcu_gp_fqs(rsp, fqs_state);
1563 trace_rcu_grace_period(rsp->name,
1564 ACCESS_ONCE(rsp->gpnum),
1565 TPS("fqsend"));
1535 cond_resched(); 1566 cond_resched();
1536 } else { 1567 } else {
1537 /* Deal with stray signal. */ 1568 /* Deal with stray signal. */
1538 cond_resched(); 1569 cond_resched();
1539 flush_signals(current); 1570 flush_signals(current);
1571 trace_rcu_grace_period(rsp->name,
1572 ACCESS_ONCE(rsp->gpnum),
1573 TPS("fqswaitsig"));
1540 } 1574 }
1541 j = jiffies_till_next_fqs; 1575 j = jiffies_till_next_fqs;
1542 if (j > HZ) { 1576 if (j > HZ) {
@@ -1584,6 +1618,8 @@ rcu_start_gp_advanced(struct rcu_state *rsp, struct rcu_node *rnp,
1584 return; 1618 return;
1585 } 1619 }
1586 rsp->gp_flags = RCU_GP_FLAG_INIT; 1620 rsp->gp_flags = RCU_GP_FLAG_INIT;
1621 trace_rcu_grace_period(rsp->name, ACCESS_ONCE(rsp->gpnum),
1622 TPS("newreq"));
1587 1623
1588 /* 1624 /*
1589 * We can't do wakeups while holding the rnp->lock, as that 1625 * We can't do wakeups while holding the rnp->lock, as that
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
index 1855d66bf705..cd95efa1da48 100644
--- a/kernel/rcutree_plugin.h
+++ b/kernel/rcutree_plugin.h
@@ -2113,15 +2113,22 @@ static void __call_rcu_nocb_enqueue(struct rcu_data *rdp,
2113 2113
2114 /* If we are not being polled and there is a kthread, awaken it ... */ 2114 /* If we are not being polled and there is a kthread, awaken it ... */
2115 t = ACCESS_ONCE(rdp->nocb_kthread); 2115 t = ACCESS_ONCE(rdp->nocb_kthread);
2116 if (rcu_nocb_poll || !t) 2116 if (rcu_nocb_poll || !t) {
2117 trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
2118 TPS("WakeNotPoll"));
2117 return; 2119 return;
2120 }
2118 len = atomic_long_read(&rdp->nocb_q_count); 2121 len = atomic_long_read(&rdp->nocb_q_count);
2119 if (old_rhpp == &rdp->nocb_head) { 2122 if (old_rhpp == &rdp->nocb_head) {
2120 wake_up(&rdp->nocb_wq); /* ... only if queue was empty ... */ 2123 wake_up(&rdp->nocb_wq); /* ... only if queue was empty ... */
2121 rdp->qlen_last_fqs_check = 0; 2124 rdp->qlen_last_fqs_check = 0;
2125 trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, TPS("WakeEmpty"));
2122 } else if (len > rdp->qlen_last_fqs_check + qhimark) { 2126 } else if (len > rdp->qlen_last_fqs_check + qhimark) {
2123 wake_up_process(t); /* ... or if many callbacks queued. */ 2127 wake_up_process(t); /* ... or if many callbacks queued. */
2124 rdp->qlen_last_fqs_check = LONG_MAX / 2; 2128 rdp->qlen_last_fqs_check = LONG_MAX / 2;
2129 trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, TPS("WakeOvf"));
2130 } else {
2131 trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, TPS("WakeNot"));
2125 } 2132 }
2126 return; 2133 return;
2127} 2134}
@@ -2145,10 +2152,12 @@ static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
2145 if (__is_kfree_rcu_offset((unsigned long)rhp->func)) 2152 if (__is_kfree_rcu_offset((unsigned long)rhp->func))
2146 trace_rcu_kfree_callback(rdp->rsp->name, rhp, 2153 trace_rcu_kfree_callback(rdp->rsp->name, rhp,
2147 (unsigned long)rhp->func, 2154 (unsigned long)rhp->func,
2148 rdp->qlen_lazy, rdp->qlen); 2155 -atomic_long_read(&rdp->nocb_q_count_lazy),
2156 -atomic_long_read(&rdp->nocb_q_count));
2149 else 2157 else
2150 trace_rcu_callback(rdp->rsp->name, rhp, 2158 trace_rcu_callback(rdp->rsp->name, rhp,
2151 rdp->qlen_lazy, rdp->qlen); 2159 -atomic_long_read(&rdp->nocb_q_count_lazy),
2160 -atomic_long_read(&rdp->nocb_q_count));
2152 return 1; 2161 return 1;
2153} 2162}
2154 2163
@@ -2226,6 +2235,7 @@ static void rcu_nocb_wait_gp(struct rcu_data *rdp)
2226static int rcu_nocb_kthread(void *arg) 2235static int rcu_nocb_kthread(void *arg)
2227{ 2236{
2228 int c, cl; 2237 int c, cl;
2238 bool firsttime = 1;
2229 struct rcu_head *list; 2239 struct rcu_head *list;
2230 struct rcu_head *next; 2240 struct rcu_head *next;
2231 struct rcu_head **tail; 2241 struct rcu_head **tail;
@@ -2234,14 +2244,27 @@ static int rcu_nocb_kthread(void *arg)
2234 /* Each pass through this loop invokes one batch of callbacks */ 2244 /* Each pass through this loop invokes one batch of callbacks */
2235 for (;;) { 2245 for (;;) {
2236 /* If not polling, wait for next batch of callbacks. */ 2246 /* If not polling, wait for next batch of callbacks. */
2237 if (!rcu_nocb_poll) 2247 if (!rcu_nocb_poll) {
2248 trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
2249 TPS("Sleep"));
2238 wait_event_interruptible(rdp->nocb_wq, rdp->nocb_head); 2250 wait_event_interruptible(rdp->nocb_wq, rdp->nocb_head);
2251 } else if (firsttime) {
2252 firsttime = 0;
2253 trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
2254 TPS("Poll"));
2255 }
2239 list = ACCESS_ONCE(rdp->nocb_head); 2256 list = ACCESS_ONCE(rdp->nocb_head);
2240 if (!list) { 2257 if (!list) {
2258 if (!rcu_nocb_poll)
2259 trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
2260 TPS("WokeEmpty"));
2241 schedule_timeout_interruptible(1); 2261 schedule_timeout_interruptible(1);
2242 flush_signals(current); 2262 flush_signals(current);
2243 continue; 2263 continue;
2244 } 2264 }
2265 firsttime = 1;
2266 trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
2267 TPS("WokeNonEmpty"));
2245 2268
2246 /* 2269 /*
2247 * Extract queued callbacks, update counts, and wait 2270 * Extract queued callbacks, update counts, and wait
@@ -2262,7 +2285,11 @@ static int rcu_nocb_kthread(void *arg)
2262 next = list->next; 2285 next = list->next;
2263 /* Wait for enqueuing to complete, if needed. */ 2286 /* Wait for enqueuing to complete, if needed. */
2264 while (next == NULL && &list->next != tail) { 2287 while (next == NULL && &list->next != tail) {
2288 trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
2289 TPS("WaitQueue"));
2265 schedule_timeout_interruptible(1); 2290 schedule_timeout_interruptible(1);
2291 trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu,
2292 TPS("WokeQueue"));
2266 next = list->next; 2293 next = list->next;
2267 } 2294 }
2268 debug_rcu_head_unqueue(list); 2295 debug_rcu_head_unqueue(list);