Are you aware of any subsystem having some extra post_fmt, please?
Well, the main question is whether we need to store this
at all. Does it bring any useful information?
Note that we do not store the value defined by pr_fmt() which
is yet another automatically added prefix.
I would personally omit these prefixes. The most important
information is:
+ fmt: is the pattern that the system monitors would most likely
look for.
+ level: says whether the string will appear on console that
shows only messages below a certain console_loglevel
+ func, file, line: help to find the string in the kernel sources.
It is useful when investigating what has changed.
For example, pre_fmt="%s %s:" used by dev_printk (4th patch)
is not much useful.
+} __packed;
+
+#define __printk_index_emit(_fmt, _level, _pre_fmt, _post_fmt) \
+ ({ \
+ if (__builtin_constant_p(_fmt) && __builtin_constant_p(_level)) { \
+ /*
+ * The compiler may not be able to eliminate the
+ * non-constant variants of _fmt and _level, so we need
+ * to make sure that it doesn't see any hypothetical
+ * assignment for non-constants even though this is
+ * already inside the __builtin_constant_p guard.
+ */ \
+ static const struct pi_entry _entry \
+ __used = { \
+ .fmt = __builtin_constant_p(_fmt) ? (_fmt) : NULL, \
+ .func = __func__, \
+ .file = __FILE__, \
+ .line = __LINE__, \
+ .level = __builtin_constant_p(_level) ? (_level) : NULL, \
+ .pre_fmt = _pre_fmt, \
Should this also be?
.pre_fmt = __builtin_constant_p(_pre_fmt) ? _pre_fmt : NULL
+ * pre and post must be known at compile time, or compilation will fail (since
+ * this is a mistake). If fmt or level is not known at compile time, no index
+ * entry will be made (since this can legitimately happen).
How is this achieved, please?
__printk_index_emit() creates the entry when the following check is true:
if (__builtin_constant_p(_fmt) && __builtin_constant_p(_level))
It checks neither _pre_fmt nor _post_fmt.
+ if (!entry->fmt)
+ return 0;
Is this just a paranoid check or is it a valid case?
Is is possible to update __printk_index_emit() to do not create
entries with fmt = NULL ?
We should either remove the above check or add a comment
explaining why it is necessary.
+
+ if (entry->level)
+ printk_parse_prefix(entry->level, &level, &flags);
+ else
+ prefix_len = printk_parse_prefix(entry->fmt, &level, &flags);
This is missing:
if (level == LOGLEVEL_DEFAULT)
level = default_message_loglevel;
Without it, it produces lines with loglevel <-1>, for example:
<-1> init/do_mounts.c:457 mount_block_root "\n"
<-1> init/do_mounts.c:456 mount_block_root " %s"
<-1> init/do_mounts.c:454 mount_block_root "No filesystem could mount root, tried: "
+
+ seq_printf(s, "<%d%s> %s:%d %s \"",
+ level, flags & LOG_CONT ? ",c" : "", entry->file,
+ entry->line, entry->func);
It produces the following for continuous lines:
<-1,c> arch/x86/events/core.c:2101 init_hw_perf_events "%s PMU driver.\n"
<-1,c> arch/x86/events/core.c:2091 init_hw_perf_events "no PMU driver, software events only.\n"
But we should print the loglevel only when explicitly defined.
So I would do it the following way:
if (flags & LOG_CONT) {
if (level == LOGLEVEL_DEFAULT)
seq_printf(s, "<c>");
else
seq_printf(s, "<%d,c>", level);
} else {
if (level == LOGLEVEL_DEFAULT)
level = default_message_loglevel;
seq_printf(s, "<%d>", level);
}
seq_printf(s, " %s:%d %s \"", entry->file, entry->line, entry->func);
I am really happy with the progress. The remaining problems are mostly
with the support for the subsystem-specific printk() callers that was
added in this revision.