Can save the space that the KERN_<LEVEL> headers require.

The biggest negative here is the %pV use which needs
recursion and adds stack depth.

$ size vmlinux.o* (defconfig, x86-64)
   text     data     bss      dec     hex  filename
12586135  1909841  777528 15273504  e90e20 vmlinux.o.new
12590348  1909841  777528 15277717  e91e95 vmlinux.o.old

Signed-off-by: Joe Perches <j...@perches.com>
---
 include/linux/printk.h | 57 ++++++++++++++++++++++++++++++++++++--------------
 kernel/printk/printk.c | 28 +++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 16 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index 3c635b610bdc..0e912e393ed5 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -171,6 +171,28 @@ int printk_emit(int facility, int level,
 asmlinkage __printf(1, 2) __cold
 int printk(const char *fmt, ...);
 
+asmlinkage __printf(1, 2) __cold
+int __pr_emerg(const char *fmt, ...);
+asmlinkage __printf(1, 2) __cold
+int __pr_alert(const char *fmt, ...);
+asmlinkage __printf(1, 2) __cold
+int __pr_crit(const char *fmt, ...);
+asmlinkage __printf(1, 2) __cold
+int __pr_err(const char *fmt, ...);
+asmlinkage __printf(1, 2) __cold
+int __pr_warn(const char *fmt, ...);
+asmlinkage __printf(1, 2) __cold
+int __pr_notice(const char *fmt, ...);
+asmlinkage __printf(1, 2) __cold
+int __pr_info(const char *fmt, ...);
+/*
+ * Like KERN_CONT, pr_cont() should only be used when continuing
+ * a line with no newline ('\n') enclosed. Otherwise it defaults
+ * back to KERN_DEFAULT.
+ */
+asmlinkage __printf(1, 2) __cold
+int pr_cont(const char *fmt, ...);
+
 /*
  * Special printk facility for scheduler/timekeeping use only, _DO_NOT_USE_ !
  */
@@ -217,6 +239,15 @@ int printk(const char *s, ...)
 {
        return 0;
 }
+#define __pr_emerg     printk
+#define __pr_alert     printk
+#define __pr_crit      printk
+#define __pr_err       printk
+#define __pr_warn      printk
+#define __pr_notice    printk
+#define __pr_info      printk
+#define pr_cont                printk
+
 static inline __printf(1, 2) __cold
 int printk_deferred(const char *s, ...)
 {
@@ -292,27 +323,21 @@ extern asmlinkage void dump_stack(void) __cold;
  * or CONFIG_DYNAMIC_DEBUG is set.
  */
 #define pr_emerg(fmt, ...) \
-       printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
+       __pr_emerg(pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_alert(fmt, ...) \
-       printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
+       __pr_alert(pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_crit(fmt, ...) \
-       printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
+       __pr_crit(pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_err(fmt, ...) \
-       printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_warning(fmt, ...) \
-       printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_warn pr_warning
+       __pr_err(pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_warn(fmt, ...) \
+       __pr_warn(pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_notice(fmt, ...) \
-       printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
+       __pr_notice(pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_info(fmt, ...) \
-       printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
-/*
- * Like KERN_CONT, pr_cont() should only be used when continuing
- * a line with no newline ('\n') enclosed. Otherwise it defaults
- * back to KERN_DEFAULT.
- */
-#define pr_cont(fmt, ...) \
-       printk(KERN_CONT fmt, ##__VA_ARGS__)
+       __pr_info(pr_fmt(fmt), ##__VA_ARGS__)
+
+#define pr_warning pr_warn
 
 /* pr_devel() should produce zero code unless DEBUG is defined */
 #ifdef DEBUG
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 34da86e73d00..8d3d93f27921 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1843,6 +1843,34 @@ asmlinkage __visible int printk(const char *fmt, ...)
 }
 EXPORT_SYMBOL(printk);
 
+#define define_pr_func(func, level)                    \
+asmlinkage __visible int func(const char *fmt, ...)    \
+{                                                      \
+       va_list args;                                   \
+       int r;                                          \
+       struct va_format vaf;                           \
+                                                       \
+       va_start(args, fmt);                            \
+       vaf.fmt = fmt;                                  \
+       vaf.va = &args;                                 \
+                                                       \
+       r = printk(level "%pV", &vaf);                  \
+                                                       \
+       va_end(args);                                   \
+                                                       \
+       return r;                                       \
+}                                                      \
+EXPORT_SYMBOL(func)
+
+define_pr_func(__pr_emerg,     KERN_EMERG);
+define_pr_func(__pr_alert,     KERN_ALERT);
+define_pr_func(__pr_crit,      KERN_CRIT);
+define_pr_func(__pr_err,       KERN_ERR);
+define_pr_func(__pr_warn,      KERN_WARNING);
+define_pr_func(__pr_notice,    KERN_NOTICE);
+define_pr_func(__pr_info,      KERN_INFO);
+define_pr_func(pr_cont,                KERN_CONT);
+
 #else /* CONFIG_PRINTK */
 
 #define LOG_LINE_MAX           0
-- 
2.10.0.rc2.1.g053435c

Reply via email to