summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2019-01-25 22:41:53 +0100
committerRichard Braun <rbraun@sceen.net>2019-01-25 22:41:53 +0100
commitc62f90391bd229e37350067751e2d2fff99f2267 (patch)
tree542aa39ceed5ff02ed7a4c27e99acc9046046b2b
parentddd03534471b9f092dac144fc05d727970236cf9 (diff)
kern/log: fix overrun handling
-rw-r--r--kern/log.c66
1 files changed, 25 insertions, 41 deletions
diff --git a/kern/log.c b/kern/log.c
index f20f966b..0bd13c6d 100644
--- a/kern/log.c
+++ b/kern/log.c
@@ -52,14 +52,6 @@ static struct thread *log_thread;
static struct cbuf log_cbuf;
static char log_buffer[LOG_BUFFER_SIZE];
-/*
- * This index is used by the log thread to report what it has consumed
- * so that producers can detect overruns.
- */
-static size_t log_index;
-
-static size_t log_nr_overruns;
-
static unsigned int log_print_level;
/*
@@ -92,6 +84,7 @@ struct log_consume_ctx {
char buf[LOG_MSG_SIZE];
size_t index;
size_t size;
+ size_t nr_overruns;
};
static void
@@ -101,24 +94,23 @@ log_consume_ctx_init(struct log_consume_ctx *ctx, struct cbuf *cbuf)
ctx->cbuf_index = cbuf_start(cbuf);
ctx->index = 0;
ctx->size = 0;
+ ctx->nr_overruns = 0;
}
-static size_t
-log_consume_ctx_index(const struct log_consume_ctx *ctx)
+static bool
+log_consume_ctx_empty(const struct log_consume_ctx *ctx)
{
- return ctx->cbuf_index;
+ return ctx->cbuf_index == cbuf_end(ctx->cbuf);
}
-static void
-log_consume_ctx_set_index(struct log_consume_ctx *ctx, size_t index)
+static size_t
+log_consume_ctx_reset_overruns(struct log_consume_ctx *ctx)
{
- ctx->cbuf_index = index;
-}
+ size_t nr_overruns;
-static bool
-log_consume_ctx_empty(const struct log_consume_ctx *ctx)
-{
- return ctx->cbuf_index == cbuf_end(ctx->cbuf);
+ nr_overruns = ctx->nr_overruns;
+ ctx->nr_overruns = 0;
+ return nr_overruns;
}
static int
@@ -126,18 +118,26 @@ log_consume_ctx_pop(struct log_consume_ctx *ctx, char *byte)
{
int error;
- if (ctx->index >= ctx->size) {
+ if (ctx->index == ctx->size) {
ctx->index = 0;
ctx->size = sizeof(ctx->buf);
error = cbuf_read(ctx->cbuf, ctx->cbuf_index, ctx->buf, &ctx->size);
if (error) {
- ctx->cbuf_index = cbuf_start(ctx->cbuf);
+ size_t new_cbuf_index;
+
+ assert(error == EINVAL);
+ new_cbuf_index = cbuf_start(ctx->cbuf);
+ ctx->nr_overruns = new_cbuf_index - ctx->cbuf_index;
+ ctx->cbuf_index = new_cbuf_index;
+ ctx->size = 0;
return error;
}
}
ctx->cbuf_index++;
+ assert(ctx->size <= sizeof(ctx->buf));
+ assert(ctx->index < ctx->size);
*byte = ctx->buf[ctx->index];
ctx->index++;
return 0;
@@ -227,6 +227,7 @@ log_record_init_consume(struct log_record *record, struct log_consume_ctx *ctx)
error = log_consume_ctx_pop(ctx, &c);
if (error) {
+ marker_found = false;
continue;
}
@@ -287,7 +288,7 @@ log_start_shell(unsigned long *flags)
#else /* CONFIG_SHELL */
#define log_start_shell(flags)
-#endif /* CONFIG_SHELL*/
+#endif /* CONFIG_SHELL */
static void
log_run(void *arg)
@@ -313,23 +314,17 @@ log_run(void *arg)
* a clean ordered output.
*/
log_start_shell(&flags);
- log_index = log_consume_ctx_index(&ctx);
thread_sleep(&log_lock, &log_cbuf, "log_cbuf");
-
- log_consume_ctx_set_index(&ctx, log_index);
}
error = log_record_init_consume(&record, &ctx);
/* Drain the log buffer before reporting overruns */
if (log_consume_ctx_empty(&ctx)) {
- nr_overruns = log_nr_overruns;
- log_nr_overruns = 0;
+ nr_overruns = log_consume_ctx_reset_overruns(&ctx);
}
- log_index = log_consume_ctx_index(&ctx);
-
spinlock_unlock_intr_restore(&log_lock, flags);
if (!error) {
@@ -343,8 +338,6 @@ log_run(void *arg)
}
spinlock_lock_intr_save(&log_lock, &flags);
-
- log_consume_ctx_set_index(&ctx, log_index);
}
}
@@ -434,7 +427,6 @@ static int __init
log_setup(void)
{
cbuf_init(&log_cbuf, log_buffer, sizeof(log_buffer));
- log_index = cbuf_start(&log_cbuf);
spinlock_init(&log_lock);
log_print_level = LOG_INFO;
@@ -474,15 +466,7 @@ INIT_OP_DEFINE(log_start,
static void
log_write(const void *s, size_t size)
{
- int error;
-
- error = cbuf_push(&log_cbuf, s, size, true);
- assert(!error);
-
- if (!cbuf_range_valid(&log_cbuf, log_index, log_index + 1)) {
- log_nr_overruns += cbuf_start(&log_cbuf) - log_index;
- log_index = cbuf_start(&log_cbuf);
- }
+ cbuf_push(&log_cbuf, s, size, true);
}
int