[RFC PATCH] printk: Make functions of pr_<level> macros

From: Joe Perches
Date: Tue Feb 28 2017 - 22:18:34 EST


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 <joe@xxxxxxxxxxx>
---
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