Kernel messages are often assembled from numerical and text
fragments. Sending fragments via UDP often produces one line
per fragment on the other end. 

Example:

        Pseudo code:
                printk "a message: "
                ...
                printk "%d, " 1234
                ...
                printk "%x, %s\n" 0x5678  "blabla"

        Log buffer/dmesg (intended format):

                a message: 1234, 5678, blabla

        After sending via UDP:

                a message 
                1234, 
                5678, blabla

Fragmented messages are very hard to process automatically.

Changes by this patch  send messages every  line after buffering.

In practice it is also generally faster as network overhead
is incurred only once per line. 

This patch is in use since June with 2.6.11 to routine monitor 
a dozen systems. 


Signed-off-by: Michael Frank <[EMAIL PROTECTED]>

---

 netconsole.c |   59 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 50 insertions(+), 9 deletions(-)


Patch file: netc-buffer-mhfp17
--- linux-2.6.15-rc2-mhf260/drivers/net/netconsole.c.001        2005-11-21 
08:28:58.000000000 +0100
+++ linux-2.6.15-rc2-mhf260/drivers/net/netconsole.c    2005-11-21 
09:08:18.000000000 +0100
@@ -15,6 +15,7 @@
  *             generic card hooks
  *             works non-modular
  * 2003-09-07  rewritten with netpoll api
+ * 2005-06-13  Michael Frank <[EMAIL PROTECTED]> Send short messages every line
  */
 
 /******************************************************************************
@@ -50,10 +51,15 @@
 MODULE_DESCRIPTION("Console driver for network interfaces");
 MODULE_LICENSE("GPL");
 
-static char config[256];
-module_param_string(netconsole, config, 256, 0);
+#define MAX_LINE 256
+
+static char linebuf[MAX_LINE];
+module_param_string(netconsole, linebuf, MAX_LINE, 0);
 MODULE_PARM_DESC(netconsole, " [EMAIL 
PROTECTED]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]\n");
 
+static char *plinebuf = linebuf;
+static int nlinebuf;
+
 static struct netpoll np = {
        .name = "netconsole",
        .dev_name = "eth0",
@@ -68,6 +74,8 @@
 
 static void write_msg(struct console *con, const char *msg, unsigned int len)
 {
+       char c;
+       char *pmsg;
        int frag, left;
        unsigned long flags;
 
@@ -76,11 +84,44 @@
 
        local_irq_save(flags);
 
-       for (left = len; left;) {
-               frag = min(left, MAX_PRINT_CHUNK);
-               netpoll_send_udp(&np, msg, frag);
-               msg += frag;
-               left -= frag;
+       left = len;
+       pmsg = (char *)msg;
+
+       if (left + nlinebuf <= MAX_LINE) {
+               /* Kernel messages are often assembled from numerical and text
+                * fragments. Sending fragments via UDP often produces one line
+                * per fragment on the other end. Therefor, messages of length
+                * up to MAX_LINE are sent every line after buffering.
+                *
+                * In practice it is also generally faster as network overhead
+                * is incurred only once per line. 
+                */
+
+               while (left--) {
+                       c = *pmsg++;
+                       *plinebuf++ = c;
+                       nlinebuf++;
+                       if (c == '\n') {
+                               plinebuf = linebuf;
+                               netpoll_send_udp(&np, plinebuf, nlinebuf);
+                               nlinebuf = 0;
+                       }
+               }
+       } else {
+               /* Messages longer than MAX_LINE are sent by block for maximum
+                * throughput. The line buffer is flushed prior to sending
+                * a message longer than MAX_LINE.
+                */
+
+               if (nlinebuf) {
+                       plinebuf = linebuf;
+                       netpoll_send_udp(&np, plinebuf, nlinebuf);
+                       nlinebuf = 0;
+               }
+               for (; left; left -= frag, pmsg += frag) {
+                       frag = min(left, MAX_PRINT_CHUNK);
+                       netpoll_send_udp(&np, pmsg, frag);
+               }
        }
 
        local_irq_restore(flags);
@@ -101,8 +142,8 @@
 
 static int init_netconsole(void)
 {
-       if (strlen(config))
-               option_setup(config);
+       if (strlen(linebuf))
+               option_setup(linebuf);
 
        if (!configured) {
                printk("netconsole: not configured, aborting\n");
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to