lkml.org 
[lkml]   [2003]   [Apr]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch] printk subsystems

    Hello,

    In an effort to get greater control over which printk()'s are logged
    during boot and after, I've put together this patch that introduces the
    concept of printk subsystems. The problem that some are beginning to
    face with larger machines is that certain subsystems are overly verbose
    (SCSI, USB, cpu related messages on large NUMA or SMP machines)
    and they overflow the buffer. Making the logbuffer bigger is a stop gap
    solution but I think this is a more elegant solution.

    Basically, each printk is assigned to a subsystem and that subsystem has
    the same set of values that the console_printk array has. The
    difference is that the console_printk loglevel decides if the message
    goes to the console whereas the subsystem loglevel decides if that
    message goes to the log at all.

    This patch implements the core, but I haven't yet put in the facilities
    to change the default values that are used at compile-time. I'm looking
    for opinions on the architecture, not the completeness. I plan to add
    configuration through sysctl.

    To use the feature you simply add the subsystem identifier to the printk
    call, much the same way that you add the priority tag:

    printk(PRINTK_NET KERN_INFO "This is a printk from the net subsys\n");

    Each subsystem has a default KERN_* priority, and if no subsystem is
    given then the printk is put into the PRINTK_UNASS queue (which is setup
    by default to log all messages).

    The patch is against 2.5.66.

    Opinions and comments welcome
    mh

    --
    Martin Hicks || mort@bork.org || PGP/GnuPG: 0x4C7F2BEE
    plato up 6 days, 6:33, 14 users, load average: 0.09, 0.11, 0.09
    Beer: So much more than just a breakfast drink.



    diff -X /home/mort/diff-exclude -uEr linux-2.5.66.pristine/include/linux/kernel.h linux-2.5.66/include/linux/kernel.h
    --- linux-2.5.66.pristine/include/linux/kernel.h 2003-03-17 16:43:37.000000000 -0500
    +++ linux-2.5.66/include/linux/kernel.h 2003-04-07 14:33:05.000000000 -0400
    @@ -47,6 +47,18 @@
    #define minimum_console_loglevel (console_printk[2])
    #define default_console_loglevel (console_printk[3])

    +/* Printk subsystem identifiers */
    +#define PRINTK_UNASS "<A>" /* unassigned printk subsystem */
    +#define PRINTK_CORE "<B>" /* from the core kernel */
    +#define PRINTK_SCSI "<C>" /* from the SCSI subsystem */
    +#define PRINTK_NET "<D>" /* from the Net subsystem */
    +#define PRINTK_USB "<E>" /* from the USB subsystem */
    +
    +#define FIRST_PRINTK_SUBSYS PRINTK_UNASS[1]
    +#define LAST_PRINTK_SUBSYS PRINTK_USB[1]
    +
    +extern int printk_subsystem[5][4];
    +
    struct completion;

    #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
    @@ -102,6 +114,62 @@
    console_loglevel = 15;
    }

    +static inline int decode_subsys(char *subsys)
    +{
    + if (subsys[1] >= FIRST_PRINTK_SUBSYS &&
    + subsys[1] <= LAST_PRINTK_SUBSYS)
    + return subsys[1] - FIRST_PRINTK_SUBSYS;
    + return -1;
    +}
    +
    +/* returns the log threshold for a given subsystem. -1 on error. */
    +static inline int get_subsys_loglevel(char *subsys)
    +{
    + int index;
    + if ((index = decode_subsys(subsys)) != -1)
    + return printk_subsystem[index][0];
    + return -1;
    +}
    +
    +/* sets the log threshold for a given subsystem.
    + * returns 0 if everything is okay, -1 if an error is encoutered. */
    +static inline int set_subsys_loglevel(char *subsys, int level)
    +{
    + int index;
    + if (level < 0 || level > 8)
    + return -1;
    + if ((index = decode_subsys(subsys)) != -1) {
    + if (level < printk_subsystem[index][2])
    + level = printk_subsystem[index][3];
    + printk_subsystem[index][0] = level;
    + return 0;
    + }
    + return -1;
    +}
    +
    +/* returns the default message level for a given subsystem. -1 on error */
    +static inline int get_subsys_msglevel(char *subsys)
    +{
    + int index;
    + if ((index = decode_subsys(subsys)) != -1)
    + return printk_subsystem[index][1];
    + return -1;
    +}
    +
    +/* sets the default message level for a given subsystem.
    + * return 0 if everything is okay, - 1 if an error is encountered */
    +static inline int set_subsys_msglevel(char *subsys, int level)
    +{
    + int index;
    + if (level < 0 || level > 7)
    + return -1;
    + if ((index = decode_subsys(subsys)) != -1) {
    + printk_subsystem[index][1] = level;
    + return 0;
    + }
    + return -1;
    +}
    +
    extern void bust_spinlocks(int yes);
    extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in progress */

    Only in linux-2.5.66.pristine/include/sound: pcm_sgbuf.h
    diff -X /home/mort/diff-exclude -uEr linux-2.5.66.pristine/kernel/printk.c linux-2.5.66/kernel/printk.c
    --- linux-2.5.66.pristine/kernel/printk.c 2003-03-17 16:44:50.000000000 -0500
    +++ linux-2.5.66/kernel/printk.c 2003-04-07 14:54:33.356776808 -0400
    @@ -42,6 +42,9 @@
    #define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */
    #define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */

    +#define MINIMUM_SUBSYS_LOGLEVEL 1
    +#define DEFAULT_SUBSYS_LOGLEVEL 8
    +
    DECLARE_WAIT_QUEUE_HEAD(log_wait);

    int console_printk[4] = {
    @@ -51,6 +54,18 @@
    DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */
    };

    +int printk_subsystem[5][4] = { /* [][0] == subsystem log level
    + * [][1] == default message loglevel
    + * [][2] == minimum subsystem loglevel
    + * [][3] == default subsystem loglevel */
    + [0 ... 4] = {
    + DEFAULT_SUBSYS_LOGLEVEL,
    + DEFAULT_MESSAGE_LOGLEVEL,
    + MINIMUM_SUBSYS_LOGLEVEL,
    + DEFAULT_SUBSYS_LOGLEVEL
    + }
    +};
    +
    int oops_in_progress;

    /*
    @@ -390,10 +405,11 @@
    {
    va_list args;
    unsigned long flags;
    - int printed_len;
    + int printed_len, msg_log_level, msg_subsystem, i;
    char *p;
    static char printk_buf[1024];
    - static int log_level_unknown = 1;
    + static int begin_message = 1;
    +

    if (oops_in_progress) {
    /* If a crash is occurring, make sure we can't deadlock */
    @@ -409,23 +425,44 @@
    va_start(args, fmt);
    printed_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
    va_end(args);
    -
    +
    /*
    - * Copy the output into log_buf. If the caller didn't provide
    - * appropriate log level tags, we insert them here
    + * Copy the output into log_buf.
    */
    - for (p = printk_buf; *p; p++) {
    - if (log_level_unknown) {
    - if (p[0] != '<' || p[1] < '0' || p[1] > '7' || p[2] != '>') {
    + p = printk_buf;
    + while (*p) {
    + if (begin_message) {
    + /* Figure out if there is zero, one or two flags */
    + msg_log_level = -1;
    + msg_subsystem = 0; /* A - Unassigned */
    + for (i = 0; i < 2; i++) {
    + if (p[0] == '<' && p[2] == '>') {
    + if (p[1] >= '0' && p[1] <= '7')
    + msg_log_level = p[1] - '0';
    + if (p[1] >= 'A' && p[1] <= 'G')
    + msg_subsystem = p[1] - 'A';
    + } else
    + break;
    + p+=3;
    + }
    +
    + /* Decide if we print this message at all */
    + if (msg_log_level == -1)
    + msg_log_level = printk_subsystem[msg_subsystem][1];
    +
    + if (msg_log_level < printk_subsystem[msg_subsystem][0]) {
    + begin_message = 0;
    emit_log_char('<');
    - emit_log_char(default_message_loglevel + '0');
    + emit_log_char(msg_log_level + '0');
    emit_log_char('>');
    + } else { // Get out of this loop. Don't log anything.
    + break;
    }
    - log_level_unknown = 0;
    }
    emit_log_char(*p);
    if (*p == '\n')
    - log_level_unknown = 1;
    + begin_message = 1;
    + p++;
    }

    if (!cpu_online(smp_processor_id())) {
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2005-03-22 13:34    [W:0.036 / U:207.912 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site