Bug 210643

Summary: libtracefs: Add ways to set the filtering of function tracing
Product: Tools Reporter: Steven Rostedt (rostedt)
Component: Trace-cmd/KernelsharkAssignee: Default virtual assignee for Trace-cmd and kernelshark (tools_tracecmd_kernelshark)
Status: RESOLVED CODE_FIX    
Severity: enhancement CC: sameeruddin.shaik8
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: N/A Tree: Mainline
Regression: No

Description Steven Rostedt 2020-12-11 18:20:59 UTC
Add an API to set filtering of functions:

int tracefs_function_filter(struct tracefs_instance *instance, const char *filter);

Which would write into the set_ftrace_filter file for the instance.

Also have a:

int tracefs_function_notrace(struct tracefs_instance *instance, const char *filter);

That would write into the set_ftrace_notrace file for the instance.

Have a:

int tracefs_function_filter_clear(struct tracefs_instance *instance);

That clears the set_ftrace_filter file.

and a:

int tracefs_function_notrace_clear(struct tracefs_instance *instance);

That clears the set_ftrace_notrace file.
Comment 1 sameer_aaron 2021-01-20 15:47:18 UTC
Hi steve

I wanted to work on this API, are you planning to work on these?

Thanks,
Sameer.
Comment 2 Steven Rostedt 2021-01-20 15:57:41 UTC
Sameer,

We are happy to let you implement these interfaces that are in Bugzilla (I may even add more). Just let us know what you want to work on and we will leave them alone.

-- Steve
Comment 3 sameer_aaron 2021-01-20 16:34:05 UTC
Steve,
For now I will work on above API, once I feel comfortable working with this library, I will try to work on more.
Moreover I am new to open source contribution 
Thanks,
Sameer
Comment 4 sameer_aaron 2021-01-20 16:36:29 UTC
I wanted to appreciate your support for my first patch.
If I am doing things that are not expected please guide me.
Comment 5 Steven Rostedt 2021-01-20 16:56:34 UTC
Will do. And my first bit of advice, let's move this conversation to linux-trace-devel@vger.kernel.org, as it doesn't belong in the bugzilla ;-)

Please subscribe to it too.

  http://vger.kernel.org/vger-lists.html#linux-trace-devel
Comment 6 sameer_aaron 2021-01-22 05:53:03 UTC
okay,

I have already subscribed to the below list


http://vger.kernel.org/vger-lists.html#linux-trace-devel
Comment 7 Steven Rostedt 2021-02-23 16:56:43 UTC
After some discussions on the mailing lists, I found that it is important to establish the requirements that I expect of this API. I'm doing it in the bugzilla instead of the mailing list (but will also forward this to the mailing list), as this is more about the feature request and not about the development of it.

The prototype should be:

 int tracefs_function_filter(struct tracefs_instance *instance,
                             const char * const *filters,
                             const char *module,
                             boolean reset);

If @instance is NULL, the filter for the top level tracing directory is used. Otherwise the filter is for the given instance.

The @filters is an array of strings that holds one or more filters, and the array ends with a NULL pointer.

If @module is set, only apply the filter to functions for a given module. This is ignored if NULL is passed in. I added this to the interface because it is commonly used, and the set_ftrace_filter has a special way to handle it (see more below).

If @reset is set, the function filter for the given instance (or toplevel if @instance is NULL), is cleared before applying the new filter functions. Otherwise, the function filters are appended.

Note on reset being set: This is an important implementation detail. The reset must be done by opening the file with O_WRONLY|O_TRUNC set. And the file is not closed until all the new filters are added. It must not clear the file and close it before setting the new filters. The reason is, if it does, then all functions will start to be traced!

If the function filter has some functions in set_ftrace_filter, and the function tracer is active, then it is only tracing those functions in set_ftrace_filter. If you want to change that set of functions to a new set, you open the set_ftrace_filter file with O_WRONLY|O_TRUNC and add your new functions. On closing the file, the change takes place. The old functions being filtered will no longer be traced, and the new functions being filter will start to be traced.

If the set_ftrace_filter is truncated and closed without setting the new functions, then the function tracer will start tracing *all* functions! That is not what this API should do. This is why it is important that you write the new filters after opening with O_TRUNC and before closing the file descriptor. This is another reason to use an array of filters instead of having the application call this function multiple times with different filters strings.

Now when writing the filters, the following should be done for each filter. Write the filter to set_ftrace_filter file, and if it succeeds, then continue to the next filter. If it does not succeed, then check if it is a regex. If so, then add all the functions that match the regex that are in available_filter_functions.

Note, if @module is not NULL, then before writing the filter strings for the non regex write, append ":mod:@module" to each filter string. That is, if @module is "bridge" and the filter is "br_*", then what should be written into the set_ftrace_filter file is: "br_*:mod:bridge", and the kernel will only apply the "br_*" to the module "bridge". Implementation detail, you can simply write the filter unmodified, then write ":mod:" then write "bridge", before writing any spaces to separate the filters. The kernel will process that as one string "br_*:mod:bridge". This way the function does not need to worry about allocating extra memory and copying the string to append the ":mod:bridge" before writing.

If a regex is used, then the search of available_filter_functions should only look for function names that have the module name behind it. That is, if @module is "bridge" and the filter is ".*switchdev_\\(port\\|fdb\\).*", and @module is set, then the search over available_filter_functions should run the regex only on functions that have a matching module name "[bridge]".
Comment 8 Steven Rostedt 2021-04-05 16:05:03 UTC
The tree at aab0622e915680e39d8f1915b921c9247c05e48f contains all the changes that implement this.