[PATCH v5][makedumpfile 6/9] Add makedumpfile extensions support
HAGIO KAZUHITO(萩尾 一仁)
k-hagio-ab at nec.com
Tue Jun 16 18:50:33 PDT 2026
On 2026/06/16 19:31, Tao Liu wrote:
> Hi Kazu,
>
> On Tue, Jun 16, 2026 at 07:51:47AM +0000, HAGIO KAZUHITO(萩尾 一仁) wrote:
>> On 2026/06/16 11:17, Tao Liu wrote:
>>> On Tue, Jun 16, 2026 at 1:39 PM HAGIO KAZUHITO(萩尾 一仁)
>>> <k-hagio-ab at nec.com> wrote:
>>>>
>>>> On 2026/06/16 8:03, Tao Liu wrote:
>>>>> Hi Stephen & Kazu,
>>>>>
>>>>> On Tue, Jun 16, 2026 at 5:12 AM Stephen Brennan
>>>>> <stephen.s.brennan at oracle.com> wrote:
>>>>>>
>>>>>> HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab at nec.com> writes:
>>>>>>> On 2026/04/14 19:26, Tao Liu wrote:
>>>>>>>
>>>>>>>> +static bool init_kallsyms_btf(void)
>>>>>>>> +{
>>>>>>>> + int count;
>>>>>>>> + bool ret = false;
>>>>>>>> + /* We will load module's btf/kallsyms on demand */
>>>>>>>> + bool init_ksyms_module = false;
>>>>>>>> + bool init_ktypes_module = false;
>>>>>>>> +
>>>>>>>> + if (check_ksyms_require_modname("vmlinux", &count)) {
>>>>>>>
>>>>>>> Thank you for the explanation [1].
>>>>>>>
>>>>>>> so which code path adds "vmlinux" to the mods array before this line?
>>>>>>> I could not find it.
>>>>>>
>>>>>> Hello Kazu,
>>>>>>
>>>>>> In kallsyms.c from patch 2, there is the line:
>>>>>> INIT_MOD_SYM(vmlinux, _stext);
>>>>>> This adds a struct ksym_info to the main makedumpfile executable's
>>>>>> array, which requests symbol "_stext" from vmlinux.
>>>>>>
>>>>>> In kallsyms.c "init_kernel_kallsyms()", again from patch 2, the first
>>>>>> step is to call:
>>>>>> register_ksym_section((char *)__start_init_ksyms,
>>>>>> (char *)__stop_init_ksyms))
>>>>>> Which is a function generated by the macro REGISTER_SECTION(). The
>>>>>> implementation will use add_ksym_modname() whens it encounters this
>>>>>> symbol, ensuring that "vmlinux" is part of the modname array.
>>>>>
>>>>> Thanks for the detailed info, yes, it is exactly how "vmlinux" is
>>>>> added to the array.
>>>>
>>>> hmm, maybe I still misread it though..
>>>>
>>>> The init_kernel_kallsyms() is called _after_ check_ksyms_require_modname().
>>>> so I've meant that if no extension adds "vmlinux" to the modname array,
>>>> no one calls it. is it ok?
>>>>
>>>> if (check_ksyms_require_modname("vmlinux", &count)) {
>>>> if (!init_kernel_kallsyms())
>>>
>>> No, even if you create a extension which doesn't require symbols from
>>> "vmlinux", once you load it, the check_ksyms_require_modname() will
>>> still be true and init_kernel_kallsyms() is called.
>>>
>>> The reason is, with the introduction of makedumpfile.ld, and the line
>>> "INIT_MOD_SYM(vmlinux, _stext);" in kallsyms.c, makedumpfile and
>>> extensions have a similar section structure, you can regard
>>> makedumpfile itself as an extension:
>>>
>>> $ readelf -S makedumpfile | grep -E 'ksyms|ktypes'
>>> [25] .init_ksyms PROGBITS 000000000046ee90 0006de90
>>> [26] .init_ktypes PROGBITS 000000000046eeb8 0006deb8
>>> $ readelf -S extensions/sample.so | grep -E 'ksyms|ktypes'
>>> [24] .init_ksyms PROGBITS 0000000000003108 00002108
>>> [25] .init_ktypes PROGBITS 0000000000003110 00002110
>>>
>>> If makedumpfile doesn't load any extensions, then makedumpfile doesn't
>>> need to initialize its .init_ksyms/ktypes section, the behaviour stays
>>> the same as before;
>>> If makedumpfile load at least one extensions, then the extension
>>> subsystem will register all .init_ksyms/ktypes sections, both
>>> extenison's and makedumpfile's.
>>>
>>> This is like, extension say "I need sym1 & sym2 to be ready before I
>>> can run", then makedumpfile say "OK, I got it, but before I can
>>> resolve your sym1 & sym2, I need to resolve some symbol(e.g. vmlinux's
>>> _stext) formyself first". So check_ksyms_require_modname("vmlinux",
>>> &count) will be true.
>>
>> hmm, but as far as I've tested with "extensions/sample.c" on RHEL10.2:
>>
>> 1) add INIT_MOD_SYM(xfs, xfsstats) and GET_MOD_SYM(xfs, xfsstats)
>>
>> ok
>>
>> Loaded extension: /share/tmp/makedumpfile/extensions/sample.so
>> sample.so: The address of xfsstats is: ffffffffc0c0b540 <<--- ok
>> sample.so: The address of init_task is: ffffffffb4412940
>> sample.so: The size of task_struct is: 10240 bytes
>> sample.so: The offset of member mm within task_struct is: 2704 bytes
>> sample.so: The size of member mm within task_struct is: 8 bytes
>> sample.so: Your kernel is using maple tree in mm_struct
>>
>> 2) remove all "vmlinux" entries (only INIT_MOD_SYM(xfs, xfsstats))
>>
>> skipped
>>
>> Loaded extension: /share/tmp/makedumpfile/extensions/sample.so
>> check_required_ksyms_all_resolved: Symbol xfsstats in xfs not found
>> init_extensions: Skip 1th extension
>>
>
> This is a bug which shouldn't happen, thanks for pointing it out.
>
>> 3) restore INIT_MOD_SYM(vmlinux, init_task) and GET_MOD_SYM(vmlinux, init_task)
>>
>> still skipped
>>
>> Loaded extension: /share/tmp/makedumpfile/extensions/sample.so
>> check_required_ksyms_all_resolved: Symbol xfsstats in xfs not found
>> init_extensions: Skip 1th extension
>>
>
> Also a bug. I made a code modification based on the v5 to fix, could you please
> give a try? If no problem I will integrate it with v6.
This patch tested ok and looks good and consistent with the condition checks
in init_kallsyms_btf().
Thanks,
Kazu
>
> diff --git a/btf_info.c b/btf_info.c
> index 1506152..fbb487b 100644
> --- a/btf_info.c
> +++ b/btf_info.c
> @@ -202,10 +202,6 @@ bool init_kernel_btf(void)
> goto out;
> }
>
> - if (!register_ktype_section((char *)__start_init_ktypes,
> - (char *)__stop_init_ktypes))
> - return ret;
> -
> size = stop_btf - start_btf;
> buf = (char *)malloc(size);
> if (!buf) {
> diff --git a/extension.c b/extension.c
> index 190dd9e..276ffb1 100644
> --- a/extension.c
> +++ b/extension.c
> @@ -153,7 +153,7 @@ static void load_extensions(void)
> }
> }
>
> -static bool register_extension_sections(void)
> +static bool register_ksyms_ktypes_sections(void)
> {
> char *start, *stop;
> int i;
> @@ -170,6 +170,18 @@ static bool register_extension_sections(void)
> if (!register_ktype_section(start, stop))
> goto out;
> }
> + /* If no extensions, don't register makedumpfile's section */
> + if (handle_cbs_len > 0) {
> + start = dlsym(NULL, "__start_init_ksyms");
> + stop = dlsym(NULL, "__stop_init_ksyms");
> + if (!register_ksym_section(start, stop))
> + goto out;
> +
> + start = dlsym(NULL, "__start_init_ktypes");
> + stop = dlsym(NULL, "__stop_init_ktypes");
> + if (!register_ktype_section(start, stop))
> + goto out;
> + }
> ret = true;
> out:
> return ret;
> @@ -260,7 +272,7 @@ void init_extensions(void)
> void (*init)(void);
>
> load_extensions();
> - if (!register_extension_sections())
> + if (!register_ksyms_ktypes_sections())
> goto fail;
> if (!init_kallsyms_btf())
> goto fail;
> diff --git a/kallsyms.c b/kallsyms.c
> index f231a06..0037600 100644
> --- a/kallsyms.c
> +++ b/kallsyms.c
> @@ -276,10 +276,6 @@ bool init_kernel_kallsyms(void)
> return ret;
> }
>
> - if (!register_ksym_section((char *)__start_init_ksyms,
> - (char *)__stop_init_ksyms))
> - return ret;
> -
> if (!readmem(VADDR, SYMBOL(kallsyms_num_syms), &kallsyms_num_syms,
> sizeof(kallsyms_num_syms))) {
> ERRMSG("Can't get kallsyms_num_syms!\n");
>
>
>> 4) also restore INIT_MOD_STRUCT_MEMBER(vmlinux, task_struct, mm) and
>> GET_MOD_STRUCT_MEMBER_SSIZE(vmlinux, task_struct, mm)
>>
>> ok
>>
>> Loaded extension: /share/tmp/makedumpfile/extensions/sample.so
>> sample.so: The address of xfsstats is: ffffffffc0c0b540
>> sample.so: The address of init_task is: ffffffffb4412940
>> sample.so: The size of task_struct is: 10240 bytes
>>
>>
>> So, it looks like, with the current condition check in init_kallsyms_btf()
>> (check_ksyms_require_modname and check_ktypes_require_modname),
>> a module needs to use INIT_* for vmlinux's kallsyms and BTF.
>>
>> I'm still missing something..?
>>
>> Thanks,
>> Kazu
More information about the kexec
mailing list