Introduce and use printk pointer extension %pV
Subsystems (5)
cover Introduce and use printk pointer extension %pV
Recursive printk can reduce the total image size of an x86 defconfig about 1% by reducing duplicated KERN_<level> strings and centralizing the functions used by macros in new separate functions.
Joe Perches (4):
vsprintf: Recursive vsnprintf: Add "%pV", struct va_format device.h drivers/base/core.c Convert dev_<level> logging macros to functions netdevice.h net/core/dev.c: Convert netdev_<level> logging macros to functions netdevice.h: Change netif_<level> macros to call netdev_<level> functions
drivers/base/core.c | 64 +++++++++++++++++++++++++ include/linux/device.h | 112 ++++++++++++++++++++++++++++++++++---------- include/linux/kernel.h | 5 ++ include/linux/netdevice.h | 56 ++++++++++++---------- lib/vsprintf.c | 9 ++++ net/core/dev.c | 62 +++++++++++++++++++++++++ 6 files changed, 256 insertions(+), 52 deletions(-)
PATCH 1/4 vsprintf: Recursive vsnprintf: Add "%pV", struct va_format
Add the ability to print a format and va_list from a structure pointer
Allows __dev_printk to be implemented as a single printk while minimizing string space duplication.
%pV should not be used without some mechanism to verify the format and argument use ala __attribute__(format (printf(...))).
--- include/linux/kernel.h | 5 +++++ lib/vsprintf.c | 9 +++++++++ 2 files changed, 14 insertions(+), 0 deletions(-)
include/linux/kernel.h +5 -0
@@ -171,6 +171,11 @@ static inline void might_fault(void) }#endif +struct va_format { +const char *fmt; +va_list *va; +}; +extern struct atomic_notifier_head panic_notifier_list;extern long (*panic_blink)(long time); NORET_TYPE void panic(const char * fmt, ...)
lib/vsprintf.c +9 -0
@@ -980,6 +980,11 @@ char *uuid_string(char *buf, char *end, const u8 *addr,* [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15] * little endian output byte order is: * [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15] +* - 'V' For a struct va_format which contains a format string * and va_list *, +* call vsnprintf(->format, *->va_list). +* Implements a "recursive vsnprintf". +* Do not use this feature without some mechanism to verify the +* correctness of the format string and va_list arguments. * * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 * function pointers are really function descriptors, which contain a
@@ -1025,6 +1030,10 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,break ;case 'U' :return uuid_string (buf, end, ptr, spec, fmt); +case 'V' : +return buf +vsnprintf (buf, end - buf, + ((struct va_format *)ptr)->fmt, + *(((struct va_format *)ptr)->va)); } spec.flags |=SMALL ;if (spec.field_width ==-1 ) {
Signature · 1 line
1.7.1.337.g6068.dirty
PATCH 2/4 device.h drivers/base/core.c Convert dev_<level> logging macros to functions
In reply to Joe PerchesReduces an x86 defconfig text and data ~55k, .6% smaller.
$ size vmlinux* text data bss dec hex filename 7205273 716016 1366288 9287577 8db799 vmlinux 7258890 719768 1366288 9344946 8e97b2 vmlinux.master
Uses %pV and struct va_format
Format arguments are verified before printk
The dev_info macro is converted to _dev_info because there are existing uses of variables named dev_info in the kernel tree like drivers/net/pcmcia/pcnet_cs.c
A dev_info macro is created to call _dev_info
--- drivers/base/core.c | 64 +++++++++++++++++++++++++++ include/linux/device.h | 112 ++++++++++++++++++++++++++++++++++++----------- 2 files changed, 150 insertions(+), 26 deletions(-)
drivers/base/core.c +64 -0
@@ -1819,3 +1819,67 @@ void device_shutdown(void)spin_unlock (&devices_kset->list_lock);async_synchronize_full (); } + +/* +* Device logging functions +*/ + +#ifdef CONFIG_PRINTK + +static int __dev_printk (const char *level,const struct device *dev, +struct va_format *vaf) +{ +if (!dev) +return printk ("%s(NULL device *): %pV" , level, vaf); + +return printk ("%s%s %s: %pV" , + level,dev_driver_string (dev),dev_name (dev), vaf); +} + +int dev_printk (const char *level,const struct device *dev, +const char *fmt, ...) +{ +struct va_format vaf; +va_list args; +int r; + +va_start (args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + r =__dev_printk (level, dev, &vaf); +va_end (args); + +return r; +} +EXPORT_SYMBOL (dev_printk); + +#define define_dev_printk_level (func, kern_level) \ +int func(const struct device *dev, const char *fmt, ...) \ +{ \ + struct va_format vaf; \ + va_list args; \ + int r; \ + \ + va_start(args, fmt); \ + \ + vaf.fmt = fmt; \ + vaf.va = &args; \ + \ + r = __dev_printk(kern_level, dev, &vaf); \ + va_end(args); \ + \ + return r; \ +} \ +EXPORT_SYMBOL(func); + +define_dev_printk_level (dev_emerg,KERN_EMERG ); +define_dev_printk_level (dev_alert,KERN_ALERT ); +define_dev_printk_level (dev_crit,KERN_CRIT ); +define_dev_printk_level (dev_err,KERN_ERR ); +define_dev_printk_level (dev_warn,KERN_WARNING ); +define_dev_printk_level (dev_notice,KERN_NOTICE ); +define_dev_printk_level (_dev_info,KERN_INFO ); + +#endif
include/linux/device.h +86 -26
129 lines not on this page · raw message
Signature · 1 line
1.7.1.337.g6068.dirty
PATCH 3/4 netdevice.h net/core/dev.c: Convert netdev_<level> logging macros to functions
In reply to Joe PerchesReduces an x86 defconfig text and data ~2k.
text is smaller, data is larger.
$ size vmlinux* text data bss dec hex filename 7198862 720112 1366288 9285262 8dae8e vmlinux 7205273 716016 1366288 9287577 8db799 vmlinux.device_h
Uses %pV and struct va_format
Format arguments are verified before printk
--- include/linux/netdevice.h | 36 ++++++++++++------------- net/core/dev.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 19 deletions(-)
include/linux/netdevice.h +17 -19
@@ -2227,25 +2227,23 @@ static inline const char *netdev_name(const struct net_device *dev)return dev->name; } -#define netdev_printk(level, netdev, format, args...) \ - dev_printk(level, (netdev)->dev.parent, \ - "%s: " format, \ - netdev_name(netdev), ##args) - -#define netdev_emerg(dev, format, args...) \ - netdev_printk(KERN_EMERG, dev, format, ##args) -#define netdev_alert(dev, format, args...) \ - netdev_printk(KERN_ALERT, dev, format, ##args) -#define netdev_crit(dev, format, args...) \ - netdev_printk(KERN_CRIT, dev, format, ##args) -#define netdev_err(dev, format, args...) \ - netdev_printk(KERN_ERR, dev, format, ##args) -#define netdev_warn(dev, format, args...) \ - netdev_printk(KERN_WARNING, dev, format, ##args) -#define netdev_notice(dev, format, args...) \ - netdev_printk(KERN_NOTICE, dev, format, ##args) -#define netdev_info(dev, format, args...) \ - netdev_printk(KERN_INFO, dev, format, ##args) +extern int netdev_printk (const char *level,const struct net_device *dev, +const char *format, ...) + __attribute__ ((format (printf,3 ,4 ))); +extern int netdev_emerg (const struct net_device *dev,const char *format, ...) + __attribute__ ((format (printf,2 ,3 ))); +extern int netdev_alert (const struct net_device *dev,const char *format, ...) + __attribute__ ((format (printf,2 ,3 ))); +extern int netdev_crit (const struct net_device *dev,const char *format, ...) + __attribute__ ((format (printf,2 ,3 ))); +extern int netdev_err (const struct net_device *dev,const char *format, ...) + __attribute__ ((format (printf,2 ,3 ))); +extern int netdev_warn (const struct net_device *dev,const char *format, ...) + __attribute__ ((format (printf,2 ,3 ))); +extern int netdev_notice (const struct net_device *dev,const char *format, ...) + __attribute__ ((format (printf,2 ,3 ))); +extern int netdev_info (const struct net_device *dev,const char *format, ...) + __attribute__ ((format (printf,2 ,3 )));#if defined(DEBUG ) #define netdev_dbg(__dev, format, args...) \
net/core/dev.c +62 -0
68 lines not on this page · raw message
Signature · 1 line
1.7.1.337.g6068.dirty
PATCH 4/4 netdevice.h: Change netif_<level> macros to call netdev_<level> functions
In reply to Joe PerchesReduces text ~300 bytes of text (woohoo!) in an x86 defconfig
$ size vmlinux* text data bss dec hex filename 7198526 720112 1366288 9284926 8dad3e vmlinux 7198862 720112 1366288 9285262 8dae8e vmlinux.netdev
--- include/linux/netdevice.h | 20 +++++++++++++------- 1 files changed, 13 insertions(+), 7 deletions(-)
include/linux/netdevice.h +13 -7
@@ -2291,20 +2291,26 @@ do { \ netdev_printk(level, (dev), fmt, ##args); \ } while (0) +#define netif_level(level, priv, type, dev, fmt, args...) \ +do { \ + if (netif_msg_##type(priv)) \ + netdev_##level(dev, fmt, ##args); \ +} while (0) + #define netif_emerg(priv, type, dev, fmt, args...) \ - netif_printk(priv, type, KERN_EMERG, dev, fmt, ##args) + netif_level(emerg, priv, type, dev, fmt, ##args) #define netif_alert(priv, type, dev, fmt, args...) \ - netif_printk(priv, type, KERN_ALERT, dev, fmt, ##args) + netif_level(alert, priv, type, dev, fmt, ##args) #define netif_crit(priv, type, dev, fmt, args...) \ - netif_printk(priv, type, KERN_CRIT, dev, fmt, ##args) + netif_level(crit, priv, type, dev, fmt, ##args) #define netif_err(priv, type, dev, fmt, args...) \ - netif_printk(priv, type, KERN_ERR, dev, fmt, ##args) + netif_level(err, priv, type, dev, fmt, ##args) #define netif_warn(priv, type, dev, fmt, args...) \ - netif_printk(priv, type, KERN_WARNING, dev, fmt, ##args) + netif_level(warn, priv, type, dev, fmt, ##args) #define netif_notice(priv, type, dev, fmt, args...) \ - netif_printk(priv, type, KERN_NOTICE, dev, fmt, ##args) + netif_level(notice, priv, type, dev, fmt, ##args) #define netif_info(priv, type, dev, fmt, args...) \ - netif_printk(priv, type, KERN_INFO, (dev), fmt, ##args) + netif_level(info, priv, type, dev, fmt, ##args) #if defined(DEBUG) #define netif_dbg(priv, type, dev, format, args...) \
Signature · 1 line
1.7.1.337.g6068.dirty
David Miller
maintainerFrom: Joe Perches <[email protected]>
Date: Sun, 27 Jun 2010 04:02:32 -0700
Quoted 9 lines
Recursive printk can reduce the total image size of an x86 defconfig about 1% by reducing duplicated KERN_<level> strings and centralizing the functions used by macros in new separate functions.
Joe Perches (4):
vsprintf: Recursive vsnprintf: Add "%pV", structva_formatdevice.hdrivers/base/core.cConvert dev_<level> logging macros to functionsnetdevice.hnet/core/dev.c: Convert netdev_<level> logging macros to functionsnetdevice.h: Change netif_<level> macros to call netdev_<level> functions
I'm fine with this, thanks Joe.
Greg, could you ACK this and let me know if it's OK if it swings through my net-next-2.6 tree?
Thanks.
David Miller
maintainerFrom: David Miller <[email protected]>
Date: Wed, 30 Jun 2010 13:07:09 -0700 (PDT)
Quoted 13 lines
From: Joe Perches <[email protected]>
Date: Sun, 27 Jun 2010 04:02:32 -0700Quoted 9 lines
Recursive printk can reduce the total image size of an x86 defconfig about 1% by reducing duplicated KERN_<level> strings and centralizing the functions used by macros in new separate functions.
Joe Perches (4):
vsprintf: Recursive vsnprintf: Add "%pV", structva_formatdevice.hdrivers/base/core.cConvert dev_<level> logging macros to functionsnetdevice.hnet/core/dev.c: Convert netdev_<level> logging macros to functionsnetdevice.h: Change netif_<level> macros to call netdev_<level> functions
Quoted 4 lines
I'm fine with this, thanks Joe.
Greg, could you ACK this and let me know if it's OK if it swings through my net-next-2.6 tree?
Greg, ping?
Greg KH
Acked-by Greg Kroah-HartmanQuoted 16 lines · David Miller
From: David Miller <[email protected]>
Date: Wed, 30 Jun 2010 13:07:09 -0700 (PDT)Quoted 13 lines
From: Joe Perches <[email protected]>
Date: Sun, 27 Jun 2010 04:02:32 -0700Quoted 9 lines
Recursive printk can reduce the total image size of an x86 defconfig about 1% by reducing duplicated KERN_<level> strings and centralizing the functions used by macros in new separate functions.
Joe Perches (4):
vsprintf: Recursive vsnprintf: Add "%pV", structva_formatdevice.hdrivers/base/core.cConvert dev_<level> logging macros to functionsnetdevice.hnet/core/dev.c: Convert netdev_<level> logging macros to functionsnetdevice.h: Change netif_<level> macros to call netdev_<level> functions
Quoted 6 lines
Quoted 4 lines
I'm fine with this, thanks Joe.
Greg, could you ACK this and let me know if it's OK if it swings through my net-next-2.6 tree?
Greg, ping?
Sorry about the delay.
Yes, that's fine to take it through your tree, thanks for doing that:
greg k-h
David Miller
maintainerFrom: Greg KH <[email protected]>
Date: Sat, 3 Jul 2010 09:08:57 -0700
Quoted 22 lines · David Miller
Quoted 21 lines
From: David Miller <[email protected]>
Date: Wed, 30 Jun 2010 13:07:09 -0700 (PDT)Quoted 17 lines
From: Joe Perches <[email protected]>
Date: Sun, 27 Jun 2010 04:02:32 -0700Quoted 9 lines
Recursive printk can reduce the total image size of an x86 defconfig about 1% by reducing duplicated KERN_<level> strings and centralizing the functions used by macros in new separate functions.
Joe Perches (4):
vsprintf: Recursive vsnprintf: Add "%pV", structva_formatdevice.hdrivers/base/core.cConvert dev_<level> logging macros to functionsnetdevice.hnet/core/dev.c: Convert netdev_<level> logging macros to functionsnetdevice.h: Change netif_<level> macros to call netdev_<level> functionsI'm fine with this, thanks Joe.
Greg, could you ACK this and let me know if it's OK if it swings through my net-next-2.6 tree?
Quoted 6 lines
Quoted 1 line
Greg, ping?
Sorry about the delay.
Yes, that's fine to take it through your tree, thanks for doing that:
Thanks! I've added this set to my tree.