[NETNS]: Move some code into __init section when CONFIG_NET_NS=n
authorPavel Emelyanov <xemul@openvz.org>
Tue, 9 Oct 2007 03:38:39 +0000 (20:38 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Wed, 10 Oct 2007 23:54:58 +0000 (16:54 -0700)
With the net namespaces many code leaved the __init section,
thus making the kernel occupy more memory than it did before.
Since we have a config option that prohibits the namespace
creation, the functions that initialize/finalize some netns
stuff are simply not needed and can be freed after the boot.

Currently, this is almost not noticeable, since few calls
are no longer in __init, but when the namespaces will be
merged it will be possible to free more code. I propose to
use the __net_init, __net_exit and __net_initdata "attributes"
for functions/variables that are not used if the CONFIG_NET_NS
is not set to save more space in memory.

The exiting functions cannot just reside in the __exit section,
as noticed by David, since the init section will have
references on it and the compilation will fail due to modpost
checks. These references can exist, since the init namespace
never dies and the exit callbacks are never called. So I
introduce the __exit_refok attribute just like it is already
done with the __init_refok.

Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/loopback.c
fs/proc/proc_net.c
include/linux/init.h
include/net/net_namespace.h
net/core/dev.c
net/core/dev_mcast.c
net/netlink/af_netlink.c
scripts/mod/modpost.c

index d6997aec45ddaec150f8dfa5e54812eb80f2faab..be25aa33971cd5f51a2fbff62dcd807420f623fd 100644 (file)
@@ -250,7 +250,7 @@ static void loopback_setup(struct net_device *dev)
 }
 
 /* Setup and register the loopback device. */
-static int loopback_net_init(struct net *net)
+static __net_init int loopback_net_init(struct net *net)
 {
        struct net_device *dev;
        int err;
@@ -278,14 +278,14 @@ out_free_netdev:
        goto out;
 }
 
-static void loopback_net_exit(struct net *net)
+static __net_exit void loopback_net_exit(struct net *net)
 {
        struct net_device *dev = net->loopback_dev;
 
        unregister_netdev(dev);
 }
 
