include/linux/module.h: mark init/cleanup_module aliases as __init/exit
PATCH v2 1/1 include/linux/module.h: mark init/cleanup_module aliases as __init/exit
The upcoming GCC 9 release extends the -Wmissing-attributes warnings (enabled by -Wall) to C and aliases: it warns when particular function attributes are missing in the aliases but not in their target.
In particular, it triggers for all the init/cleanup_module aliases in the kernel (defined by the module_init/exit macros), ending up being very noisy.
These aliases point to the __init/__exit functions of a module, which are defined as __cold (among other attributes). However, the aliases themselves do not have the __cold attribute.
Since the compiler behaves differently when compiling a __cold function as well as when compiling paths leading to calls to __cold functions, the warning is trying to point out the possibly-forgotten attribute in the alias.
In order to keep the warning enabled, we choose to silence the warning by marking the aliases as __init/__exit.
Note that the warning would go away marking either the extern declaration, the definition, or both. However, we only mark the definition of the alias, since we do not want callers (which only see the declaration) to be compiled as if the function was __cold (and therefore the paths leading to those calls would be assumed to be unlikely).
---
The new version I pushed for -next.
include/linux/module.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/module.h +2 -2
@@ -129,13 +129,13 @@ extern void cleanup_module(void);#define module_init (initfn) \ static inline initcall_t __maybe_unused __inittest(void) \ { return initfn; } \ - int init_module(void) __attribute__((alias(#initfn))); + int init_module(void) __init __attribute__((alias(#initfn)));/* This is only required if you want to be unloadable. */ #define module_exit (exitfn) \ static inline exitcall_t __maybe_unused __exittest(void) \ { return exitfn; } \ - void cleanup_module(void) __attribute__((alias(#exitfn))); + void cleanup_module(void) __exit __attribute__((alias(#exitfn)));#endif
Signature · 1 line
2.17.1
Quoted 8 lines · Miguel Ojeda
include/linux/module.h +0
-0@@ -129,13 +129,13 @@ extern void cleanup_module(void);#define module_init (initfn) \ static inline initcall_t __maybe_unused __inittest(void) \
include/linux/module.h extern void cleanup_module(void); · line 138
Quoted 10 lines
include/linux/module.h +2
-2{return initfn; } \ - int init_module(void) __attribute__((alias(#initfn))); + int init_module(void) __init __attribute__((alias(#initfn))); /* This is only required if you want to be unloadable. */ #define module_exit(exitfn) \ static inline exitcall_t __maybe_unused __exittest(void) \ { return exitfn; } \ - void cleanup_module(void) __attribute__((alias(#exitfn))); + void cleanup_module(void) __exit __attribute__((alias(#exitfn)));
It turns out that there are some modules without __init/__exit marked functions, which GCC complains about, since now the alias is in a different section than the target:
* In some cases, this is due to a missing __init/__exit marking
(e.g. drivers/connector/connector.c). These should be fixed in any case.
* In other cases, the cleanup function is not marked as such because
it is called from another place in the TU, like the init function (e.g. arch/x86/kvm/vmx.c). We would need to create an actual cleanup function (marked as __exit) that simply calls the current exit static function.
So we have a few alternatives:
1) Going only with __cold.
2) Using the new __copy attribute (because then they are copied only
in the cases they are actually used).
3) Fix and go for __init/__exit. While this requires some tweaking
as explained above, it would be good if we can achieve it since then we are enforcing proper __init/__exit markings for all modules (whereas __copy wouldn't spot).
I think it is worth achieving 3), but that will take a bit more of time. In that case, I suggest we push 1) or 2) for the moment (so that the warning is fixed) and then work on fixing all instances. As soon as that is done, we can push 3).
What do you think?
Cheers,
Miguel
+++ Miguel Ojeda [06/02/19 22:19 +0100]:
Quoted 25 lines
Quoted 8 lines · Miguel Ojeda
include/linux/module.h +0
-0@@ -129,13 +129,13 @@ extern void cleanup_module(void);#define module_init (initfn) \ static inline initcall_t __maybe_unused __inittest(void) \include/linux/module.h extern void cleanup_module(void); · line 138
Quoted 10 lines
include/linux/module.h +2
-2{return initfn; } \ - int init_module(void) __attribute__((alias(#initfn))); + int init_module(void) __init __attribute__((alias(#initfn))); /* This is only required if you want to be unloadable. */ #define module_exit(exitfn) \ static inline exitcall_t __maybe_unused __exittest(void) \ { return exitfn; } \ - void cleanup_module(void) __attribute__((alias(#exitfn))); + void cleanup_module(void) __exit __attribute__((alias(#exitfn)));It turns out that there are some modules without __init/__exit marked functions, which GCC complains about, since now the alias is in a different section than the target:
Quoted 8 lines
* In some cases, this is due to a missing __init/__exit marking
(e.g.drivers/connector/connector.c). These should be fixed in any case.
* In other cases, the cleanup function is not marked as such because
it is called from another place in the TU, like the init function (e.g.arch/x86/kvm/vmx.c). We would need to create an actual cleanup function (marked as__exit) that simply calls the current exit static function.
Grr, I guess it was not so simple after all. :)
Quoted 10 lines
So we have a few alternatives:
1) Going only with
__cold.
2) Using the new__copyattribute (because then they are copied only
in the cases they are actually used).
3) Fix and go for __init/__exit. While this requires some tweaking
as explained above, it would be good if we can achieve it since then we are enforcing proper __init/__exit markings for all modules (whereas__copywouldn't spot).
Quoted 4 lines
I think it is worth achieving 3), but that will take a bit more of time. In that case, I suggest we push 1) or 2) for the moment (so that the warning is fixed) and then work on fixing all instances. As soon as that is done, we can push 3).
My order of preference would be 2, 1, striving for 3 eventually.
Thanks Miguel!
Jessica
Quoted 2 lines · Jessica Yu
My order of preference would be 2, 1, striving for 3 eventually.
For reference, for 3), we would need to tweak the following ~130 modules [1]. Quite a lot of them are the simple kind. Also, if we end up with 3), we could potentially remove a few modpost checks (e.g. ANY_INIT_TO_ANY_EXIT).
I am submitting the patch for 2). It requires introducing the new attribute, so let's see if people like it.
Cheers,
Miguel
[1]
arch/x86/kvm/vmx/vmx.c crypto/async_tx/raid6test.ccrypto/ecdh.cdrivers/block/drbd/drbd_main.c drivers/bluetooth/btrsi.c drivers/char/ipmi/ipmi_si_intf.c drivers/char/ipmi/ipmi_ssif.cdrivers/char/lp.cdrivers/char/mwave/mwavedd.c drivers/connector/connector.c drivers/cpufreq/powernow-k8.c drivers/crypto/ccp/ccp-crypto-main.c drivers/dma/ti/edma.cdrivers/dma/ti/omap-dma.c drivers/firmware/efi/efivars.c drivers/firmware/google/memconsole-coreboot.c drivers/fmc/fmc-chardev.cdrivers/fmc/fmc-core.cdrivers/fmc/fmc-fakedev.c drivers/fmc/fmc-trivial.c drivers/fmc/fmc-write-eeprom.c drivers/fsi/fsi-core.cdrivers/fsi/fsi-occ.cdrivers/fsi/fsi-sbefifo.cdrivers/fsi/fsi-scom.cdrivers/gpu/drm/drm_drv.cdrivers/hv/hv_util.c drivers/hwtracing/stm/console.c drivers/hwtracing/stm/dummy_stm.c drivers/hwtracing/stm/heartbeat.c drivers/hwtracing/stm/p_basic.c drivers/hwtracing/stm/p_sys-t.c drivers/infiniband/sw/rdmavt/vt.c drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c drivers/isdn/mISDN/core.c drivers/isdn/mISDN/l1oip_core.c drivers/lightnvm/pblk-init.c drivers/mcb/mcb-core.cdrivers/md/bcache/super.c drivers/md/dm-integrity.cdrivers/md/dm-thin.cdrivers/md/md-cluster.cdrivers/md/md-faulty.cdrivers/md/md-linear.cdrivers/md/raid0.cdrivers/md/raid1.cdrivers/md/raid10.cdrivers/md/raid5.c drivers/media/common/b2c2/flexcop.c drivers/media/pci/cx25821/cx25821-alsa.c drivers/media/pci/ivtv/ivtvfb.c drivers/media/pci/saa7134/saa7134-alsa.c drivers/media/platform/davinci/vpif.c drivers/media/platform/davinci/vpss.c drivers/media/platform/exynos4-is/fimc-is.c drivers/media/platform/omap/omap_vout.c drivers/message/fusion/mptctl.c drivers/mtd/devices/block2mtd.c drivers/mtd/maps/sbc_gxx.c drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c drivers/net/ethernet/microchip/encx24j600.c drivers/net/fddi/defxx.c drivers/net/ipvlan/ipvtap.c drivers/net/macvtap.cdrivers/net/phy/sfp.cdrivers/net/tun.c drivers/net/vmxnet3/vmxnet3_drv.c drivers/net/wireless/marvell/mwifiex/main.c drivers/net/wireless/rsi/rsi_91x_main.c drivers/net/wireless/rsi/rsi_91x_sdio.c drivers/nfc/nfcmrvl/uart.c drivers/pcmcia/i82092.c drivers/platform/x86/classmate-laptop.c drivers/platform/x86/thinkpad_acpi.c drivers/rpmsg/rpmsg_char.c drivers/scsi/aic7xxx/aic7xxx_osm.c drivers/scsi/arcmsr/arcmsr_hba.c drivers/soc/fsl/dpio/dpio-driver.c drivers/staging/gasket/apex_driver.c drivers/staging/greybus/fw-core.c drivers/staging/greybus/loopback.c drivers/staging/greybus/raw.c drivers/staging/greybus/uart.c drivers/staging/unisys/visorhba/visorhba_main.c drivers/staging/unisys/visornic/visornic_main.c drivers/tty/rocket.cdrivers/tty/serial/kgdboc.c drivers/tty/serial/owl-uart.c drivers/usb/gadget/function/f_tcm.c drivers/usb/gadget/function/u_serial.c drivers/vhost/net.cdrivers/vhost/scsi.c drivers/video/fbdev/aty/aty128fb.c drivers/video/fbdev/geode/gx1fb_core.c drivers/video/fbdev/gxt4500.c drivers/video/fbdev/matrox/matroxfb_crtc2.c drivers/video/fbdev/mb862xx/mb862xxfbdrv.c drivers/video/fbdev/nvidia/nvidia.c drivers/video/fbdev/riva/fbdev.c drivers/video/fbdev/sstfb.c drivers/video/fbdev/uvesafb.c drivers/virtio/virtio.c drivers/watchdog/cpu5wdt.c kernel/backtracetest.c kernel/locking/locktorture.c kernel/rcu/rcuperf.ckernel/rcu/rcutorture.clib/interval_tree_test.c lib/memory-notifier-error-inject.c lib/netdev-notifier-error-inject.c lib/of-reconfig-notifier-error-inject.c lib/pm-notifier-error-inject.clib/raid6/algos.clib/test_ida.clib/test_xarray.cmm/hwpoison-inject.cnet/9p/trans_xen.cnet/core/drop_monitor.cnet/l2tp/l2tp_netlink.c net/netfilter/xt_NETMAP.c net/openvswitch/datapath.cnet/rds/af_rds.cnet/rds/rdma_transport.cnet/rds/tcp.csamples/connector/cn_test.c samples/livepatch/livepatch-callbacks-busymod.c samples/livepatch/livepatch-callbacks-demo.c samples/livepatch/livepatch-callbacks-mod.c samples/livepatch/livepatch-sample.c samples/livepatch/livepatch-shadow-fix1.c samples/livepatch/livepatch-shadow-fix2.c samples/livepatch/livepatch-shadow-mod.c