Hi Sameer, I forgot to include you on the Cc for this email. Talking with Tzvetomir, he suggested that I create a more detailed requirement list of what I expect from the tracefs_function_filter() API. Thinking about how I plan on using it, I modified it a little. Namely, I added the "module" parameter. Below is the requirements for the function. If you have any questions, feel free to email Tzvetomir and myself. Thanks, -- Steve On Tue, 23 Feb 2021 12:01:30 -0500 Steven Rostedt <rostedt@xxxxxxxxxxx> wrote: > Forwarding this to the mailing list, as well. Any discussions on this may > be easier to discuss here than on the bugzilla. > > -- Steve > > > https://bugzilla.kernel.org/show_bug.cgi?id=210643 > > --- Comment #7 from Steven Rostedt (rostedt@xxxxxxxxxxx) --- > 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]". >