linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: akpm@linux-foundation.org, davem@davemloft.net
Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	Tejun Heo <tj@kernel.org>, Kay Sievers <kay@vrfy.org>,
	Petr Mladek <pmladek@suse.cz>
Subject: [PATCH 05/16] printk: implement log_seq_range() and ext_log_from_seq()
Date: Thu, 16 Apr 2015 19:03:42 -0400	[thread overview]
Message-ID: <1429225433-11946-6-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1429225433-11946-1-git-send-email-tj@kernel.org>

Implement two functions to access log messages by their sequence
numbers.

* log_seq_range() determines the currently available sequence number
  range.

* ext_log_from_seq() outputs log message identified by a given
  sequence number in the extended format.

These will be used to implement reliable netconsole.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Kay Sievers <kay@vrfy.org>
Cc: Petr Mladek <pmladek@suse.cz>
---
 include/linux/printk.h | 14 ++++++++
 kernel/printk/printk.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 110 insertions(+)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index 58b1fec..4fd3bb4 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -6,6 +6,7 @@
 #include <linux/kern_levels.h>
 #include <linux/linkage.h>
 #include <linux/cache.h>
+#include <linux/errno.h>
 
 extern const char linux_banner[];
 extern const char linux_proc_banner[];
@@ -169,6 +170,8 @@ void __init setup_log_buf(int early);
 void dump_stack_set_arch_desc(const char *fmt, ...);
 void dump_stack_print_info(const char *log_lvl);
 void show_regs_print_info(const char *log_lvl);
+void log_seq_range(u64 *beginp, u64 *endp);
+ssize_t ext_log_from_seq(char *buf, size_t size, u64 log_seq);
 #else
 static inline __printf(1, 0)
 int vprintk(const char *s, va_list args)
@@ -228,6 +231,17 @@ static inline void dump_stack_print_info(const char *log_lvl)
 static inline void show_regs_print_info(const char *log_lvl)
 {
 }
+
+static inline void log_seq_range(u64 *begin_seqp, u64 *end_seqp)
+{
+	*begin_seqp = 0;
+	*end_seqp = 0;
+}
+
+static inline ssize_t ext_log_from_seq(char *buf, size_t size, u64 log_seq)
+{
+	return -ERANGE;
+}
 #endif
 
 extern asmlinkage void dump_stack(void) __cold;
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 349a37b..904413e 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -617,6 +617,102 @@ static ssize_t msg_print_ext_body(char *buf, size_t size,
 	return p - buf;
 }
 
