|
|
Subscribe / Log in / New account

printk() and KERN_CONT

By Jake Edge
August 30, 2017

A nearly year-old "fix" to the main logging function used in the kernel, printk(), changed the appearance of some log messages in an unexpected way, at least for some. Messages that had appeared on a single line will now be spread over multiple lines as each call to printk() begins a new line in the output unless the KERN_CONT flag is used. That is how a comment in the kernel code says it should work, but the change was made by Linus Torvalds without any discussion or fanfare, so it took some by surprise.

The printk() function is the workhorse of kernel output, for critical messages, warnings, information, and debugging. It is used in much the same way as printf() but there are some differences. For one thing, "log levels" can be prepended to the format string to specify the severity of the message. These range from KERN_EMERG to KERN_DEBUG and can be used as follows:

    printk(KERN_ALERT "CPU on fire: %d\n", cpu_num);
The log levels are simply strings that get concatenated with the format string, thus there is no comma between them. Another difference from printf() is in how a format string without a newline is treated, which is what has changed. The KERN_CONT "log level" is meant to indicate a continuation line; a printk() that lacks that flag is supposed to start a new line in the log—though that hasn't always been enforced.

Pavel Machek posted a query about that behavior on August 28. He noted that "printk("foo"); printk("bar"); seems to produce foo\nbar", which was both surprising and unwelcome. That led to a bit of a rant from Torvalds, who had made the change:

If you want to continue a line, you NEED to use KERN_CONT.

That has always been true. It hasn't always been enforced, though.

If you do two printk's and the second one doesn't say "I'm a continuation", the printk logic assumes you're just confused and wanted two lines.

But, as several pointed out, that behavior only changed relatively recently (for the 4.9 kernel released in December 2016); prior to that Machek's example would produce "foobar" as he expected. Lots of places in the kernel use printk() without KERN_CONT and expect to get output on a single line, Joe Perches pointed out. Perches also complained that Torvalds had, in fact, changed longstanding behavior and was not just enforcing something that had "always been true". But Torvalds pointed to a commit from 2007 that added the KERN_CONT flag, along with the following comment:

    /*
     * Annotation for a "continued" line of log printout (only done after a
     * line that had no enclosing \n). Only to be used by core/arch code
     * during early bootup (a continued line is not SMP-safe otherwise).
     */

While 2007 is not exactly "always", the comment certainly documents the intent of KERN_CONT, so not using it and expecting multiple calls to printk() to end up on the same line has not been right for nearly ten years. Torvalds was unapologetic about this recent change:

So yes, we're enforcing it now, and we're not going back to the unenforced times, because a decade of shit has shown that people didn't do it without being forced to.

In fact, he would like to get rid of the whole idea of continuation lines. They made some amount of sense when the output was just sent to a circular character buffer, he said, but printk() now has a log-based structure so continuation lines do not really work well in that environment. Beyond that, there is always the chance that some asynchronous action (e.g. an interrupt) outputs something that interferes with the single line of output. Instead, users should be marshaling their own output into single-line chunks and passing those to printk(), he said.

He went on to suggest that some helper functions be added to assist in places where that marshaling is needed. Users would provide their own buffer to these routines that would then call printk() when they have a full line.

That avoids the whole nasty issue with printk - printk wants to show stuff early (because _maybe_ it's critical) and printk wants to make log records with timestamps and loglevels. And printk has serious locking issues that are really nasty and fundamental.

That set off a discussion on various ways to implement what had been suggested. Various schemes to replace printk() with something "smarter" were batted down quickly by Torvalds. Steven Rostedt recommended using the kernel's seq_buf facility that is used for tracing and implementing /proc files. That idea seemed to gain traction among the other thread participants (including, crucially, Torvalds). So far, no patch set along those lines has been proposed, but it seems like a promising direction.

No matter what happens, there are going to be multiple changes to fix the output in places where KERN_CONT was not used but should have been. If the seq_buf interface is going to be used, it would make sense to do that directly, rather than add a bunch of KERN_CONT flags in various places. Once that is done, perhaps the existing uses of KERN_CONT could be tackled to get rid of as many of those as possible—leaving only those used at boot time as was originally planned.

Clearly Torvalds doesn't think twice about breaking things internal to the kernel in order to enforce something he sees as important. Doing so silently, though, as happened here, might not have been the best approach. Had there been discussion of the patch on the mailing list, it would at least have given folks a chance to realize what was up. That might have eliminated Machek's query and perhaps reduced Torvalds's blood pressure a bit.


Index entries for this article
KernelKernel messages
Kernelprintk()


to post comments

printk() and KERN_CONT

Posted Aug 31, 2017 7:17 UTC (Thu) by abelloni (subscriber, #89904) [Link]

I had déjà vu and I was wondering were I saw this. I was actually greatly reported in https://lwn.net/Articles/703110/. I guess Pavel needs an LWN subscription ;)

printk() and KERN_CONT

Posted Aug 31, 2017 11:45 UTC (Thu) by grawity (subscriber, #80596) [Link]

He's defending it now, but I remember when the new /dev/kmsg system got merged and broke implicit (non-KERN_CONT) continuations for the first time. Linus wasn't amused.

(Well, it's fine. As a userspace person, I'd much rather have /dev/kmsg with strict records than the old crusty interface with continuations...)

That will take some getting used to...

Posted Sep 4, 2017 15:49 UTC (Mon) by nettings (subscriber, #429) [Link] (7 responses)

Granted, it's widely accepted proper journalistic style, but having to mentally map arbitrary identifiers to values that actually make sense to the way I think about the kernel community is a strain on my wetware at times. If you have the same problem, and in the open source spirit, here's my cheat sheet: { torvalds: "linus", machek: "pavel"};
;)

That will take some getting used to...

Posted Sep 4, 2017 16:11 UTC (Mon) by rvfh (guest, #31018) [Link] (2 responses)

At LWN, I have always seen the name printed in full first (e.g. "Linus Torvalds"), then only the surname used (e.g. "Torvalds"). It is the case in this article.

That will take some getting used to...

Posted Sep 8, 2017 8:45 UTC (Fri) by Wol (subscriber, #4433) [Link]

No doubt because there are (afaik) several Linus involved in kernel development. I'm sure I've seen the odd post/message/article where they were both there at the same time ... :-)

And the same almost certainly holds true for other names!

Cheers,
Wol

That will take some getting used to...

Posted Sep 8, 2017 21:03 UTC (Fri) by nix (subscriber, #2304) [Link]

Nope! Jon uses first names everywhere, just like, er, everyone who's actually involved in kernel development. Using surnames is, as noted, weirdly distancing.

That will take some getting used to...

Posted Sep 10, 2017 8:24 UTC (Sun) by mcortese (guest, #52099) [Link] (3 responses)

It's not journalistic style, it's how we actually speak: you fully define the persons the first time you mention them, then you refer to them with a placeholder. "I met my younger brother at the pub. He was drinking a beer".

LWN's style is the same: full name and surname (and possibly role in the kernel community) at first mention, unadorned surname afterwards.

There's no need for your cheat sheet, if you don't remember who is who, all you have to do is go back some paragraphs.

That will take some getting used to...

Posted Sep 10, 2017 13:07 UTC (Sun) by nix (subscriber, #2304) [Link] (2 responses)

Alternatively, just using first names (the way people in non-insanely-formal workplaces actually do) would mean we wouldn't have to dash around in this ridiculous mapping chaos at all. I use first names and sometimes initials or self-chosen identifier handles to identify people ('rms', not 'Stallman'; 'Linus', not 'Torvalds'; 'mkp', not 'Petersen') simply because those are the identifiers by which they identify themselves to other people.

If these people were in the habit of introducing themselves to other people by their surname, using surnames as identifiers in news reporting might make sense. (For, e.g. political reporting, this is often true). But until Linus is is the habit of calling himself 'Torvalds' on the linux-kernel list, and other people call him that, I think it's the wrong identifier to use, and needlessly confusing. It seems rather disrespectful, too. Why call someone 'Machek' when he's made it clear in every post he makes that he wants to be called Pavel?

(This may be a generation-gap thing, too. A lifetime ago, perhaps before WWII and definitely before WWI, it was disrespectful to not call your elders and betters by their surnames whether or not they called each other by anything else, but in my view this has completely inverted by now.)

That will take some getting used to...

Posted Sep 11, 2017 7:02 UTC (Mon) by mcortese (guest, #52099) [Link] (1 responses)

I think you can't apply the same rules to the inner group of co-workers who have daily interactions and the broader audience of a newsletter. I've never thought of LWN as targeting the same people who is involved in the kernel development and is thus familiar with its jargon, nicknames, and abbreviations. In that restricted group it might be OK to use first names, as it's also OK to use well-known acronyms like BKL. For the rest of us, LWN provides a great service defining them on first use and applying a consistent scheme.

That will take some getting used to...

Posted Sep 11, 2017 11:52 UTC (Mon) by nix (subscriber, #2304) [Link]

I think it's mostly because Jon *is* in that restricted group (which is probably why he uses the style I'm familiar with).

(Also, you don't have to be *in* the inner group. That's the beauty of work in the open: you just have to read the same mailing lists!)


Copyright © 2017, 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