xref: /openbmc/linux/Documentation/trace/fprobe.rst (revision 213f891525c222e8ed145ce1ce7ae1f47921cb9c)
1aba09b44SMasami Hiramatsu.. SPDX-License-Identifier: GPL-2.0
2aba09b44SMasami Hiramatsu
3aba09b44SMasami Hiramatsu==================================
4aba09b44SMasami HiramatsuFprobe - Function entry/exit probe
5aba09b44SMasami Hiramatsu==================================
6aba09b44SMasami Hiramatsu
7aba09b44SMasami Hiramatsu.. Author: Masami Hiramatsu <mhiramat@kernel.org>
8aba09b44SMasami Hiramatsu
9aba09b44SMasami HiramatsuIntroduction
10aba09b44SMasami Hiramatsu============
11aba09b44SMasami Hiramatsu
12aba09b44SMasami HiramatsuFprobe is a function entry/exit probe mechanism based on ftrace.
13aba09b44SMasami HiramatsuInstead of using ftrace full feature, if you only want to attach callbacks
14aba09b44SMasami Hiramatsuon function entry and exit, similar to the kprobes and kretprobes, you can
15aba09b44SMasami Hiramatsuuse fprobe. Compared with kprobes and kretprobes, fprobe gives faster
16aba09b44SMasami Hiramatsuinstrumentation for multiple functions with single handler. This document
17aba09b44SMasami Hiramatsudescribes how to use fprobe.
18aba09b44SMasami Hiramatsu
19aba09b44SMasami HiramatsuThe usage of fprobe
20aba09b44SMasami Hiramatsu===================
21aba09b44SMasami Hiramatsu
22aba09b44SMasami HiramatsuThe fprobe is a wrapper of ftrace (+ kretprobe-like return callback) to
23aba09b44SMasami Hiramatsuattach callbacks to multiple function entry and exit. User needs to set up
24aba09b44SMasami Hiramatsuthe `struct fprobe` and pass it to `register_fprobe()`.
25aba09b44SMasami Hiramatsu
26aba09b44SMasami HiramatsuTypically, `fprobe` data structure is initialized with the `entry_handler`
27aba09b44SMasami Hiramatsuand/or `exit_handler` as below.
28aba09b44SMasami Hiramatsu
29aba09b44SMasami Hiramatsu.. code-block:: c
30aba09b44SMasami Hiramatsu
31aba09b44SMasami Hiramatsu struct fprobe fp = {
32aba09b44SMasami Hiramatsu        .entry_handler  = my_entry_callback,
33aba09b44SMasami Hiramatsu        .exit_handler   = my_exit_callback,
34aba09b44SMasami Hiramatsu };
35aba09b44SMasami Hiramatsu
36aba09b44SMasami HiramatsuTo enable the fprobe, call one of register_fprobe(), register_fprobe_ips(), and
37aba09b44SMasami Hiramatsuregister_fprobe_syms(). These functions register the fprobe with different types
38aba09b44SMasami Hiramatsuof parameters.
39aba09b44SMasami Hiramatsu
40aba09b44SMasami HiramatsuThe register_fprobe() enables a fprobe by function-name filters.
41aba09b44SMasami HiramatsuE.g. this enables @fp on "func*()" function except "func2()".::
42aba09b44SMasami Hiramatsu
43aba09b44SMasami Hiramatsu  register_fprobe(&fp, "func*", "func2");
44aba09b44SMasami Hiramatsu
45aba09b44SMasami HiramatsuThe register_fprobe_ips() enables a fprobe by ftrace-location addresses.
46aba09b44SMasami HiramatsuE.g.
47aba09b44SMasami Hiramatsu
48aba09b44SMasami Hiramatsu.. code-block:: c
49aba09b44SMasami Hiramatsu
50aba09b44SMasami Hiramatsu  unsigned long ips[] = { 0x.... };
51aba09b44SMasami Hiramatsu
52aba09b44SMasami Hiramatsu  register_fprobe_ips(&fp, ips, ARRAY_SIZE(ips));
53aba09b44SMasami Hiramatsu
54aba09b44SMasami HiramatsuAnd the register_fprobe_syms() enables a fprobe by symbol names.
55aba09b44SMasami HiramatsuE.g.
56aba09b44SMasami Hiramatsu
57aba09b44SMasami Hiramatsu.. code-block:: c
58aba09b44SMasami Hiramatsu
59aba09b44SMasami Hiramatsu  char syms[] = {"func1", "func2", "func3"};
60aba09b44SMasami Hiramatsu
61aba09b44SMasami Hiramatsu  register_fprobe_syms(&fp, syms, ARRAY_SIZE(syms));
62aba09b44SMasami Hiramatsu
63aba09b44SMasami HiramatsuTo disable (remove from functions) this fprobe, call::
64aba09b44SMasami Hiramatsu
65aba09b44SMasami Hiramatsu  unregister_fprobe(&fp);
66aba09b44SMasami Hiramatsu
67aba09b44SMasami HiramatsuYou can temporally (soft) disable the fprobe by::
68aba09b44SMasami Hiramatsu
69aba09b44SMasami Hiramatsu  disable_fprobe(&fp);
70aba09b44SMasami Hiramatsu
71aba09b44SMasami Hiramatsuand resume by::
72aba09b44SMasami Hiramatsu
73aba09b44SMasami Hiramatsu  enable_fprobe(&fp);
74aba09b44SMasami Hiramatsu
75aba09b44SMasami HiramatsuThe above is defined by including the header::
76aba09b44SMasami Hiramatsu
77aba09b44SMasami Hiramatsu  #include <linux/fprobe.h>
78aba09b44SMasami Hiramatsu
79aba09b44SMasami HiramatsuSame as ftrace, the registered callbacks will start being called some time
80aba09b44SMasami Hiramatsuafter the register_fprobe() is called and before it returns. See
81aba09b44SMasami Hiramatsu:file:`Documentation/trace/ftrace.rst`.
82aba09b44SMasami Hiramatsu
83aba09b44SMasami HiramatsuAlso, the unregister_fprobe() will guarantee that the both enter and exit
84aba09b44SMasami Hiramatsuhandlers are no longer being called by functions after unregister_fprobe()
85aba09b44SMasami Hiramatsureturns as same as unregister_ftrace_function().
86aba09b44SMasami Hiramatsu
87aba09b44SMasami HiramatsuThe fprobe entry/exit handler
88aba09b44SMasami Hiramatsu=============================
89aba09b44SMasami Hiramatsu
908be098a9SMasami Hiramatsu (Google)The prototype of the entry/exit callback function are as follows:
91aba09b44SMasami Hiramatsu
92aba09b44SMasami Hiramatsu.. code-block:: c
93aba09b44SMasami Hiramatsu
94*2a86ac30SMasami Hiramatsu (Google) int entry_callback(struct fprobe *fp, unsigned long entry_ip, unsigned long ret_ip, struct pt_regs *regs, void *entry_data);
95aba09b44SMasami Hiramatsu
96*2a86ac30SMasami Hiramatsu (Google) void exit_callback(struct fprobe *fp, unsigned long entry_ip, unsigned long ret_ip, struct pt_regs *regs, void *entry_data);
978be098a9SMasami Hiramatsu (Google)
988be098a9SMasami Hiramatsu (Google)Note that the @entry_ip is saved at function entry and passed to exit handler.
998be098a9SMasami Hiramatsu (Google)If the entry callback function returns !0, the corresponding exit callback will be cancelled.
100aba09b44SMasami Hiramatsu
101aba09b44SMasami Hiramatsu@fp
102aba09b44SMasami Hiramatsu        This is the address of `fprobe` data structure related to this handler.
103aba09b44SMasami Hiramatsu        You can embed the `fprobe` to your data structure and get it by
104aba09b44SMasami Hiramatsu        container_of() macro from @fp. The @fp must not be NULL.
105aba09b44SMasami Hiramatsu
106aba09b44SMasami Hiramatsu@entry_ip
107aba09b44SMasami Hiramatsu        This is the ftrace address of the traced function (both entry and exit).
108aba09b44SMasami Hiramatsu        Note that this may not be the actual entry address of the function but
109aba09b44SMasami Hiramatsu        the address where the ftrace is instrumented.
110aba09b44SMasami Hiramatsu
111*2a86ac30SMasami Hiramatsu (Google)@ret_ip
112*2a86ac30SMasami Hiramatsu (Google)        This is the return address that the traced function will return to,
113*2a86ac30SMasami Hiramatsu (Google)        somewhere in the caller. This can be used at both entry and exit.
114*2a86ac30SMasami Hiramatsu (Google)
115aba09b44SMasami Hiramatsu@regs
116aba09b44SMasami Hiramatsu        This is the `pt_regs` data structure at the entry and exit. Note that
117aba09b44SMasami Hiramatsu        the instruction pointer of @regs may be different from the @entry_ip
118aba09b44SMasami Hiramatsu        in the entry_handler. If you need traced instruction pointer, you need
119aba09b44SMasami Hiramatsu        to use @entry_ip. On the other hand, in the exit_handler, the instruction
120d56b699dSBjorn Helgaas        pointer of @regs is set to the current return address.
121aba09b44SMasami Hiramatsu
1228be098a9SMasami Hiramatsu (Google)@entry_data
1238be098a9SMasami Hiramatsu (Google)        This is a local storage to share the data between entry and exit handlers.
1248be098a9SMasami Hiramatsu (Google)        This storage is NULL by default. If the user specify `exit_handler` field
1258be098a9SMasami Hiramatsu (Google)        and `entry_data_size` field when registering the fprobe, the storage is
1268be098a9SMasami Hiramatsu (Google)        allocated and passed to both `entry_handler` and `exit_handler`.
1278be098a9SMasami Hiramatsu (Google)
128aba09b44SMasami HiramatsuShare the callbacks with kprobes
129aba09b44SMasami Hiramatsu================================
130aba09b44SMasami Hiramatsu
131aba09b44SMasami HiramatsuSince the recursion safeness of the fprobe (and ftrace) is a bit different
132aba09b44SMasami Hiramatsufrom the kprobes, this may cause an issue if user wants to run the same
133aba09b44SMasami Hiramatsucode from the fprobe and the kprobes.
134aba09b44SMasami Hiramatsu
135aba09b44SMasami HiramatsuKprobes has per-cpu 'current_kprobe' variable which protects the kprobe
136aba09b44SMasami Hiramatsuhandler from recursion in all cases. On the other hand, fprobe uses
137aba09b44SMasami Hiramatsuonly ftrace_test_recursion_trylock(). This allows interrupt context to
138aba09b44SMasami Hiramatsucall another (or same) fprobe while the fprobe user handler is running.
139aba09b44SMasami Hiramatsu
140aba09b44SMasami HiramatsuThis is not a matter if the common callback code has its own recursion
141aba09b44SMasami Hiramatsudetection, or it can handle the recursion in the different contexts
142aba09b44SMasami Hiramatsu(normal/interrupt/NMI.)
143aba09b44SMasami HiramatsuBut if it relies on the 'current_kprobe' recursion lock, it has to check
144aba09b44SMasami Hiramatsukprobe_running() and use kprobe_busy_*() APIs.
145aba09b44SMasami Hiramatsu
146aba09b44SMasami HiramatsuFprobe has FPROBE_FL_KPROBE_SHARED flag to do this. If your common callback
147aba09b44SMasami Hiramatsucode will be shared with kprobes, please set FPROBE_FL_KPROBE_SHARED
148aba09b44SMasami Hiramatsu*before* registering the fprobe, like:
149aba09b44SMasami Hiramatsu
150aba09b44SMasami Hiramatsu.. code-block:: c
151aba09b44SMasami Hiramatsu
152aba09b44SMasami Hiramatsu fprobe.flags = FPROBE_FL_KPROBE_SHARED;
153aba09b44SMasami Hiramatsu
154aba09b44SMasami Hiramatsu register_fprobe(&fprobe, "func*", NULL);
155aba09b44SMasami Hiramatsu
156aba09b44SMasami HiramatsuThis will protect your common callback from the nested call.
157aba09b44SMasami Hiramatsu
158aba09b44SMasami HiramatsuThe missed counter
159aba09b44SMasami Hiramatsu==================
160aba09b44SMasami Hiramatsu
161aba09b44SMasami HiramatsuThe `fprobe` data structure has `fprobe::nmissed` counter field as same as
162aba09b44SMasami Hiramatsukprobes.
163aba09b44SMasami HiramatsuThis counter counts up when;
164aba09b44SMasami Hiramatsu
165aba09b44SMasami Hiramatsu - fprobe fails to take ftrace_recursion lock. This usually means that a function
166aba09b44SMasami Hiramatsu   which is traced by other ftrace users is called from the entry_handler.
167aba09b44SMasami Hiramatsu
168aba09b44SMasami Hiramatsu - fprobe fails to setup the function exit because of the shortage of rethook
169aba09b44SMasami Hiramatsu   (the shadow stack for hooking the function return.)
170aba09b44SMasami Hiramatsu
171aba09b44SMasami HiramatsuThe `fprobe::nmissed` field counts up in both cases. Therefore, the former
172aba09b44SMasami Hiramatsuskips both of entry and exit callback and the latter skips the exit
173aba09b44SMasami Hiramatsucallback, but in both case the counter will increase by 1.
174aba09b44SMasami Hiramatsu
175aba09b44SMasami HiramatsuNote that if you set the FTRACE_OPS_FL_RECURSION and/or FTRACE_OPS_FL_RCU to
176aba09b44SMasami Hiramatsu`fprobe::ops::flags` (ftrace_ops::flags) when registering the fprobe, this
177aba09b44SMasami Hiramatsucounter may not work correctly, because ftrace skips the fprobe function which
178aba09b44SMasami Hiramatsuincrease the counter.
179aba09b44SMasami Hiramatsu
180aba09b44SMasami Hiramatsu
181aba09b44SMasami HiramatsuFunctions and structures
182aba09b44SMasami Hiramatsu========================
183aba09b44SMasami Hiramatsu
184aba09b44SMasami Hiramatsu.. kernel-doc:: include/linux/fprobe.h
185aba09b44SMasami Hiramatsu.. kernel-doc:: kernel/trace/fprobe.c
186aba09b44SMasami Hiramatsu
187