-static struct pernet_operations loopback_net_ops = {
+static struct pernet_operations __net_initdata loopback_net_ops = {
        .init = loopback_net_init,
        .exit = loopback_net_exit,
 };
index 85cc8e8bb8621392a0d49dd736a72cfd5a241c80..2e91fb756e9ad27be30488bd88a5e5ac8856bf34 100644 (file)
@@ -140,7 +140,7 @@ static struct inode_operations proc_net_dir_inode_operations = {
        .setattr        = proc_net_setattr,
 };
 
-static int proc_net_ns_init(struct net *net)
+static __net_init int proc_net_ns_init(struct net *net)
 {
        struct proc_dir_entry *root, *netd, *net_statd;
        int err;
@@ -178,19 +178,19 @@ free_root:
        goto out;
 }
 
-static void proc_net_ns_exit(struct net *net)
+static __net_exit void proc_net_ns_exit(struct net *net)
 {
        remove_proc_entry("stat", net->proc_net);
        remove_proc_entry("net", net->proc_net_root);
        kfree(net->proc_net_root);
 }
 
-struct pernet_operations proc_net_ns_ops = {
+struct pernet_operations __net_initdata proc_net_ns_ops = {
        .init = proc_net_ns_init,
        .exit = proc_net_ns_exit,
 };
 
-int proc_net_init(void)
+int __init proc_net_init(void)
 {
        proc_net_shadow = proc_mkdir("net", NULL);
        proc_net_shadow->proc_iops = &proc_net_dir_inode_operations;
index 74b1f43bf9825b260be74c1bf71be116f9bd40fc..f8d9d0b5cffcad16fecacaafaca541a338aec951 100644 (file)
@@ -57,6 +57,7 @@
  * The markers follow same syntax rules as __init / __initdata. */
 #define __init_refok     noinline __attribute__ ((__section__ (".text.init.refok")))
 #define __initdata_refok          __attribute__ ((__section__ (".data.init.refok")))
+#define __exit_refok     noinline __attribute__ ((__section__ (".exit.text.refok")))
 
 #ifdef MODULE
 #define __exit         __attribute__ ((__section__(".exit.text"))) __cold
index 934c840b5941f7885f1aeb27eed4e82925f4f1e5..93aa87d328040b71877a31ee400e7adebd3e2073 100644 (file)
@@ -99,6 +99,15 @@ static inline void release_net(struct net *net)
 #define for_each_net(VAR)                              \
        list_for_each_entry(VAR, &net_namespace_list, list)
 
+#ifdef CONFIG_NET_NS
+#define __net_init
+#define __net_exit
+#define __net_initdata
+#else
+#define __net_init     __init
+#define __net_exit     __exit_refok
+#define __net_initdata __initdata
+#endif
 
 struct pernet_operations {
        struct list_head list;
index 1aa07047826e275110743a5a5b4d7feb09692416..e7e728aea9f3c315279612231f5b6ad64f6162e2 100644 (file)
@@ -2611,7 +2611,7 @@ static const struct file_operations ptype_seq_fops = {
 };
 
 
-static int dev_proc_net_init(struct net *net)
+static int __net_init dev_proc_net_init(struct net *net)
 {
        int rc = -ENOMEM;
 
@@ -2636,7 +2636,7 @@ out_dev:
        goto out;
 }
 
-static void dev_proc_net_exit(struct net *net)
+static void __net_exit dev_proc_net_exit(struct net *net)
 {
        wext_proc_exit(net);
 
@@ -2645,7 +2645,7 @@ static void dev_proc_net_exit(struct net *net)
        proc_net_remove(net, "dev");
 }
 
-static struct pernet_operations dev_proc_ops = {
+static struct pernet_operations __net_initdata dev_proc_ops = {
        .init = dev_proc_net_init,
        .exit = dev_proc_net_exit,
 };
@@ -4278,7 +4278,7 @@ static struct hlist_head *netdev_create_hash(void)
 }
 
 /* Initialize per network namespace state */
-static int netdev_init(struct net *net)
+static int __net_init netdev_init(struct net *net)
 {
        INIT_LIST_HEAD(&net->dev_base_head);
        rwlock_init(&dev_base_lock);
@@ -4299,18 +4299,18 @@ err_name:
        return -ENOMEM;
 }
 
-static void netdev_exit(struct net *net)
+static void __net_exit netdev_exit(struct net *net)
 {
        kfree(net->dev_name_head);
        kfree(net->dev_index_head);
 }
 
-static struct pernet_operations netdev_net_ops = {
+static struct pernet_operations __net_initdata netdev_net_ops = {
        .init = netdev_init,
        .exit = netdev_exit,
 };
 
-static void default_device_exit(struct net *net)
+static void __net_exit default_device_exit(struct net *net)
 {
        struct net_device *dev, *next;
        /*
@@ -4336,7 +4336,7 @@ static void default_device_exit(struct net *net)
        rtnl_unlock();
 }
 
-static struct pernet_operations default_device_ops = {
+static struct pernet_operations __net_initdata default_device_ops = {
        .exit = default_device_exit,
 };
 
index 896b0ca5aed7c63b19ddc007ad402832bf66a8f6..15241cf48af8a8b835a502978e1777c6c2d8ab12 100644 (file)
@@ -273,19 +273,19 @@ static const struct file_operations dev_mc_seq_fops = {
 
 #endif
 
-static int dev_mc_net_init(struct net *net)
+static int __net_init dev_mc_net_init(struct net *net)
 {
        if (!proc_net_fops_create(net, "dev_mcast", 0, &dev_mc_seq_fops))
                return -ENOMEM;
        return 0;
 }
 
-static void dev_mc_net_exit(struct net *net)
+static void __net_exit dev_mc_net_exit(struct net *net)
 {
        proc_net_remove(net, "dev_mcast");
 }
 
-static struct pernet_operations dev_mc_net_ops = {
+static struct pernet_operations __net_initdata dev_mc_net_ops = {
        .init = dev_mc_net_init,
        .exit = dev_mc_net_exit,
 };
index 46eb5ea1fbd7f253f777e14f25948bcdfe32b63d..3ef32825da714889079b06f796abb74aef677902 100644 (file)
@@ -1924,7 +1924,7 @@ static struct net_proto_family netlink_family_ops = {
        .owner  = THIS_MODULE,  /* for consistency 8) */
 };
 
-static int netlink_net_init(struct net *net)
+static int __net_init netlink_net_init(struct net *net)
 {
 #ifdef CONFIG_PROC_FS
        if (!proc_net_fops_create(net, "netlink", 0, &netlink_seq_fops))
@@ -1933,14 +1933,14 @@ static int netlink_net_init(struct net *net)
        return 0;
 }
 
-static void netlink_net_exit(struct net *net)
+static void __net_exit netlink_net_exit(struct net *net)
 {
 #ifdef CONFIG_PROC_FS
        proc_net_remove(net, "netlink");
 #endif
 }
 
-static struct pernet_operations netlink_net_ops = {
+static struct pernet_operations __net_initdata netlink_net_ops = {
        .init = netlink_net_init,
        .exit = netlink_net_exit,
 };
index 6c145d6e89dec73d2b595a9895825a70c9bd6efe..0a4051fbd34e24116cd55c4e758605ea683348a8 100644 (file)
@@ -709,6 +709,7 @@ static int secref_whitelist(const char *modname, const char *tosec,
 
        /* Check for pattern 0 */
        if ((strncmp(fromsec, ".text.init.refok", strlen(".text.init.refok")) == 0) ||
+           (strncmp(fromsec, ".exit.text.refok", strlen(".exit.text.refok")) == 0) ||
            (strncmp(fromsec, ".data.init.refok", strlen(".data.init.refok")) == 0))
                return 1;