|
|
Subscribe / Log in / New account

The perils of pr_info()

By Jonathan Corbet
March 21, 2012
In the beginning there was printk() - literally: the 0.01 kernel release included 44 printk() calls. Since then, printk() has picked up details like logging levels and a lot of new formatting operators; it has also expanded to tens of thousands of call sites throughout the kernel. Developers often reach for it as the first way to figure out what is going on inside a misbehaving subsystem. If some developers have their way, though, printk() calls will become an endangered species. But not everybody has signed on to that goal.

There are certainly plenty of ways in which printk() could be improved. It imposes no standardization on messages, either across a subsystem or over time. As a result, messages can be hard for programs (or people) to parse, and they can change in trivial but obnoxious ways from one kernel release to the next. The actual calls, starting with text like:

    printk(KERN_ERR ...

are relatively verbose; among other things, that often causes printk() statements to run afoul of the 80-column line width restriction. Messages printed with printk() may also lack important information needed to determine what the kernel is really trying to say.

Various attempts have been made to improve on printk() over the years. Arguably the most successful of those is the set of functions defined for device drivers:

    int dev_dbg(struct device *dev, const char *format, ...);
    int dev_info(struct device *dev, const char *format, ...);
    int dev_notice(struct device *dev, const char *format, ...);
    /* ... */
    int dev_emerg(struct device *dev, const char *format, ...);

These functions, by embedding the logging level in the name itself, are more concise than the printk() calls they replace. They also print the name of the relevant device in standard form, ensuring that it's always possible to associate a message with the device that generated it. Use of these functions is not universal in device drivers, but it is widespread and uncontroversial.

There is a rather lower level of consensus surrounding a different set of functions (macros, really) that look like this:

    int pr_info(const char *format, ...);
    /* ... */
    int pr_emerg(const char *format, ...);

These functions, too, encode the logging level in the function name, making things more concise. They also attempt to at least minimally standardize the format of logging by passing the format string through a macro called pr_fmt(). That leads to a line like this appearing in several hundred source files in the kernel:

    #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

Due to the way the macro works, this line must appear before the #include block that would otherwise be at the beginning of the file. Defining pr_fmt() in this way causes all strings printed from the file to have the module name prepended; many subsystems use a literal string rather than the module name, but the intent is the same.

The spread of pr_*() through the kernel is mainly the result of an ongoing campaign by Joe Perches - notable for having just merged a 100,000-line whitespace-only ISDN subsystem cleanup patch for 3.4 - who has converted thousands of printk() calls over the years. To some developers, these changes are a welcome cleaning-up of the code; to others, they represent pointless code churn. The discussion has been quiet for a while, but it recently came back when Joe tried to convert the ext4 filesystem; ext4 maintainer Ted Ts'o rejected the conversion, saying:

Changing printk's to pr_info and pr_cont is patch noise as far as I'm concerned. Adds no value, and just breaks other patches

David Miller commented on this decision in a rather unsympathetic fashion:

Some kernel maintainers are real blockheads about code cleanups. And being like that doesn't make you look established and sophisticated, instead it makes you look like what you actually are, a relic.

Ted probably does not feel like a relic, and he is probably not trying to be sophisticated; he is almost certainly trying to maintain code he is responsible for in the best way he can. In his view, changing a bunch of code from one print function to another - possibly introducing a lot of patch conflicts on the way - does not help in that regard. Beyond that, he said, the standardization introduced by these functions is nowhere near enough to solve the structured logging problem, meaning that, someday, all those calls will have to be changed yet another time when a proper solution is available.

Proponents of the change argue that some structure is better than none, and that the new functions offer some useful flexibility when the time to add more structure comes. They claim that the overall size of the kernel is reduced (slightly) due to better sharing of strings. Messages printed with pr_debug() can be enabled and disabled with the dynamic debugging interface, while straight printk() calls cannot. And, perhaps most of all, they argue that consistency across the code base has value - though that argument was heard rather less when the pr_*() interface was new and relatively unused.

Needless to say, this is not the kind of discussion that comes to any sort of definitive conclusion. With regard to ext4, the conversion will probably not take place anytime soon; that is Ted's turf, and it is unlikely that anybody can summon arguments strong enough to convince Linus to override him. Elsewhere in the kernel, though, these conversions will certainly continue. As will, undoubtedly, the associated flame wars.

Index entries for this article
Kernelprintk()


to post comments

The pr_*() macros versus dynamic debug

Posted Mar 22, 2012 11:43 UTC (Thu) by abacus (guest, #49001) [Link] (1 responses)

I think it's worth mentioning here that printk(KERN_DEBUG ...) statements are always enabled while when using pr_dbg() one gets dynamic debug support for free.

The pr_*() macros versus dynamic debug

Posted Mar 22, 2012 13:26 UTC (Thu) by corbet (editor, #1) [Link]

In fact, it's so worth mentioning that I did mention it in the article...:) Except that I mentioned it with regard to pr_debug(), which is the actual name of the macro.

The perils of pr_info()

Posted Mar 22, 2012 12:32 UTC (Thu) by slashdot (guest, #22014) [Link] (5 responses)

If it is decided that this is worthwhile, just convert the whole tree with a script and deprecate printk.

What's the point of just converting specific subsystems like ext4?

The perils of pr_info()

Posted Mar 22, 2012 13:46 UTC (Thu) by dlang (guest, #313) [Link] (4 responses)

Jon is going though the entire tree and making the changes, but the changes then get sent to the appropriate maintainer to be accepted. When he got around to the ext* tree, Ted gave an emphatic NAK to the pf_info() patches, while accepting and expressing appreciation for some of the other patches Jon provided.

The perils of pr_info()

Posted Mar 22, 2012 17:54 UTC (Thu) by liljencrantz (guest, #28458) [Link] (2 responses)

Jon == Joe in this case, right? (Honest question, not trying to be a wise ass)

The perils of pr_info()

Posted Mar 22, 2012 18:02 UTC (Thu) by dlang (guest, #313) [Link] (1 responses)

oops, yes. I was thinking Jow, but my fingers typed Jon :-(

The perils of pr_info()

Posted Mar 23, 2012 11:47 UTC (Fri) by vonbrand (guest, #4458) [Link]

You've got a serious curly fingers problem there ;-)

The perils of pr_info()

Posted Mar 24, 2012 4:24 UTC (Sat) by jzbiciak (guest, #5246) [Link]

I can kinda see the bind something like ext4 is in, since the change smacks a little of a "flag day" for "how ext4 prints messages from the kernel". Any bugfix or stability patch made to ext4 after the printk->pr_XXX change will be that much harder to backport those changes to a kernel that existed before that "flag day".

That said, once the pr_XXX functions have been in release kernels long enough that the oldest relevant 'stable' release has them (what's that, about a year? year and a half?), then it seems like you can incrementally start folding the pr_XXX changes in, file by file. Then a backport will convert some fraction of printk calls relatively painlessly, it seems. Either that, or you could execute a much less exciting 'flag day' patch on ext4 to convert printk to the newer forms, and make it a prereq for any further bugfixes/improvements. Because all the relevant back-port targets will have pr_XXX, at least it'll be mostly painless.

Right now, though, am I wrong in thinking that the printk->pr_XXX changes make it just that bit more difficult to migrate patches to older, pre-change kernels, as long as the patch overlaps one of these conversions?

The perils of pr_info()

Posted May 2, 2020 22:30 UTC (Sat) by gdynamics (guest, #138572) [Link] (2 responses)

"Due to the way the macro works, this line must appear before the #include block that would otherwise be at the beginning of the file. Defining pr_fmt() in this way causes all strings printed from the file to have the module name prepended; many subsystems use a literal string rather than the module name, but the intent is the same."

I do not think this is true.

------------------------------------------------------------------------------------------------------------------------------------------------------
#include <linux/module.h>
#include <linux/init.h>

#define pr_fmt(fmt) KBUILD_MODNAME " -> %s:%d -> " fmt,__func__,__LINE__
------------------------------------------------------------------------------------------------------------------------------------------------------

This works for me in the LKM that I am writing while following a course. I could be mistaken on my interpretation of what was said, though.

This aside, I do appreciate the rest of the piece!

The perils of pr_info()

Posted May 2, 2020 22:32 UTC (Sat) by corbet (editor, #1) [Link] (1 responses)

Bear in mind that you're responding to an article that was written over eight years ago. A lot can change in eight years of kernel development!

The perils of pr_info()

Posted May 5, 2020 0:31 UTC (Tue) by gdynamics (guest, #138572) [Link]

True!

It also seems that while this is does technically work, it does give a small warning about overwriting a previously defined pr_fmt.


Copyright © 2012, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy