1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2016 Wang Nan <wangnan0@huawei.com>
6 * Copyright (C) 2016 Huawei Inc.
12 #include <linux/err.h>
13 #include <linux/kernel.h>
14 #include "util/util.h"
15 #include "util/debug.h"
16 #include "util/perf-hooks.h"
18 static sigjmp_buf jmpbuf
;
19 static const struct perf_hook_desc
*current_perf_hook
;
21 void perf_hooks__invoke(const struct perf_hook_desc
*desc
)
23 if (!(desc
&& desc
->p_hook_func
&& *desc
->p_hook_func
))
26 if (sigsetjmp(jmpbuf
, 1)) {
27 pr_warning("Fatal error (SEGFAULT) in perf hook '%s'\n",
29 *(current_perf_hook
->p_hook_func
) = NULL
;
31 current_perf_hook
= desc
;
32 (**desc
->p_hook_func
)(desc
->hook_ctx
);
34 current_perf_hook
= NULL
;
37 void perf_hooks__recover(void)
39 if (current_perf_hook
)
40 siglongjmp(jmpbuf
, 1);
43 #define PERF_HOOK(name) \
44 perf_hook_func_t __perf_hook_func_##name = NULL; \
45 struct perf_hook_desc __perf_hook_desc_##name = \
46 {.hook_name = #name, \
47 .p_hook_func = &__perf_hook_func_##name, \
49 #include "perf-hooks-list.h"
52 #define PERF_HOOK(name) \
53 &__perf_hook_desc_##name,
55 static struct perf_hook_desc
*perf_hooks
[] = {
56 #include "perf-hooks-list.h"
60 int perf_hooks__set_hook(const char *hook_name
,
61 perf_hook_func_t hook_func
,
66 for (i
= 0; i
< ARRAY_SIZE(perf_hooks
); i
++) {
67 if (strcmp(hook_name
, perf_hooks
[i
]->hook_name
) != 0)
70 if (*(perf_hooks
[i
]->p_hook_func
))
71 pr_warning("Overwrite existing hook: %s\n", hook_name
);
72 *(perf_hooks
[i
]->p_hook_func
) = hook_func
;
73 perf_hooks
[i
]->hook_ctx
= hook_ctx
;
79 perf_hook_func_t
perf_hooks__get_hook(const char *hook_name
)
83 for (i
= 0; i
< ARRAY_SIZE(perf_hooks
); i
++) {
84 if (strcmp(hook_name
, perf_hooks
[i
]->hook_name
) != 0)
87 return *(perf_hooks
[i
]->p_hook_func
);
89 return ERR_PTR(-ENOENT
);