Re: [PATCH 04/16] printk: implement support for extended console drivers

2015-04-28 Thread Tejun Heo
Hello, Petr.

On Tue, Apr 28, 2015 at 11:42:44AM +0200, Petr Mladek wrote:
 Note that cont buffer is only a memory optimization. You could put
 every text snippet into the ring buffer and console immediately.
 You need to set LOG_CONT instead of LOG_NEWLINE flag. This is
 already used when the line is too long for the cont buffer or
 when there is printed a message from another cpu in the middle
 of a continuing message.

Yeah, hmmm, I wonder whether the right solution here is to bypass cont
buffer if ext_console is present.  This would use a bit more memory
and hurt users catting /proc/kmsg but everyone else should be able to
get the same result and things get a lot simpler on both sending and
receiving sides.  What do you think?

Thanks.

-- 
tejun
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/16] printk: implement support for extended console drivers

2015-04-28 Thread Petr Mladek
On Tue 2015-04-28 10:10:14, Tejun Heo wrote:
 Hello, Petr.
 
 On Tue, Apr 28, 2015 at 11:42:44AM +0200, Petr Mladek wrote:
  Note that cont buffer is only a memory optimization. You could put
  every text snippet into the ring buffer and console immediately.
  You need to set LOG_CONT instead of LOG_NEWLINE flag. This is
  already used when the line is too long for the cont buffer or
  when there is printed a message from another cpu in the middle
  of a continuing message.
 
 Yeah, hmmm, I wonder whether the right solution here is to bypass cont
 buffer if ext_console is present.  This would use a bit more memory
 and hurt users catting /proc/kmsg but everyone else should be able to
 get the same result and things get a lot simpler on both sending and
 receiving sides.  What do you think?

I would personally give it a try. If it works well, we might
eventually get rid of the cont buffer completely and make
the printk code a bit easier again.

Best Regards,
Petr
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/16] printk: implement support for extended console drivers

2015-04-28 Thread Petr Mladek
On Mon 2015-04-27 17:09:22, Tejun Heo wrote:
 Hello, Petr.
 
 Sorry about the delay.

np

 On Mon, Apr 20, 2015 at 05:43:07PM +0200, Petr Mladek wrote:
  I was afraid that there might be a potential buffer overflow because
  the user-provided dict need not be limited by '\0'. But LOG_DICT_META
  is used only with the internal data that are safe. We might document
  this as well.
  
  BTW: Do you want to print the internal dict when calling this function
  in devkmsg_read()?
 
 No, plesae see below.

I see, it is not printed there because the dict_len is zero for the
internal info.

   + scnprintf(fragid_buf, sizeof(fragid_buf),
   +   ,fragid=%llu, fragid);
   + return scnprintf(buf, size, %u,%llu,%llu,%c%s;,
   +  (msg-facility  3) | msg-level, seq, ts_usec, cont,
   +  fragid_buf);
  
  The above comment suggests that  cont and fragid_buf are delimited
  by a comma but it is not used here. Is it by intention.
 
 Hmm... how is it not?  The fragid printf has preceding comma.

I see it now.

   + dict_len = scnprintf(dict_buf, sizeof(dict_buf), FRAGID=%llu,
   +  cont.fragid);
   + log_store(cont.facility, cont.level,
   +   flags | LOG_NOCONS | LOG_DICT_META,
   +   cont.ts_nsec, dict_buf, dict_len, cont.buf, cont.len);
  
  I wonder if it would make sense to restart fragid here. Another line
  will get distinguished by seqnum.
 
 That'd assume that there can only ever be a single continuation
 buffer, which is true now but it's possible that we may want to make
 it per-cpu in the future.

I am not sure if any more complications will get accepted. Anyway,
each CPU should print an independent message. Therefore each pre-CPU
cont buffer would be printed on separate line and would get another
seqnum. We could have per-CPU fragid counter.


  Sigh, the whole mess is caused by the fact that we could not extend
  struct printk_log easily. It would be much better if we could put
  fragid there. I finally understand why you need to reuse the dict.
 
 I've been thinking about it and using dict area for internal metadata
 is indeed quite messy.  I think a better way to do it is declaring
 dict_len as a union w/ fragid.  This'd limit the fragid to 16bit but
 that should be more than enough and we can do away with the string
 formatting and reading back.

Nice idea. I like it much more.


  Another solution would be to allow to disable the continuous buffer
  via some boot option or /sys/kernel/debug entry if you want to debug
  such a problem and have problem with the partial flushing.

 It isn't really about debugging partial flushing itself but rather
 always being able to push out the messages before the printk
 invocation finishes.

I did not mean cont-buffer debugging. I meant debugging with
netconsole.

Note that cont buffer is only a memory optimization. You could put
every text snippet into the ring buffer and console immediately.
You need to set LOG_CONT instead of LOG_NEWLINE flag. This is
already used when the line is too long for the cont buffer or
when there is printed a message from another cpu in the middle
of a continuing message.


Best Regards,
Petr
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/16] printk: implement support for extended console drivers

2015-04-27 Thread Tejun Heo
Hello, Petr.

Sorry about the delay.

On Mon, Apr 20, 2015 at 05:43:07PM +0200, Petr Mladek wrote:
...
  * Extended message formatting for console drivers is enabled iff there
 
 s/iff/if/

if and only if

 I was afraid that there might be a potential buffer overflow because
 the user-provided dict need not be limited by '\0'. But LOG_DICT_META
 is used only with the internal data that are safe. We might document
 this as well.
 
 BTW: Do you want to print the internal dict when calling this function
 in devkmsg_read()?

No, plesae see below.

  +   scnprintf(fragid_buf, sizeof(fragid_buf),
  + ,fragid=%llu, fragid);
  +   return scnprintf(buf, size, %u,%llu,%llu,%c%s;,
  +(msg-facility  3) | msg-level, seq, ts_usec, cont,
  +fragid_buf);
 
 The above comment suggests that  cont and fragid_buf are delimited
 by a comma but it is not used here. Is it by intention.

Hmm... how is it not?  The fragid printf has preceding comma.

  +   dict_len = scnprintf(dict_buf, sizeof(dict_buf), FRAGID=%llu,
  +cont.fragid);
  +   log_store(cont.facility, cont.level,
  + flags | LOG_NOCONS | LOG_DICT_META,
  + cont.ts_nsec, dict_buf, dict_len, cont.buf, cont.len);
 
 I wonder if it would make sense to restart fragid here. Another line
 will get distinguished by seqnum.

That'd assume that there can only ever be a single continuation
buffer, which is true now but it's possible that we may want to make
it per-cpu in the future.

 Sigh, the whole mess is caused by the fact that we could not extend
 struct printk_log easily. It would be much better if we could put
 fragid there. I finally understand why you need to reuse the dict.

I've been thinking about it and using dict area for internal metadata
is indeed quite messy.  I think a better way to do it is declaring
dict_len as a union w/ fragid.  This'd limit the fragid to 16bit but
that should be more than enough and we can do away with the string
formatting and reading back.

 Another solution would be to allow to disable the continuous buffer
 via some boot option or /sys/kernel/debug entry if you want to debug
 such a problem and have problem with the partial flushing.

It isn't really about debugging partial flushing itself but rather
always being able to push out the messages before the printk
invocation finishes.

Thanks.

-- 
tejun
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/16] printk: implement support for extended console drivers

2015-04-21 Thread Petr Mladek
On Mon 2015-04-20 17:43:07, Petr Mladek wrote:
 On Thu 2015-04-16 19:03:41, Tejun Heo wrote:
  printk log_buf keeps various metadata for each message including its
  sequence number and timestamp.  The metadata is currently available
  only through /dev/kmsg and stripped out before passed onto console
  drivers.  We want this metadata to be available to console drivers
  too.  Immediately, it's to implement reliable netconsole but may be
  useful for other console devices too.
  
  This patch implements support for extended console drivers.  Consoles
  can indicate that they process extended messages by setting the new
  CON_EXTENDED flag and they'll fed messages formatted the same way as
  /dev/kmsg output as follows.
  
   level,sequnum,timestamp,contflag;message text
  
  One special case is fragments.  Message fragments are output
  immediately to consoles to avoid losing them in case of crashes.  For
  normal consoles, this is handled by later suppressing the assembled
  result and /dev/kmsg only shows fully assembled message; however,
  extended consoles would need both the fragments, to avoid losing
  message in case of a crash, and the assembled result, to tell how the
  fragments are assembled and which sequence number got assigned to it.
  
  To help matching up the fragments with the resulting message,
  fragments are emitted in the following format.
  
   level,-,timestamp,-,fragid=fragid;message fragment
  
  And later when the assembly is complete, the following is transmitted,
  
   level,sequnum,timestamp,contflag,fragid=fragid;message text
  
  * Extended message formatting for console drivers is enabled iff there

[...]

 Sigh, it adds another twist into the already complex printk code.
 
 Another solution would be to allow to disable the continuous buffer
 via some boot option or /sys/kernel/debug entry if you want to debug
 such a problem and have problem with the partial flushing.
 
 Hmm, I wonder what are the typical values passed via dict and if we
 need to handle this entry such a special way. It would make sense to
 always print dict values to the ext consoles and handle this as a
 yet another normal dict value. It would allow us to remove
 some hacks at least.

Another solution would be to always flush cont buffer when it is being
printed to the console. Then the messages might by distinguished by
the seqnum and fragid won't be needed. The question is if the cont
buffer will still have any affect after this change.

Best Regards,
Petr
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/16] printk: implement support for extended console drivers

2015-04-20 Thread Petr Mladek
On Thu 2015-04-16 19:03:41, Tejun Heo wrote:
 printk log_buf keeps various metadata for each message including its
 sequence number and timestamp.  The metadata is currently available
 only through /dev/kmsg and stripped out before passed onto console
 drivers.  We want this metadata to be available to console drivers
 too.  Immediately, it's to implement reliable netconsole but may be
 useful for other console devices too.
 
 This patch implements support for extended console drivers.  Consoles
 can indicate that they process extended messages by setting the new
 CON_EXTENDED flag and they'll fed messages formatted the same way as
 /dev/kmsg output as follows.
 
  level,sequnum,timestamp,contflag;message text
 
 One special case is fragments.  Message fragments are output
 immediately to consoles to avoid losing them in case of crashes.  For
 normal consoles, this is handled by later suppressing the assembled
 result and /dev/kmsg only shows fully assembled message; however,
 extended consoles would need both the fragments, to avoid losing
 message in case of a crash, and the assembled result, to tell how the
 fragments are assembled and which sequence number got assigned to it.
 
 To help matching up the fragments with the resulting message,
 fragments are emitted in the following format.
 
  level,-,timestamp,-,fragid=fragid;message fragment
 
 And later when the assembly is complete, the following is transmitted,
 
  level,sequnum,timestamp,contflag,fragid=fragid;message text
 
 * Extended message formatting for console drivers is enabled iff there
   ^^^

s/iff/if/

   are registered extended consoles.
 
 * Comment describing extended message formats updated to help
   distinguishing variable with verbatim terms.
 
 Signed-off-by: Tejun Heo t...@kernel.org
 Cc: Kay Sievers k...@vrfy.org
 Cc: Petr Mladek pmla...@suse.cz
 ---
  include/linux/console.h |   1 +
  kernel/printk/printk.c  | 141 
 +---
  2 files changed, 123 insertions(+), 19 deletions(-)
 
 diff --git a/include/linux/console.h b/include/linux/console.h
 index 7571a16..04bbd09 100644
 --- a/include/linux/console.h
 +++ b/include/linux/console.h
 @@ -115,6 +115,7 @@ static inline int con_debug_leave(void)
  #define CON_BOOT (8)
  #define CON_ANYTIME  (16) /* Safe to call when cpu is offline */
  #define CON_BRL  (32) /* Used for a braille device */
 +#define CON_EXTENDED (64) /* Use the extended output format a la /dev/kmsg */
  
  struct console {
   charname[16];
 diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
 index 0175c46..349a37b 100644
 --- a/kernel/printk/printk.c
 +++ b/kernel/printk/printk.c
 @@ -84,6 +84,8 @@ static struct lockdep_map console_lock_dep_map = {
  };
  #endif
  
 +static int nr_ext_console_drivers;
 +
  /*
   * Helper macros to handle lockdep when locking/unlocking console_sem. We use
   * macros instead of functions so that _RET_IP_ contains useful information.
 @@ -195,14 +197,28 @@ static int console_may_schedule;
   * need to be changed in the future, when the requirements change.
   *
   * /dev/kmsg exports the structured data in the following line format:
 - *   level,sequnum,timestamp;message text\n
 + *   level,sequnum,timestamp,contflag;message text\n
   *
   * The optional key/value pairs are attached as continuation lines starting
   * with a space character and terminated by a newline. All possible
   * non-prinatable characters are escaped in the \xff notation.
   *
   * Users of the export format should ignore possible additional values
 - * separated by ',', and find the message after the ';' character.
 + * separated by ',', and find the message after the ';' character. All
 + * optional header fields should have the form key=value.
 + *
 + * For consoles with CON_EXTENDED set, a message formatted like the
 + * following may also be printed. This is a continuation fragment which are
 + * being assembled and will be re-transmitted with a normal header once
 + * assembly finishes. The fragments are sent out immediately to avoid
 + * losing them over a crash.
 + *   level,-,timestamp,-,fragid=fragid;message fragment\n
 + *
 + * On completion of assembly, the following is transmitted.
 + *   level,sequnum,timestamp,contflag,fragid=fragid;message 
 text\n
 + *
 + * Extended consoles should identify and handle duplicates by matching the
 + * fragids of the fragments and assembled messages.
   */
  
  enum log_flags {
 @@ -210,6 +226,7 @@ enum log_flags {
   LOG_NEWLINE = 2,/* text ended with a newline */
   LOG_PREFIX  = 4,/* text started with a prefix */
   LOG_CONT= 8,/* text is a fragment of a continuation line */
 + LOG_DICT_META   = 16,   /* dict contains console meta information */
  };
  
  struct printk_log {
 @@ -292,6 +309,12 @@ static char *log_dict(const struct printk_log *msg)
   return (char *)msg + 

[PATCH 04/16] printk: implement support for extended console drivers

2015-04-16 Thread Tejun Heo
printk log_buf keeps various metadata for each message including its
sequence number and timestamp.  The metadata is currently available
only through /dev/kmsg and stripped out before passed onto console
drivers.  We want this metadata to be available to console drivers
too.  Immediately, it's to implement reliable netconsole but may be
useful for other console devices too.

This patch implements support for extended console drivers.  Consoles
can indicate that they process extended messages by setting the new
CON_EXTENDED flag and they'll fed messages formatted the same way as
/dev/kmsg output as follows.

 level,sequnum,timestamp,contflag;message text

One special case is fragments.  Message fragments are output
immediately to consoles to avoid losing them in case of crashes.  For
normal consoles, this is handled by later suppressing the assembled
result and /dev/kmsg only shows fully assembled message; however,
extended consoles would need both the fragments, to avoid losing
message in case of a crash, and the assembled result, to tell how the
fragments are assembled and which sequence number got assigned to it.

To help matching up the fragments with the resulting message,
fragments are emitted in the following format.

 level,-,timestamp,-,fragid=fragid;message fragment

And later when the assembly is complete, the following is transmitted,

 level,sequnum,timestamp,contflag,fragid=fragid;message text

* Extended message formatting for console drivers is enabled iff there
  are registered extended consoles.

* Comment describing extended message formats updated to help
  distinguishing variable with verbatim terms.

Signed-off-by: Tejun Heo t...@kernel.org
Cc: Kay Sievers k...@vrfy.org
Cc: Petr Mladek pmla...@suse.cz
---
 include/linux/console.h |   1 +
 kernel/printk/printk.c  | 141 +---
 2 files changed, 123 insertions(+), 19 deletions(-)

diff --git a/include/linux/console.h b/include/linux/console.h
index 7571a16..04bbd09 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -115,6 +115,7 @@ static inline int con_debug_leave(void)
 #define CON_BOOT   (8)
 #define CON_ANYTIME(16) /* Safe to call when cpu is offline */
 #define CON_BRL(32) /* Used for a braille device */
+#define CON_EXTENDED   (64) /* Use the extended output format a la /dev/kmsg */
 
 struct console {
charname[16];
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 0175c46..349a37b 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -84,6 +84,8 @@ static struct lockdep_map console_lock_dep_map = {
 };
 #endif
 
+static int nr_ext_console_drivers;
+
 /*
  * Helper macros to handle lockdep when locking/unlocking console_sem. We use
  * macros instead of functions so that _RET_IP_ contains useful information.
@@ -195,14 +197,28 @@ static int console_may_schedule;
  * need to be changed in the future, when the requirements change.
  *
  * /dev/kmsg exports the structured data in the following line format:
- *   level,sequnum,timestamp;message text\n
+ *   level,sequnum,timestamp,contflag;message text\n
  *
  * The optional key/value pairs are attached as continuation lines starting
  * with a space character and terminated by a newline. All possible
  * non-prinatable characters are escaped in the \xff notation.
  *
  * Users of the export format should ignore possible additional values
- * separated by ',', and find the message after the ';' character.
+ * separated by ',', and find the message after the ';' character. All
+ * optional header fields should have the form key=value.
+ *
+ * For consoles with CON_EXTENDED set, a message formatted like the
+ * following may also be printed. This is a continuation fragment which are
+ * being assembled and will be re-transmitted with a normal header once
+ * assembly finishes. The fragments are sent out immediately to avoid
+ * losing them over a crash.
+ *   level,-,timestamp,-,fragid=fragid;message fragment\n
+ *
+ * On completion of assembly, the following is transmitted.
+ *   level,sequnum,timestamp,contflag,fragid=fragid;message 
text\n
+ *
+ * Extended consoles should identify and handle duplicates by matching the
+ * fragids of the fragments and assembled messages.
  */
 
 enum log_flags {
@@ -210,6 +226,7 @@ enum log_flags {
LOG_NEWLINE = 2,/* text ended with a newline */
LOG_PREFIX  = 4,/* text started with a prefix */
LOG_CONT= 8,/* text is a fragment of a continuation line */
+   LOG_DICT_META   = 16,   /* dict contains console meta information */
 };
 
 struct printk_log {
@@ -292,6 +309,12 @@ static char *log_dict(const struct printk_log *msg)
return (char *)msg + sizeof(struct printk_log) + msg-text_len;
 }
 
+/* if LOG_DICT_META is set, the dict buffer carries printk internal info */
+static size_t log_dict_len(const struct printk_log *msg)
+{
+   return (msg-flags