From: Evgenii Shatokhin <eshatok...@virtuozzo.com> A kernel module containing a ReadyKernel patch could have lots of ELF sections: one per each new or patched function, one per each new static or global variable, etc.
The kernel creates a sysfs file /sys/module/<module_name>/sections/<section_name> for each loaded section when the patch module is being loaded, see add_sect_attrs() in kernel/module.c. A big chunk of memory is allocated for all these with kzalloc. For the ReadyKernel patches we have already released, the amount of memory could be as high as 34528 bytes (48 + 80 * 431 loaded sections), which is a 4th order allocation. 3rd order allocations are also common here, see https://jira.sw.ru/browse/PSBM-95050. Not only it is a waste (contiguous memory is not needed there), but the allocation may also fail when the memory is fragmented. ReadyKernel patches are often used in the systems with rather significant uptime, so the fragmentation is possible. It could be better if the patch modules did not use too many ELF sections. However, the KPatch maintainers pointed out (https://github.com/dynup/kpatch/pull/1131) that the same problem would affect regular kernel modules as well after FGKASLR has been merged into the mainline kernel. Combining the sections of the kernel modules destroys the purpose of FGKASLR, so, it was agreed that we probably should just switch to kvmalloc+kvfree in add_sect_attrs/free_sect_attrs. Details and discussion: https://www.spinics.net/lists/live-patching/msg06364.html https://jira.sw.ru/browse/PSBM-108017 Signed-off-by: Evgenii Shatokhin <eshatok...@virtuozzo.com> (cherry picked from vz8 commit e16aab11613f1fcf9b34d3df664591e5504fa624) Signed-off-by: Andrey Zhadchenko <andrey.zhadche...@virtuozzo.com> --- kernel/module.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index c402a69..05cb510 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1529,7 +1529,7 @@ static void free_sect_attrs(struct module_sect_attrs *sect_attrs) for (section = 0; section < sect_attrs->nsections; section++) kfree(sect_attrs->attrs[section].battr.attr.name); - kfree(sect_attrs); + kvfree(sect_attrs); } static void add_sect_attrs(struct module *mod, const struct load_info *info) @@ -1546,7 +1546,7 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info) size[0] = ALIGN(struct_size(sect_attrs, attrs, nloaded), sizeof(sect_attrs->grp.bin_attrs[0])); size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]); - sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL); + sect_attrs = kvzalloc(size[0] + size[1], GFP_KERNEL); if (sect_attrs == NULL) return; -- 1.8.3.1 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel