move unneeded data to initdata section
Subsystems (3)
PATCH 2/2 move unneeded data to initdata section
This patch reverts Eric's commit 2b008b0a8e96b726c603c5e1a5a7a509b5f61e35
It diets .text & .data section of the kernel if CONFIG_NET_NS is not set. This is safe after list operations cleanup.
drivers/net/loopback.c renamed from drivers/net/loopback.c.reversed +1 -1
@@ -284,7 +284,7 @@ static __net_exit void loopback_net_exitunregister_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, };
fs/proc/proc_net.c renamed from fs/proc/proc_net.c.reversed +1 -1
@@ -185,7 +185,7 @@ static __net_exit void proc_net_ns_exit(kfree (net->proc_net_root); } -static struct pernet_operations proc_net_ns_ops = { +static struct pernet_operations __net_initdata proc_net_ns_ops = { .init = proc_net_ns_init, .exit = proc_net_ns_exit, };
include/net/net_namespace.h renamed from include/net/net_namespace.h.reversed +2 -0
@@ -102,9 +102,11 @@ static inline void release_net(struct ne#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 {
net/core/dev.c renamed from net/core/dev.c.reversed +3 -3
@@ -2676,7 +2676,7 @@ static void __net_exit dev_proc_net_exitproc_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, };
@@ -4336,7 +4336,7 @@ static void __net_exit netdev_exit(struckfree (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, };
@@ -4367,7 +4367,7 @@ static void __net_exit default_device_exrtnl_unlock (); } -static struct pernet_operations default_device_ops = { +static struct pernet_operations __net_initdata default_device_ops = { .exit = default_device_exit, };
net/core/dev_mcast.c renamed from net/core/dev_mcast.c.reversed +1 -1
@@ -285,7 +285,7 @@ static void __net_exit dev_mc_net_exit(sproc_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, };
net/netlink/af_netlink.c renamed from net/netlink/af_netlink.c.reversed +1 -1
@@ -1888,7 +1888,7 @@ static void __net_exit netlink_net_exit(#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, };
From: "Denis V. Lunev" <[email protected]>
Date: Wed, 7 Nov 2007 15:01:00 +0300
Quoted 6 lines
This patch reverts Eric's commit
2b008b0a8e96b726c603c5e1a5a7a509b5f61e35It diets .text & .data section of the kernel if
CONFIG_NET_NSis not set. This is safe after list operations cleanup.Signed-of-by Denis V. Lunev <[email protected]>
Applied, thanks Denis.
Quoted 4 lines · Denis V. Lunev
This patch reverts Eric's commit
2b008b0a8e96b726c603c5e1a5a7a509b5f61e35It diets .text & .data section of the kernel if
CONFIG_NET_NSis not set. This is safe after list operations cleanup.
Ok. This patch is technically safe because none of the touched code can live in a module and so we never touch the exit code path.
However in the general case and as a code idiom this __net_initdata on struct pernet_operations is fundamentally horribly broken.
Look at what happens if we use this idiom in module. There is only one definition of __initdata ".init.data". The module loader places all sections that begin with .init in a region of memory that will be discarded after module initialization.
So in register_pernet_operations we pass in the a pointer to struct pernet_operations and call the init method. Later when we remove the module we again pass in the pointer to struct pernet_operations which lived in an init section so it has been discarded. We dereference that pointer to find the exit method and KABOOM!!!!
So I'm still opposed to __net_initdata on the grounds that at best it is like putting our head under a guillotine and reaching up and sawing at the row that holds the blade up with a pocket knife. It is a think rope and a puny knife so you are safe for a while....
Eric
Quoted 10 lines · Eric W. Biederman
Quoted 4 lines · Denis V. Lunev
This patch reverts Eric's commit
2b008b0a8e96b726c603c5e1a5a7a509b5f61e35It diets .text & .data section of the kernel if
CONFIG_NET_NSis not set. This is safe after list operations cleanup.Ok. This patch is technically safe because none of the touched code can live in a module and so we never touch the exit code path.
Quoted 7 lines
However in the general case and as a code idiom this
__net_initdataon structpernet_operationsis fundamentally horribly broken.Look at what happens if we use this idiom in module. There is only one definition of
__initdata".init.data". The module loader places all sections that begin with .init in a region of memory that will be discarded after module initialization.
nothing is discarded after module load. Though, I can be wrong. Could you point me to the exact place?
Regards,
Den
Quoted 14 lines · Denis V. Lunev
Quoted 13 lines · Eric W. Biederman
Quoted 4 lines · Denis V. Lunev
This patch reverts Eric's commit
2b008b0a8e96b726c603c5e1a5a7a509b5f61e35It diets .text & .data section of the kernel if
CONFIG_NET_NSis not set. This is safe after list operations cleanup.Ok. This patch is technically safe because none of the touched code can live in a module and so we never touch the exit code path.
However in the general case and as a code idiom this
__net_initdataon structpernet_operationsis fundamentally horribly broken.
Quoted 7 lines
Quoted 4 lines
Look at what happens if we use this idiom in module. There is only one definition of
__initdata".init.data". The module loader places all sections that begin with .init in a region of memory that will be discarded after module initialization.nothing is discarded after module load. Though, I can be wrong. Could you point me to the exact place?
If __initdata is not discarded after module load then we should do it. There is no reason to waste __initdata RAM when the module is loaded.
Sam
Quoted 6 lines · Sam Ravnborg
Quoted 3 lines · Denis V. Lunev
nothing is discarded after module load. Though, I can be wrong. Could you point me to the exact place?
If
__initdatais not discarded after module load then we should do it. There is no reason to waste__initdataRAM when the module is loaded.
Down at the bottom of sys_init_module we have:
/* Drop initial reference. */ module_put(mod); unwind_remove_table(mod->unwind_info, 1); module_free(mod, mod->module_init); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mod->module_init = NULL; mod->init_size = 0; mod->init_text_size = 0; mutex_unlock(&module_mutex); return 0;
Which frees the memory for the .init sections.
Eric
Quoted 24 lines · Eric W. Biederman
Quoted 6 lines · Sam Ravnborg
Quoted 3 lines · Denis V. Lunev
nothing is discarded after module load. Though, I can be wrong. Could you point me to the exact place?
If
__initdatais not discarded after module load then we should do it. There is no reason to waste__initdataRAM when the module is loaded.Down at the bottom of
sys_init_modulewe have:/* Drop initial reference. */ module_put(mod); unwind_remove_table(mod->unwind_info, 1); module_free(mod, mod->module_init); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mod->module_init = NULL; mod->init_size = 0; mod->init_text_size = 0; mutex_unlock(&module_mutex); return 0;
Quoted 1 line
Which frees the memory for the .init sections.
Thanks for clarifying this Eric - should have looked myself..
Sam
A message that is not in the archive (sent off-list or not yet received): 20071115184334.GC23914-QabhHTsIXMSnlFQ6Q1D1Y0B+6BGkLq7r@public.gmane.org
Quoted 21 lines · Sam Ravnborg
Quoted 20 lines · Eric W. Biederman
Quoted 5 lines · Sam Ravnborg
Quoted 2 lines · Denis V. Lunev
nothing is discarded after module load. Though, I can be wrong. Could you point me to the exact place?
If
__initdatais not discarded after module load then we should do it. There is no reason to waste__initdataRAM when the module is loaded.Down at the bottom of
sys_init_modulewe have:/* Drop initial reference. */ module_put(mod); unwind_remove_table(mod->unwind_info, 1); module_free(mod, mod->module_init); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mod->module_init = NULL; mod->init_size = 0; mod->init_text_size = 0; mutex_unlock(&module_mutex);
Quoted 5 lines
Quoted 3 lines
return 0;Which frees the memory for the .init sections.
Thanks for clarifying this Eric - should have looked myself..
clear :) I was wrong... Thank you for pointing this out.
will you mind against this?
include/net/net_namespace.h +5 -1
@@ -119,10 +119,14 @@ static inline struct net *maybe_get_net(struct net *net)#ifdef CONFIG_NET_NS #define __net_init#define __net_exit -#define __net_initdata#else #define __net_init __init#define __net_exit __exit_refok +#endif + +#if defined(CONFIG_NET_NS ) || defined(MODULE ) +#define __net_initdata +#else #define __net_initdata __initdata#endif
_______________________________________________
Containers mailing list Containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linux-foundation.org/mailman/listinfo/containers
Quoted 12 lines · Denis V. Lunev
will you mind against this?
include/net/net_namespace.h +0
-1@@ -119,10 +119,14 @@ static inline struct net *maybe_get_net(struct net *net)#ifdef CONFIG_NET_NS #define __net_init#define __net_exit -#define __net_initdata
include/net/net_namespace.h static inline struct net *maybe_get_net(struct net *net) · line 131
Quoted 10 lines
include/net/net_namespace.h +5
-0#else #define __net_init __init#define __net_exit __exit_refok +#endif + +#if defined(CONFIG_NET_NS ) || defined(MODULE ) +#define __net_initdata +#else #define __net_initdata __initdata#endif
n principle I am against this approach. __initdata is far too overloaded with different stuff.
A much more preferred approach should be to create new sections named for example .init.data.net and .init.data.net.module
And then in include/asm-generic/vmlinux.lds.h decide the location of these sections.
On top of this we would have to teach modpost about these new sections. But the advantage of this approach is that the section mismatch checks are *independent* of the module being a MODULE or build-in. The check will still happen.
In this way we avoid the situation where a warning only pops up in certain configurations.
To do so will obviously require a bit more linker script consolidation but if you or some else could step in a do this it would be great!
Sam