LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Karsten Wiese <fzu@wemgehoertderstaat.de>
To: Ingo Molnar <mingo@elte.hu>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH -rt 2/3] Make trace_freerunning work; Take 2: Add atomic_t underrun
Date: Wed, 6 Dec 2006 16:18:50 +0100	[thread overview]
Message-ID: <200612061618.51150.fzu@wemgehoertderstaat.de> (raw)
In-Reply-To: <200612061612.53254.fzu@wemgehoertderstaat.de>


Add atomic_t underrun to struct cpu_trace.
Increment it only when trace_freerunning is set and an older trace
entry is overwritten.
Modify copy_trace() to reorder entries, if underrun != 0.

Signed-off-by: Karsten Wiese <fzu@wemgehoertderstaat.de>


--- rt6-kw/kernel/latency_trace-tk2.1.c	2006-12-06 14:43:52.000000000 +0100
+++ rt6-kw/kernel/latency_trace.c	2006-12-06 14:58:44.000000000 +0100
@@ -228,6 +228,7 @@ struct cpu_trace {
 	cycle_t preempt_timestamp;
 	unsigned long critical_start, critical_end;
 	unsigned long critical_sequence;
+	atomic_t underrun;
 	atomic_t overrun;
 	int early_warning;
 	int latency_type;
@@ -606,16 +607,21 @@ again:
 	idx_next = idx + 1;
 	timestamp = now();
 
-	if (unlikely((trace_freerunning || print_functions) &&
-						(idx_next >= MAX_TRACE)))
+	if (unlikely((trace_freerunning || print_functions || atomic_read(&tr->underrun)) &&
+		     (idx_next >= MAX_TRACE) && !atomic_read(&tr->overrun))) {
+		atomic_inc(&tr->underrun);
 		idx_next = 0;
+	}
 	if (unlikely(idx >= MAX_TRACE)) {
 		atomic_inc(&tr->overrun);
 		goto out;
 	}
 #ifdef __HAVE_ARCH_CMPXCHG
-	if (unlikely(cmpxchg(&tr->trace_idx, idx, idx_next) != idx))
+	if (unlikely(cmpxchg(&tr->trace_idx, idx, idx_next) != idx)) {
+		if (idx_next == 0)
+			atomic_dec(&tr->underrun);
 		goto again;
+	}
 #else
 # ifdef CONFIG_SMP
 #  error CMPXCHG missing
@@ -626,6 +632,9 @@ again:
 	tr->trace_idx = idx_next;
 # endif
 #endif
+	if (unlikely(idx_next != 0 && atomic_read(&tr->underrun)))
+		atomic_inc(&tr->underrun);
+
 	pc = preempt_count();
 
 	if (unlikely(!tr->trace))
@@ -938,13 +947,12 @@ char *pid_to_cmdline(unsigned long pid)
 	return cmdline;
 }
 
-static void copy_trace(struct cpu_trace *save, struct cpu_trace *tr)
+static void copy_trace(struct cpu_trace *save, struct cpu_trace *tr, int reorder)
 {
 	if (!save->trace || !tr->trace)
 		return;
 	/* free-running needs reordering */
-	/* FIXME: what if we just switched back from freerunning mode? */
-	if (trace_freerunning) {
+	if (reorder && atomic_read(&tr->underrun)) {
 		int i, idx, idx0 = tr->trace_idx;
 
 		for (i = 0; i < MAX_TRACE; i++) {
@@ -959,6 +967,7 @@ static void copy_trace(struct cpu_trace 
 			min(save->trace_idx, MAX_TRACE) *
 					sizeof(struct trace_entry));
 	}
+	save->underrun = tr->underrun;
 	save->overrun = tr->overrun;
 }
 
@@ -1010,7 +1019,7 @@ static void update_out_trace(void)
 	cycle_t stamp, first_stamp, last_stamp;
 	struct block_idx bidx = { { 0, }, };
 	struct cpu_trace *tmp_max, *tmp_out;
-	int cpu, sum, entries, overrun_sum;
+	int cpu, sum, entries, underrun_sum, overrun_sum;
 
 	/*
 	 * For out_tr we only have the first array's trace entries
@@ -1023,7 +1032,7 @@ static void update_out_trace(void)
 	 * Easier to copy this way. Note: the trace buffer is private
 	 * to the output buffer, so preserve it:
 	 */
-	copy_trace(tmp_out, tmp_max);
+	copy_trace(tmp_out, tmp_max, 0);
 	tmp = tmp_out->trace;
 	*tmp_out = *tmp_max;
 	tmp_out->trace = tmp;
@@ -1134,12 +1143,15 @@ static void update_out_trace(void)
 	}
 
 	sum = 0;
+	underrun_sum = 0;
 	overrun_sum = 0;
 	for_each_online_cpu(cpu) {
 		sum += max_tr.traces[cpu].trace_idx;
+		underrun_sum += atomic_read(&max_tr.traces[cpu].underrun);
 		overrun_sum += atomic_read(&max_tr.traces[cpu].overrun);
 	}
 	tmp_out->trace_idx = sum;
+	atomic_set(&tmp_out->underrun, underrun_sum);
 	atomic_set(&tmp_out->overrun, overrun_sum);
 }
 
