debugtrace: add entry when entry count is wrapping

The debugtrace entry count is a 32 bit variable, so it can wrap when
lots of trace entries are being produced. Making it wider would result
in a waste of buffer space as the printed count value would consume
more bytes when not wrapping.

So instead of letting the count value grow to huge values let it wrap
and add a wrap counter printed in this situation. This will keep the
needed buffer space at today's value while avoiding to loose a way to
sort all entries in case multiple trace buffers are involved.

Note that the wrap message will be printed before the first trace
entry in case output is switched to console early. This is on purpose
in order to enable a future support of debugtrace to console without
any allocated buffer.

Signed-off-by: Juergen Gross <jgross@suse.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Juergen Gross authored and Jan Beulich committed 2019-09-12 15:13:47 +02:00
1 parent 6338c9ead9
commit c82425e456
1 file changed
+29 -4
+29 -4
View File
@@ -15,11 +15,14 @@
#include <xen/spinlock.h>
#include <xen/watchdog.h>
#define DEBUGTRACE_COUNT_WRAP 99999999
/* Send output direct to console, or buffer it? */
static volatile bool debugtrace_send_to_console;
struct debugtrace_data {
unsigned long prd; /* Producer index. */
unsigned long wrap_cnt;
char buf[];
};
@@ -72,6 +75,7 @@ static void debugtrace_dump_buffer(struct debugtrace_data *data,
/* Print youngest portion of the ring. */
data->buf[data->prd] = '\0';
console_serial_puts(&data->buf[0], data->prd);
printk("wrap: %lu\n", data->wrap_cnt);
memset(data->buf, '\0', debugtrace_bytes);
data->prd = 0;
@@ -153,9 +157,9 @@ void debugtrace_printk(const char *fmt, ...)
{
static char buf[1024], last_buf[1024];
static unsigned int count, last_count, last_cpu;
static unsigned long last_prd;
static unsigned long last_prd, wrap_cnt;
char cntbuf[24];
char cntbuf[50];
va_list args;
unsigned long flags;
unsigned int nr;
@@ -173,10 +177,23 @@ void debugtrace_printk(const char *fmt, ...)
nr = vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
if ( count == DEBUGTRACE_COUNT_WRAP )
{
count = 0;
wrap_cnt++;
}
if ( debugtrace_send_to_console )
{
unsigned int n = scnprintf(cntbuf, sizeof(cntbuf), "%u ", ++count);
unsigned int n;
if ( count == 0 )
{
n = scnprintf(cntbuf, sizeof(cntbuf), "wrap: %lu\n", wrap_cnt);
console_serial_puts(cntbuf, n);
}
n = scnprintf(cntbuf, sizeof(cntbuf), "%u ", ++count);
console_serial_puts(cntbuf, n);
console_serial_puts(buf, nr);
}
@@ -184,8 +201,16 @@ void debugtrace_printk(const char *fmt, ...)
{
unsigned int cpu = debugtrace_per_cpu ? smp_processor_id() : 0;
if ( debugtrace_buf_empty || cpu != last_cpu || strcmp(buf, last_buf) )
if ( debugtrace_buf_empty || cpu != last_cpu ||
wrap_cnt != data->wrap_cnt || strcmp(buf, last_buf) )
{
if ( wrap_cnt != data->wrap_cnt )
{
snprintf(cntbuf, sizeof(cntbuf), "wrap: %lu->%lu\n",
data->wrap_cnt, wrap_cnt);
debugtrace_add_to_buf(cntbuf);
data->wrap_cnt = wrap_cnt;
}
debugtrace_buf_empty = false;
last_prd = data->prd;
last_count = ++count;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.