mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 16:54:20 +08:00
d697bad588
Replaced patches are removed from the stack when the transition is finished. It means that Nop structures will never be needed again and can be removed. Why should we care? + Nop structures give the impression that the function is patched even though the ftrace handler has no effect. + Ftrace handlers do not come for free. They cause slowdown that might be visible in some workloads. The ftrace-related slowdown might actually be the reason why the function is no longer patched in the new cumulative patch. One would expect that cumulative patch would help solve these problems as well. + Cumulative patches are supposed to replace any earlier version of the patch. The amount of NOPs depends on which version was replaced. This multiplies the amount of scenarios that might happen. One might say that NOPs are innocent. But there are even optimized NOP instructions for different processors, for example, see arch/x86/kernel/alternative.c. And klp_ftrace_handler() is much more complicated. + It sounds natural to clean up a mess that is no longer needed. It could only be worse if we do not do it. This patch allows to unpatch and free the dynamic structures independently when the transition finishes. The free part is a bit tricky because kobject free callbacks are called asynchronously. We could not wait for them easily. Fortunately, we do not have to. Any further access can be avoided by removing them from the dynamic lists. Signed-off-by: Petr Mladek <pmladek@suse.com> Acked-by: Miroslav Benes <mbenes@suse.cz> Acked-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
36 lines
1.1 KiB
C
36 lines
1.1 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _LIVEPATCH_PATCH_H
|
|
#define _LIVEPATCH_PATCH_H
|
|
|
|
#include <linux/livepatch.h>
|
|
#include <linux/list.h>
|
|
#include <linux/ftrace.h>
|
|
|
|
/**
|
|
* struct klp_ops - structure for tracking registered ftrace ops structs
|
|
*
|
|
* A single ftrace_ops is shared between all enabled replacement functions
|
|
* (klp_func structs) which have the same old_func. This allows the switch
|
|
* between function versions to happen instantaneously by updating the klp_ops
|
|
* struct's func_stack list. The winner is the klp_func at the top of the
|
|
* func_stack (front of the list).
|
|
*
|
|
* @node: node for the global klp_ops list
|
|
* @func_stack: list head for the stack of klp_func's (active func is on top)
|
|
* @fops: registered ftrace ops struct
|
|
*/
|
|
struct klp_ops {
|
|
struct list_head node;
|
|
struct list_head func_stack;
|
|
struct ftrace_ops fops;
|
|
};
|
|
|
|
struct klp_ops *klp_find_ops(void *old_func);
|
|
|
|
int klp_patch_object(struct klp_object *obj);
|
|
void klp_unpatch_object(struct klp_object *obj);
|
|
void klp_unpatch_objects(struct klp_patch *patch);
|
|
void klp_unpatch_objects_dynamic(struct klp_patch *patch);
|
|
|
|
#endif /* _LIVEPATCH_PATCH_H */
|