Commit 433cdddc authored by Paul E. McKenney's avatar Paul E. McKenney Committed by Paul E. McKenney
Browse files

rcu: Add tracing for RCU_FAST_NO_HZ



This commit adds trace_rcu_prep_idle(), which is invoked from
rcu_prepare_for_idle() and rcu_wake_cpu() to trace attempts on
the part of RCU to force CPUs into dyntick-idle mode.

Signed-off-by: default avatarPaul E. McKenney <paul.mckenney@linaro.org>
Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
parent 045fb931
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -274,6 +274,42 @@ TRACE_EVENT(rcu_dyntick,
		  __entry->oldnesting, __entry->newnesting)
);

/*
 * Tracepoint for RCU preparation for idle, the goal being to get RCU
 * processing done so that the current CPU can shut off its scheduling
 * clock and enter dyntick-idle mode.  One way to accomplish this is
 * to drain all RCU callbacks from this CPU, and the other is to have
 * done everything RCU requires for the current grace period.  In this
 * latter case, the CPU will be awakened at the end of the current grace
 * period in order to process the remainder of its callbacks.
 *
 * These tracepoints take a string as argument:
 *
 *	"No callbacks": Nothing to do, no callbacks on this CPU.
 *	"In holdoff": Nothing to do, holding off after unsuccessful attempt.
 *	"Dyntick with callbacks": Callbacks remain, but RCU doesn't need CPU.
 *	"Begin holdoff": Attempt failed, don't retry until next jiffy.
 *	"More callbacks": Still more callbacks, try again to clear them out.
 *	"Callbacks drained": All callbacks processed, off to dyntick idle!
 *	"CPU awakened at GP end":
 */
TRACE_EVENT(rcu_prep_idle,

	TP_PROTO(char *reason),

	TP_ARGS(reason),

	TP_STRUCT__entry(
		__field(char *, reason)
	),

	TP_fast_assign(
		__entry->reason = reason;
	),

	TP_printk("%s", __entry->reason)
);

/*
 * Tracepoint for the registration of a single RCU callback function.
 * The first argument is the type of RCU, the second argument is
@@ -482,6 +518,7 @@ TRACE_EVENT(rcu_torture_read,
#define trace_rcu_quiescent_state_report(rcuname, gpnum, mask, qsmask, level, grplo, grphi, gp_tasks) do { } while (0)
#define trace_rcu_fqs(rcuname, gpnum, cpu, qsevent) do { } while (0)
#define trace_rcu_dyntick(polarity, oldnesting, newnesting) do { } while (0)
#define trace_rcu_prep_idle(reason) do { } while (0)
#define trace_rcu_callback(rcuname, rhp, qlen) do { } while (0)
#define trace_rcu_kfree_callback(rcuname, rhp, offset, qlen) do { } while (0)
#define trace_rcu_batch_start(rcuname, qlen, blimit) do { } while (0)
+15 −3
Original line number Diff line number Diff line
@@ -2031,10 +2031,13 @@ static void rcu_prepare_for_idle(int cpu)
	/* If no callbacks or in the holdoff period, enter dyntick-idle. */
	if (!rcu_cpu_has_callbacks(cpu)) {
		per_cpu(rcu_dyntick_holdoff, cpu) = jiffies - 1;
		trace_rcu_prep_idle("No callbacks");
		return;
	}
	if (per_cpu(rcu_dyntick_holdoff, cpu) == jiffies)
	if (per_cpu(rcu_dyntick_holdoff, cpu) == jiffies) {
		trace_rcu_prep_idle("In holdoff");
		return;
	}

	/* Check and update the rcu_dyntick_drain sequencing. */
	if (per_cpu(rcu_dyntick_drain, cpu) <= 0) {
@@ -2044,9 +2047,11 @@ static void rcu_prepare_for_idle(int cpu)
		/* We have hit the limit, so time to give up. */
		per_cpu(rcu_dyntick_holdoff, cpu) = jiffies;
		if (!rcu_pending(cpu)) {
			trace_rcu_prep_idle("Dyntick with callbacks");
			per_cpu(rcu_awake_at_gp_end, cpu) = 1;
			return;  /* Nothing to do immediately. */
		}
		trace_rcu_prep_idle("Begin holdoff");
		invoke_rcu_core();  /* Force the CPU out of dyntick-idle. */
		return;
	}
@@ -2073,9 +2078,15 @@ static void rcu_prepare_for_idle(int cpu)
		c = c || per_cpu(rcu_bh_data, cpu).nxtlist;
	}

	/* If RCU callbacks are still pending, RCU still needs this CPU. */
	if (c)
	/*
	 * If RCU callbacks are still pending, RCU still needs this CPU.
	 * So try forcing the callbacks through the grace period.
	 */
	if (c) {
		trace_rcu_prep_idle("More callbacks");
		invoke_rcu_core();
	} else
		trace_rcu_prep_idle("Callbacks drained");
}

/*
@@ -2085,6 +2096,7 @@ static void rcu_prepare_for_idle(int cpu)
 */
static void rcu_wake_cpu(void *unused)
{
	trace_rcu_prep_idle("CPU awakened at GP end");
	invoke_rcu_core();
}