+/**
+ * log_seq_range - get the range of available log sequence numbers
+ * @begin_seqp: output parameter for the begin of the range
+ * @end_seqp: output parameter for the end of the range
+ *
+ * Returns the log sequence number range [*@begin_seqp, *@ends_seqp) which
+ * is currently available to be retrieved using ext_log_from_seq().  Note
+ * that the range may shift anytime.
+ */
+void log_seq_range(u64 *begin_seqp, u64 *end_seqp)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&logbuf_lock, flags);
+	*begin_seqp = log_first_seq;
+	*end_seqp = log_next_seq;
+	raw_spin_unlock_irqrestore(&logbuf_lock, flags);
+}
+EXPORT_SYMBOL_GPL(log_seq_range);
+
+/**
+ * ext_log_from_seq - obtain log message in extended format from its seq number
+ * @buf: output buffer
+ * @size: size of @buf
+ * @log_seq: target log sequence number
+ *
+ * Print the log message with @log_seq as its sequence number into @buf
+ * using the extended format.  On success, returns the length of formatted
+ * output excluding the terminating '\0'.  If @log_seq doesn't match any
+ * message, -ERANGE is returned.
+ *
+ * Due to the way messages are stored, accessing @log_seq requires seeking
+ * the log buffer sequentially.  As the last looked up position is cached,
+ * accessing messages in ascending sequence order is recommended.
+ */
+ssize_t ext_log_from_seq(char *buf, size_t size, u64 log_seq)
+{
+	static u64 seq_hint;
+	static u32 idx_hint;
+	static enum log_flags prev_flags_hint;
+	struct printk_log *msg;
+	enum log_flags prev_flags = 0;
+	unsigned long flags;
+	ssize_t len;
+	u32 seq;
+	u32 prev_idx, idx;
+
+	raw_spin_lock_irqsave(&logbuf_lock, flags);
+
+	if (log_seq < log_first_seq || log_seq >= log_next_seq) {
+		len = -ERANGE;
+		goto out_unlock;
+	}
+
+	/*
+	 * Seek to @log_seq to determine its index. The last looked up seq
+	 * and index are cached to accelerate in-order accesses.  For now,
+	 * @prev_flags is best effort.  It'd be better to restructure it so
+	 * that the current entry carries all the relevant information
+	 * without depending on the previous one.
+	 */
+	seq = log_first_seq;
+	idx = log_first_idx;
+
+	if (seq < seq_hint && seq_hint <= log_seq) {
+		seq = seq_hint;
+		idx = idx_hint;
+		prev_flags = prev_flags_hint;
+	}
+
+	prev_idx = idx;
+	while (seq < log_seq) {
+		seq++;
+		prev_idx = idx;
+		idx = log_next(idx);
+	}
+
+	if (prev_idx != idx)
+		prev_flags = log_from_idx(prev_idx)->flags;
+	msg = log_from_idx(idx);
+
+	/* entry located, format it */
+	len = msg_print_ext_header(buf, size, msg, seq, prev_flags);
+	len += msg_print_ext_body(buf + len, size - len,
+				  log_dict(msg), msg->dict_len,
+				  log_text(msg), msg->text_len);
+
+	seq_hint = seq;
+	idx_hint = idx;
+	prev_flags_hint = prev_flags;
+out_unlock:
+	raw_spin_unlock_irqrestore(&logbuf_lock, flags);
+	return len;
+}
+EXPORT_SYMBOL_GPL(ext_log_from_seq);
+
 /* /dev/kmsg - userspace message inject/listen interface */
 struct devkmsg_user {
 	u64 seq;
-- 
2.1.0


  parent reply	other threads:[~2015-04-16 23:09 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-16 23:03 [PATCHSET] printk, netconsole: implement reliable netconsole Tejun Heo
2015-04-16 23:03 ` [PATCH 01/16] printk: guard the amount written per line by devkmsg_read() Tejun Heo
2015-04-20 12:11   ` Petr Mladek
2015-04-20 12:33     ` Petr Mladek
2015-04-16 23:03 ` [PATCH 02/16] printk: factor out message formatting from devkmsg_read() Tejun Heo
2015-04-20 12:30   ` Petr Mladek
2015-04-16 23:03 ` [PATCH 03/16] printk: move LOG_NOCONS skipping into call_console_drivers() Tejun Heo
2015-04-20 12:50   ` Petr Mladek
2015-04-16 23:03 ` [PATCH 04/16] printk: implement support for extended console drivers Tejun Heo
2015-04-20 15:43   ` Petr Mladek
2015-04-21 10:03     ` Petr Mladek
2015-04-27 21:09     ` Tejun Heo
2015-04-28  9:42       ` Petr Mladek
2015-04-28 14:10         ` Tejun Heo
2015-04-28 14:24           ` Petr Mladek
2015-04-16 23:03 ` Tejun Heo [this message]
2015-04-16 23:03 ` [PATCH 06/16] netconsole: make netconsole_target->enabled a bool Tejun Heo
2015-04-16 23:03 ` [PATCH 07/16] netconsole: factor out alloc_netconsole_target() Tejun Heo
2015-04-16 23:03 ` [PATCH 08/16] netconsole: punt disabling to workqueue from netdevice_notifier Tejun Heo
2015-04-16 23:03 ` [PATCH 09/16] netconsole: replace target_list_lock with console_lock Tejun Heo
2015-04-16 23:03 ` [PATCH 10/16] netconsole: introduce netconsole_mutex Tejun Heo
2015-04-16 23:03 ` [PATCH 11/16] netconsole: consolidate enable/disable and create/destroy paths Tejun Heo
2015-04-16 23:03 ` [PATCH 12/16] netconsole: implement extended console support Tejun Heo
2015-04-16 23:03 ` [PATCH 13/16] netconsole: implement retransmission support for extended consoles Tejun Heo
2015-04-16 23:03 ` [PATCH 14/16] netconsole: implement ack handling and emergency transmission Tejun Heo
2015-04-16 23:03 ` [PATCH 15/16] netconsole: implement netconsole receiver library Tejun Heo
2015-04-16 23:03 ` [PATCH 16/16] netconsole: update documentation for extended netconsole Tejun Heo
2015-04-17 15:35 ` [PATCHSET] printk, netconsole: implement reliable netconsole Tetsuo Handa
2015-04-17 16:28   ` Tejun Heo
2015-04-17 17:17     ` David Miller
2015-04-17 17:37       ` Tejun Heo
2015-04-17 17:43         ` Tetsuo Handa
2015-04-17 17:45           ` Tejun Heo
2015-04-17 18:03             ` Tetsuo Handa
2015-04-17 18:07               ` Tejun Heo
2015-04-17 18:20                 ` Tetsuo Handa
2015-04-17 18:26                   ` Tejun Heo
2015-04-18 13:09                     ` Tetsuo Handa
2015-04-17 18:04         ` Tejun Heo
2015-04-17 18:55         ` David Miller
2015-04-17 19:52           ` Tejun Heo
2015-04-17 20:06             ` David Miller
2015-04-21 21:51       ` Stephen Hemminger
2015-04-19  7:25 ` Rob Landley
2015-04-20 12:00   ` David Laight
2015-04-20 14:33   ` Tejun Heo

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=1429225433-11946-6-git-send-email-tj@kernel.org \
    --to=tj@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=davem@davemloft.net \
    --cc=kay@vrfy.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pmladek@suse.cz \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).