[PATCH 24/26 v5] seq_buf: Move the seq_buf code to lib/
From: "Steven Rostedt (Red Hat)" The seq_buf functions are rather useful outside of tracing. Instead of having it be dependent on CONFIG_TRACING, move the code into lib/ and allow other users to have access to it even when tracing is not configured. The seq_buf utility is similar to the seq_file utility, but instead of writing sending data back up to userland, it writes it into a buffer defined at seq_buf_init(). This allows us to send a descriptor around that writes printf() formatted strings into it that can be retrieved later. It is currently used by the tracing facility for such things like trace events to convert its binary saved data in the ring buffer into an ASCII human readable context to be displayed in /sys/kernel/debug/trace. It can also be used for doing NMI prints safely from NMI context into the seq_buf and retrieved later and dumped to printk() safely. Doing printk() from an NMI context is dangerous because an NMI can preempt a current printk() and deadlock on it. Link: http://lkml.kernel.org/p/20140619213952.058255...@goodmis.org Tested-by: Jiri Kosina Acked-by: Jiri Kosina Reviewed-by: Petr Mladek Signed-off-by: Steven Rostedt --- kernel/trace/Makefile | 1 - kernel/trace/seq_buf.c | 351 - lib/Makefile | 2 +- lib/seq_buf.c | 351 + 4 files changed, 352 insertions(+), 353 deletions(-) delete mode 100644 kernel/trace/seq_buf.c create mode 100644 lib/seq_buf.c diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index edc98c72a634..67d6369ddf83 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -29,7 +29,6 @@ obj-$(CONFIG_RING_BUFFER_BENCHMARK) += ring_buffer_benchmark.o obj-$(CONFIG_TRACING) += trace.o obj-$(CONFIG_TRACING) += trace_output.o obj-$(CONFIG_TRACING) += trace_seq.o -obj-$(CONFIG_TRACING) += seq_buf.o obj-$(CONFIG_TRACING) += trace_stat.o obj-$(CONFIG_TRACING) += trace_printk.o obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o diff --git a/kernel/trace/seq_buf.c b/kernel/trace/seq_buf.c deleted file mode 100644 index a2288ca567a3.. --- a/kernel/trace/seq_buf.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * seq_buf.c - * - * Copyright (C) 2014 Red Hat Inc, Steven Rostedt - * - * The seq_buf is a handy tool that allows you to pass a descriptor around - * to a buffer that other functions can write to. It is similar to the - * seq_file functionality but has some differences. - * - * To use it, the seq_buf must be initialized with seq_buf_init(). - * This will set up the counters within the descriptor. You can call - * seq_buf_init() more than once to reset the seq_buf to start - * from scratch. - */ -#include -#include -#include - -static bool seq_buf_can_fit(struct seq_buf *s, size_t len) -{ - return s->len + len <= s->size; -} - -/** - * seq_buf_print_seq - move the contents of seq_buf into a seq_file - * @m: the seq_file descriptor that is the destination - * @s: the seq_buf descriptor that is the source. - * - * Returns zero on success, non zero otherwise - */ -int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s) -{ - unsigned int len = seq_buf_used(s); - - return seq_write(m, s->buffer, len); -} - -/** - * seq_buf_vprintf - sequence printing of information. - * @s: seq_buf descriptor - * @fmt: printf format string - * @args: va_list of arguments from a printf() type function - * - * Writes a vnprintf() format into the sequencce buffer. - * - * Returns zero on success, -1 on overflow. - */ -int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args) -{ - int len; - - WARN_ON(s->size == 0); - - if (s->len < s->size) { - len = vsnprintf(s->buffer + s->len, s->size - s->len, fmt, args); - if (seq_buf_can_fit(s, len)) { - s->len += len; - return 0; - } - } - seq_buf_set_overflow(s); - return -1; -} - -/** - * seq_buf_printf - sequence printing of information - * @s: seq_buf descriptor - * @fmt: printf format string - * - * Writes a printf() format into the sequence buffer. - * - * Returns zero on success, -1 on overflow. - */ -int seq_buf_printf(struct seq_buf *s, const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret = seq_buf_vprintf(s, fmt, ap); - va_end(ap); - - return ret; -} - -/** - * seq_buf_bitmask - write a bitmask array in its ASCII representation - * @s: seq_buf descriptor - * @maskp: points to an array of unsigned longs that represent a bitmask - * @nmaskbits: The number of bits that are valid in @maskp - * - * Writes a ASCII representation of a bitmask string into @s. - * - * Returns zero on success, -1 on overflow. - */ -int seq_buf_bitmask(struct seq_buf *s, const unsigned long *maskp, - int nmaskbits) -{ - unsigned int len =
[PATCH 24/26 v5] seq_buf: Move the seq_buf code to lib/
From: Steven Rostedt (Red Hat) rost...@goodmis.org The seq_buf functions are rather useful outside of tracing. Instead of having it be dependent on CONFIG_TRACING, move the code into lib/ and allow other users to have access to it even when tracing is not configured. The seq_buf utility is similar to the seq_file utility, but instead of writing sending data back up to userland, it writes it into a buffer defined at seq_buf_init(). This allows us to send a descriptor around that writes printf() formatted strings into it that can be retrieved later. It is currently used by the tracing facility for such things like trace events to convert its binary saved data in the ring buffer into an ASCII human readable context to be displayed in /sys/kernel/debug/trace. It can also be used for doing NMI prints safely from NMI context into the seq_buf and retrieved later and dumped to printk() safely. Doing printk() from an NMI context is dangerous because an NMI can preempt a current printk() and deadlock on it. Link: http://lkml.kernel.org/p/20140619213952.058255...@goodmis.org Tested-by: Jiri Kosina jkos...@suse.cz Acked-by: Jiri Kosina jkos...@suse.cz Reviewed-by: Petr Mladek pmla...@suse.cz Signed-off-by: Steven Rostedt rost...@goodmis.org --- kernel/trace/Makefile | 1 - kernel/trace/seq_buf.c | 351 - lib/Makefile | 2 +- lib/seq_buf.c | 351 + 4 files changed, 352 insertions(+), 353 deletions(-) delete mode 100644 kernel/trace/seq_buf.c create mode 100644 lib/seq_buf.c diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index edc98c72a634..67d6369ddf83 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -29,7 +29,6 @@ obj-$(CONFIG_RING_BUFFER_BENCHMARK) += ring_buffer_benchmark.o obj-$(CONFIG_TRACING) += trace.o obj-$(CONFIG_TRACING) += trace_output.o obj-$(CONFIG_TRACING) += trace_seq.o -obj-$(CONFIG_TRACING) += seq_buf.o obj-$(CONFIG_TRACING) += trace_stat.o obj-$(CONFIG_TRACING) += trace_printk.o obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o diff --git a/kernel/trace/seq_buf.c b/kernel/trace/seq_buf.c deleted file mode 100644 index a2288ca567a3.. --- a/kernel/trace/seq_buf.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * seq_buf.c - * - * Copyright (C) 2014 Red Hat Inc, Steven Rostedt srost...@redhat.com - * - * The seq_buf is a handy tool that allows you to pass a descriptor around - * to a buffer that other functions can write to. It is similar to the - * seq_file functionality but has some differences. - * - * To use it, the seq_buf must be initialized with seq_buf_init(). - * This will set up the counters within the descriptor. You can call - * seq_buf_init() more than once to reset the seq_buf to start - * from scratch. - */ -#include linux/uaccess.h -#include linux/seq_file.h -#include linux/seq_buf.h - -static bool seq_buf_can_fit(struct seq_buf *s, size_t len) -{ - return s-len + len = s-size; -} - -/** - * seq_buf_print_seq - move the contents of seq_buf into a seq_file - * @m: the seq_file descriptor that is the destination - * @s: the seq_buf descriptor that is the source. - * - * Returns zero on success, non zero otherwise - */ -int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s) -{ - unsigned int len = seq_buf_used(s); - - return seq_write(m, s-buffer, len); -} - -/** - * seq_buf_vprintf - sequence printing of information. - * @s: seq_buf descriptor - * @fmt: printf format string - * @args: va_list of arguments from a printf() type function - * - * Writes a vnprintf() format into the sequencce buffer. - * - * Returns zero on success, -1 on overflow. - */ -int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args) -{ - int len; - - WARN_ON(s-size == 0); - - if (s-len s-size) { - len = vsnprintf(s-buffer + s-len, s-size - s-len, fmt, args); - if (seq_buf_can_fit(s, len)) { - s-len += len; - return 0; - } - } - seq_buf_set_overflow(s); - return -1; -} - -/** - * seq_buf_printf - sequence printing of information - * @s: seq_buf descriptor - * @fmt: printf format string - * - * Writes a printf() format into the sequence buffer. - * - * Returns zero on success, -1 on overflow. - */ -int seq_buf_printf(struct seq_buf *s, const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret = seq_buf_vprintf(s, fmt, ap); - va_end(ap); - - return ret; -} - -/** - * seq_buf_bitmask - write a bitmask array in its ASCII representation - * @s: seq_buf descriptor - * @maskp: points to an array of unsigned longs that represent a bitmask - * @nmaskbits: The number of bits that are valid in @maskp - * - * Writes a ASCII representation of a bitmask string into @s. - * - * Returns zero on success, -1 on overflow. - */ -int