rcutorture: Record grace periods in forward-progress histogram
This commit records grace periods in rcutorture's n_launders_hist[] histogram, thus allowing rcu_torture_fwd_cb_hist() to print out the elapsed number of grace periods between buckets. This information helps to determine whether a lack of forward progress is due to stalled grace periods on the one hand or due to sluggish callback invocation on the other. Signed-off-by: Paul E. McKenney <paulmck@linux.ibm.com>
This commit is contained in:
Родитель
7a968bb26a
Коммит
cd618d102b
|
@ -1630,21 +1630,34 @@ static bool rcu_fwd_emergency_stop;
|
||||||
#define MIN_FWD_CB_LAUNDERS 3 /* This many CB invocations to count. */
|
#define MIN_FWD_CB_LAUNDERS 3 /* This many CB invocations to count. */
|
||||||
#define MIN_FWD_CBS_LAUNDERED 100 /* Number of counted CBs. */
|
#define MIN_FWD_CBS_LAUNDERED 100 /* Number of counted CBs. */
|
||||||
#define FWD_CBS_HIST_DIV 10 /* Histogram buckets/second. */
|
#define FWD_CBS_HIST_DIV 10 /* Histogram buckets/second. */
|
||||||
static long n_launders_hist[2 * MAX_FWD_CB_JIFFIES / (HZ / FWD_CBS_HIST_DIV)];
|
struct rcu_launder_hist {
|
||||||
|
long n_launders;
|
||||||
|
unsigned long launder_gp_seq;
|
||||||
|
};
|
||||||
|
#define N_LAUNDERS_HIST (2 * MAX_FWD_CB_JIFFIES / (HZ / FWD_CBS_HIST_DIV))
|
||||||
|
static struct rcu_launder_hist n_launders_hist[N_LAUNDERS_HIST];
|
||||||
|
static unsigned long rcu_launder_gp_seq_start;
|
||||||
|
|
||||||
static void rcu_torture_fwd_cb_hist(void)
|
static void rcu_torture_fwd_cb_hist(void)
|
||||||
{
|
{
|
||||||
|
unsigned long gps;
|
||||||
|
unsigned long gps_old;
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (i = ARRAY_SIZE(n_launders_hist) - 1; i > 0; i--)
|
for (i = ARRAY_SIZE(n_launders_hist) - 1; i > 0; i--)
|
||||||
if (n_launders_hist[i] > 0)
|
if (n_launders_hist[i].n_launders > 0)
|
||||||
break;
|
break;
|
||||||
pr_alert("%s: Callback-invocation histogram (duration %lu jiffies):",
|
pr_alert("%s: Callback-invocation histogram (duration %lu jiffies):",
|
||||||
__func__, jiffies - rcu_fwd_startat);
|
__func__, jiffies - rcu_fwd_startat);
|
||||||
for (j = 0; j <= i; j++)
|
gps_old = rcu_launder_gp_seq_start;
|
||||||
pr_cont(" %ds/%d: %ld",
|
for (j = 0; j <= i; j++) {
|
||||||
j + 1, FWD_CBS_HIST_DIV, n_launders_hist[j]);
|
gps = n_launders_hist[j].launder_gp_seq;
|
||||||
|
pr_cont(" %ds/%d: %ld:%ld",
|
||||||
|
j + 1, FWD_CBS_HIST_DIV, n_launders_hist[j].n_launders,
|
||||||
|
rcutorture_seq_diff(gps, gps_old));
|
||||||
|
gps_old = gps;
|
||||||
|
}
|
||||||
pr_cont("\n");
|
pr_cont("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1666,7 +1679,8 @@ static void rcu_torture_fwd_cb_cr(struct rcu_head *rhp)
|
||||||
i = ((jiffies - rcu_fwd_startat) / (HZ / FWD_CBS_HIST_DIV));
|
i = ((jiffies - rcu_fwd_startat) / (HZ / FWD_CBS_HIST_DIV));
|
||||||
if (i >= ARRAY_SIZE(n_launders_hist))
|
if (i >= ARRAY_SIZE(n_launders_hist))
|
||||||
i = ARRAY_SIZE(n_launders_hist) - 1;
|
i = ARRAY_SIZE(n_launders_hist) - 1;
|
||||||
n_launders_hist[i]++;
|
n_launders_hist[i].n_launders++;
|
||||||
|
n_launders_hist[i].launder_gp_seq = cur_ops->get_gp_seq();
|
||||||
spin_unlock_irqrestore(&rcu_fwd_lock, flags);
|
spin_unlock_irqrestore(&rcu_fwd_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1786,9 +1800,10 @@ static void rcu_torture_fwd_prog_cr(void)
|
||||||
n_max_cbs = 0;
|
n_max_cbs = 0;
|
||||||
n_max_gps = 0;
|
n_max_gps = 0;
|
||||||
for (i = 0; i < ARRAY_SIZE(n_launders_hist); i++)
|
for (i = 0; i < ARRAY_SIZE(n_launders_hist); i++)
|
||||||
n_launders_hist[i] = 0;
|
n_launders_hist[i].n_launders = 0;
|
||||||
cver = READ_ONCE(rcu_torture_current_version);
|
cver = READ_ONCE(rcu_torture_current_version);
|
||||||
gps = cur_ops->get_gp_seq();
|
gps = cur_ops->get_gp_seq();
|
||||||
|
rcu_launder_gp_seq_start = gps;
|
||||||
while (time_before(jiffies, stopat) &&
|
while (time_before(jiffies, stopat) &&
|
||||||
!READ_ONCE(rcu_fwd_emergency_stop) && !torture_must_stop()) {
|
!READ_ONCE(rcu_fwd_emergency_stop) && !torture_must_stop()) {
|
||||||
rfcp = READ_ONCE(rcu_fwd_cb_head);
|
rfcp = READ_ONCE(rcu_fwd_cb_head);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче