-
Notifications
You must be signed in to change notification settings - Fork 304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
create-diff-object: __patchable_function_entries section support #1415
base: master
Are you sure you want to change the base?
Conversation
422b699
to
a527949
Compare
a527949
to
14c03c4
Compare
Tested internally (beaker job #10108322) on s390x and ppc64le running early rhel-10 kernel. Also tested by Amazon on top of the rest of the aarch64 arch support code. |
14c03c4
to
6dc0961
Compare
kpatch-build/create-diff-object.c
Outdated
* sections for each symbols. | ||
*/ | ||
kelf->has_pfe = true; | ||
sec = find_section_by_name(&kelf->sections, "__patchable_function_entries"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has no purpose apparently?
Also since this function is very similar to kpatch_create_mcount_sections() it would be a good idea to mirror that logic as much as possible so it's easier to review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, looks like sec
and relasec
assignments are just overwritten here.
With respect to kpatch_create_mcount_sections() - yes, ideally there will be a single function, but I found it much easier to debug and review a standalone copy, at least to start with. Once the pfe functionality is set (and the commonality determined), I can merge the two functions back together.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They don't necessarily need to be combined into a single function, if it's easier to keep them apart. I was just looking for more symmetry between the two functions so it's easier to see they're correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The latest version combines them into a single kpatch_create_ftrace_callsite_sections()
with only two if (pfe)
conditional blocks.
kpatch-build/create-diff-object.c
Outdated
} | ||
|
||
/* Allocate __patchable_function_entries for symbol */ | ||
sec = create_section_pair(kelf, "__patchable_function_entries", sizeof(void *), 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why "1" instead of "nr"? Also this should be up higher (so it mirrors the mcount version of the function).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unlike the combined mcount section, we're creating a pfe section per function, so there's a new 1 entry pair created every time through the loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah... is that really necessary though? can they just be placed in a single section?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure, but I figured I would try to mimic a kernel build object as closely as possible to avoid any toolchain surprises.
6dc0961
to
c1472d5
Compare
v2:
|
kpatch-build/create-diff-object.c
Outdated
* We will create separate __patchable_function_entries | ||
* sections for each symbols. | ||
*/ | ||
kelf->has_pfe = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think it's simpler (and easier to converge with the mcount stuff) to just make a single section. It should be harmless.
kpatch-build/create-diff-object.c
Outdated
|
||
/* __patchable_function_entries relocates off the section symbol */ | ||
section_sym = find_symbol_by_name(&kelf->symbols, sym->sec->name); | ||
pfe_rela->sym = section_sym; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure there's no need to use the section symbol, either way it points to the same thing in the code. Regardless the find_symbol_by_name() isn't needed, the section symbol is already in sym->sec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is another instance of matching the input kernel objects (as reported by readelf --relocs
).
kpatch-build/create-diff-object.c
Outdated
* Create a .rela__patchable_function_entries entry which also points to it. | ||
*/ | ||
ALLOC_LINK(pfe_rela, &relasec->relas); | ||
struct symbol *section_sym; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Variables should be defined at the beginning of the block
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch.
kpatch-build/kpatch-elf.c
Outdated
if (sym->sec->pfe) { | ||
sym->sec->pfe->sh.sh_link = sym->sec->index; | ||
if (sym->sec->pfe->rela) | ||
sym->sec->pfe->rela->sh.sh_info = sym->sec->index; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This last part seems wrong, .rela__patchable_function_entries
sh_info should point to its __patchable_function_entries
section.
And anyway this gets overwritten by the code in main() which does that, right after calling this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's overwritten, I'll just remove it.
The __mcount_loc section contains the addresses of patchable ftrace sites which is used by the ftrace infrastructure in the kernel to create a list of tracable functions and to know where to patch to enable tracing of them. On some kernel configurations, section is called __patchable_function_entries and is generated by the compiler. Either of __mcount_loc or __patchable_function_entries is recognised by the kernel but for these configurations, use __patchable_function_entries as it is what is expected. The x86_64 arch is special (of course). Unlike other arches (ppc64le and aarch64) a x86_64 kernel built with -fpatchable-function-entry will generate nops AND create rela__patchable_function_entries for functions even marked as notrace. For this arch, always create __mount_loc sections and rely on __fentry__ relocations to indicate ftrace call sites. Note: this patch is a refactoring of original code by Pete Swain <swine@google.com> for aarch64. At the same time, this version squashes several follow up commits from him and zimao <zimao@microsoft.com>. The intent is minimize the eventual changeset for aarch64 support now that other arches are making use of __patchable_function_entries sections. Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
948f93e
to
d8b1708
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I think my latest force pushes may have screwed up my github replies to your earlier comments. I'll try to find those and summarize in another comment that summarizes the latest updates. Sorry about that.)
kpatch-build/create-diff-object.c
Outdated
sym->sec->pfe = sec; | ||
|
||
/* | ||
* 'rela' points to the patchable function entry |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, shall I update this in a follow up commit that separates pfe code from cleanup?
kpatch-build/create-diff-object.c
Outdated
* Create a .rela__patchable_function_entries entry which also points to it. | ||
*/ | ||
ALLOC_LINK(pfe_rela, &relasec->relas); | ||
struct symbol *section_sym; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch.
kpatch-build/kpatch-elf.c
Outdated
if (sym->sec->pfe) { | ||
sym->sec->pfe->sh.sh_link = sym->sec->index; | ||
if (sym->sec->pfe->rela) | ||
sym->sec->pfe->rela->sh.sh_info = sym->sec->index; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's overwritten, I'll just remove it.
list_for_each_entry(rela, &sym->sec->rela->relas, list) { | ||
if (!strcmp(rela->sym->name, "_mcount")) { | ||
sym->has_func_profiling = 1; | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at a ppc64le object file, I don't think it's the first rela:
Relocation section '.rela.text.meminfo_proc_open' at offset 0x1698 contains 6 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000000 000000220000002c R_PPC64_REL64 0000000000000000 .TOC. - 8
0000000000000008 0000000000000076 R_PPC64_ENTRY 0
0000000000000014 000000330000000a R_PPC64_REL24 0000000000000000 _mcount + 0
0000000000000028 0000000800000032 R_PPC64_TOC16_HA 0000000000000000 .toc + 10
0000000000000030 0000000800000040 R_PPC64_TOC16_LO_DS 0000000000000000 .toc + 10
0000000000000034 000000320000000a R_PPC64_REL24 0000000000000000 single_open + 0
Though maybe some other assumption could be made (considering global/local entry and TOC relas)?
v3:
Sorry again for making the review a hash. GitHub hides/buries earlier comments when a subsequent push removes the associated code. |
I'd disagree with both points, pfe/mcount_loc are quite simple and should be bug-free at this point, especially with mostly shared code. More robust/readable code is more important than hypothetical (and rare for this code IMO) debugging. I don't see how that would help much with debugging anyway, as the layouts of these sections are dirt simple. But I defer to you.
No worries, it's one of github's quirks and the comments can be shown by unhiding the "resolved" comments. The above summary is actually pretty helpful, but not necessary. BTW I think you forgot to move 'pfe' to struct symbol? |
|
The __mcount_loc section contains the addresses of patchable ftrace sites which is used by the ftrace infrastructure in the kernel to create a list of tracable functions and to know where to patch to enable tracing of them. On some kernel configurations, section is called __patchable_function_entries and is generated by the compiler. Either of __mcount_loc or __patchable_function_entries is recognised by the kernel but for these configurations, use __patchable_function_entries as it is what is expected.
The x86_64 arch is special (of course). Unlike other arches (ppc64le and aarch64) a x86_64 kernel built with -fpatchable-function-entry will generate nops AND create rela__patchable_function_entries for functions even marked as notrace. For this arch, always create __mount_loc sections and rely on fentry relocations to indicate ftrace call sites.
Note: this patch is a non-arch translation of original code by Pete Swain swine@google.com for aarch64. At the same time, this version squashes several follow up commits from him and zimao zimao@microsoft.com. The intent is minimize the eventual changeset for aarch64 support now that other arches are making use of __patchable_function_entries sections.