@@ -1186,7 +1198,7 @@ static void * notrace l_start(struct seq
 		seq_puts(m, "--------------------------------------------------------------------\n");
 		seq_printf(m, " latency: %lu us, #%lu/%lu, CPU#%d | (M:%s VP:%d, KP:%d, SP:%d HP:%d",
 			cycles_to_usecs(tr->saved_latency),
-			entries, entries + atomic_read(&tr->overrun),
+			entries, entries + atomic_read(&tr->underrun) + atomic_read(&tr->overrun),
 			out_tr.cpu,
 #if defined(CONFIG_PREEMPT_NONE)
 			"server",
@@ -1629,11 +1641,11 @@ static void update_max_tr(struct cpu_tra
 
 	if (all_cpus) {
 		for_each_online_cpu(cpu) {
-			copy_trace(max_tr.traces + cpu, cpu_traces + cpu);
+			copy_trace(max_tr.traces + cpu, cpu_traces + cpu, 1);
 			atomic_dec(&cpu_traces[cpu].disabled);
 		}
 	} else
-		copy_trace(save, tr);
+		copy_trace(save, tr, 1);
 }
 
 #else /* !EVENT_TRACE */
@@ -1830,6 +1842,7 @@ __start_critical_timing(unsigned long ei
 	tr->critical_sequence = max_sequence;
 	tr->preempt_timestamp = get_monotonic_cycles();
 	tr->critical_start = eip;
+	atomic_set(&tr->underrun, 0);
 	atomic_set(&tr->overrun, 0);
 	reset_trace_idx(cpu, tr);
 	tr->latency_type = latency_type;
@@ -2208,6 +2221,7 @@ void __trace_start_sched_wakeup(struct t
 		tr->preempt_timestamp = get_monotonic_cycles();
 		tr->latency_type = WAKEUP_LATENCY;
 		tr->critical_start = CALLER_ADDR0;
+		atomic_set(&tr->underrun, 0);
 		atomic_set(&tr->overrun, 0);
 		_trace_cmdline(raw_smp_processor_id(), tr);
 		atomic_dec(&tr->disabled);
@@ -2318,6 +2332,7 @@ long user_trace_start(void)
 	tr->critical_sequence = max_sequence;
 	tr->preempt_timestamp = get_monotonic_cycles();
 	tr->critical_start = CALLER_ADDR0;
+	atomic_set(&tr->underrun, 0);
 	atomic_set(&tr->overrun, 0);
 	_trace_cmdline(cpu, tr);
 	mcount();

  reply	other threads:[~2006-12-06 15:18 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20061205220257.1AECF3E2420@elvis.elte.hu>
2006-12-05 22:10 ` [PATCH -rt 2/3] Make trace_freerunning work Ingo Molnar
2006-12-06 15:08   ` [PATCH -rt 0/3] Make trace_freerunning work; Take 2 Karsten Wiese
2006-12-06 15:12     ` [PATCH -rt 1/3] Make trace_freerunning work; Take 2: Off by 1 tweaks Karsten Wiese
2006-12-06 15:18       ` Karsten Wiese [this message]
2006-12-06 15:26         ` [PATCH -rt 3/3] Make trace_freerunning work; Take 2: change reset_trace_idx() Karsten Wiese
2006-12-06 15:54     ` [PATCH -rt 0/3] Make trace_freerunning work; Take 2 Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200612061618.51150.fzu@wemgehoertderstaat.de \
    --to=fzu@wemgehoertderstaat.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --subject='Re: [PATCH -rt 2/3] Make trace_freerunning work; Take 2: Add atomic_t underrun' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).