Reducing the number of ELF section in the livepatch modules

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

It is possible that keeping each new and patched function in a separate 
ELF section in a livepatch kernel module could cause problems.

During the testing of binary patches for the kernels used in Virtuozzo 
7, I found that the kernel may try to allocate a relatively large (for 
kmalloc) memory area to support sysfs files 
/sys/module/<module_name>/sections/* for the patch modules. The size was 
16 - 35 KB, depending on the patch, i.e. 3rd and 4th order allocations. 
The numbers do not look very big but still increase the chance that the 
patch module will fail to load when the memory is fragmented.

kernel/module.c, add_sect_attrs():
	/* Count loaded sections and allocate structures */
	for (i = 0; i < info->hdr->e_shnum; i++)
		if (!sect_empty(&info->sechdrs[i]))
			nloaded++;
	size[0] = ALIGN(sizeof(*sect_attrs)
			+ nloaded * sizeof(sect_attrs->attrs[0]),
			sizeof(sect_attrs->grp.attrs[0]));
	size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]);
	sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);

So, in our case, the size of the requested memory chunk was
48 + 80 * <number_of_loaded_ELF_sections>.

Both livepatch and old-style KPatch kernel modules place each new or 
patched function in a separate section, same for the new global and 
static data. So, if we patch 200+ kernel functions (which not that 
unusual in cumulative patches), the kernel will try to allocate around 
16 KB of memory for these sysfs data only. The largest of our binary 
patches have around 400 new and patched functions, plus a few dozens of 
new data items, which results in a wasted kernel memory chunk of 35 KB 
in size.

Here are the questions.

1. The files /sys/module/<module_name>/sections/* currently contain the 
start addresses of the relevant sections, i.e. the addresses of new and 
patched functions among other things. Is this info really needed for 
livepatch kernel modules after they have been loaded?

2. Of course, create-diff-object relies heavily upon placing each new or 
patched function in a separate section. But is it needed to keep the 
functions there after the diff object files have been prepared?

Does the code that loads/unloads the patches require that each function 
is kept that way? Looks like no, but I am not 100% sure.

As an experiment, I added the following to kmod/patch/kpatch.lds.S to 
merge all .text.* sections into .text.livepatch in the resulting patch 
module:

SECTIONS
{
+   .text.livepatch : {
+    *(.text.*)
+   }

My test patch module with around 200 changed functions was built OK with 
that, the functions were actually placed into .text.livepatch section as 
requested. The patch was loaded fine but I haven't tested it much yet.

It also might be reasonable to merge .rodata.__func__.* the same way.

Are there any pitfalls in such merging of sections? Am I missing 
something obvious?

Regards,
Evgenii




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux Kernel]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux