lkml.org 
[lkml]   [2019]   [Nov]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectRe: [PATCHv2 1/8] ftrace: add ftrace_init_nop()
    Date
    Hi Mark,

    On 10/29/19 10:28 PM, Mark Rutland wrote:
    > Architectures may need to perform special initialization of ftrace
    > callsites, and today they do so by special-casing ftrace_make_nop() when
    > the expected branch address is MCOUNT_ADDR. In some cases (e.g. for
    > patchable-function-entry), we don't have an mcount-like symbol and don't
    s/an mcount/a mcount.
    > want a synthetic MCOUNT_ADDR, but we may need to perform some
    > initialization of callsites.
    >
    > To make it possible to separate initialization from runtime
    > modification, and to handle cases without an mcount-like symbol, this
    Same as above.
    > patch adds an optional ftrace_init_nop() function that architectures can
    > implement, which does not pass a branch address.
    >
    > Where an architecture does not provide ftrace_init_nop(), we will fall
    > back to the existing behaviour of calling ftrace_make_nop() with
    > MCOUNT_ADDR.
    >
    > At the same time, ftrace_code_disable() is renamed to
    > ftrace_nop_initialize() to make it clearer that it is intended to
    > intialize a callsite into a disabled state, and is not for disabling a
    > callsite that has been runtime enabled. The kerneldoc description of rec
    > arguments is updated to cover non-mcount callsites.
    >
    > Signed-off-by: Mark Rutland <mark.rutland@arm.com>
    > Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
    > Cc: Ingo Molnar <mingo@redhat.com>
    > Cc: Steven Rostedt <rostedt@goodmis.org>
    > Cc: Torsten Duwe <duwe@suse.de>
    > ---
    > include/linux/ftrace.h | 35 ++++++++++++++++++++++++++++++++---
    > kernel/trace/ftrace.c | 6 +++---
    > 2 files changed, 35 insertions(+), 6 deletions(-)
    >
    > diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
    > index 8a8cb3c401b2..9867d90d635e 100644
    > --- a/include/linux/ftrace.h
    > +++ b/include/linux/ftrace.h
    > @@ -499,7 +499,7 @@ static inline int ftrace_disable_ftrace_graph_caller(void) { return 0; }
    > /**
    > * ftrace_make_nop - convert code into nop
    > * @mod: module structure if called by module load initialization
    > - * @rec: the mcount call site record
    > + * @rec: the call site record (e.g. mcount/fentry)
    > * @addr: the address that the call site should be calling
    > *
    > * This is a very sensitive operation and great care needs
    > @@ -520,9 +520,38 @@ static inline int ftrace_disable_ftrace_graph_caller(void) { return 0; }
    > extern int ftrace_make_nop(struct module *mod,
    > struct dyn_ftrace *rec, unsigned long addr);
    >
    > +
    > +/**
    > + * ftrace_init_nop - initialize a nop call site
    > + * @mod: module structure if called by module load initialization
    > + * @rec: the call site record (e.g. mcount/fentry)
    > + *
    > + * This is a very sensitive operation and great care needs
    > + * to be taken by the arch. The operation should carefully
    > + * read the location, check to see if what is read is indeed
    > + * what we expect it to be, and then on success of the compare,
    > + * it should write to the location.
    > + *
    > + * The code segment at @rec->ip should contain the contents created by
    > + * the compiler
    Nit: Will it be better to write it as "@rec->ip should store the
    adjusted ftrace entry address of the call site" or something like that.
    > + *
    > + * Return must be:
    > + * 0 on success
    > + * -EFAULT on error reading the location
    > + * -EINVAL on a failed compare of the contents
    > + * -EPERM on error writing to the location
    > + * Any other value will be considered a failure.
    > + */
    > +#ifndef ftrace_init_nop
    > +static inline int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
    > +{
    > + return ftrace_make_nop(mod, rec, MCOUNT_ADDR);
    > +}
    > +#endif
    > +
    Now that ftrace_init_nop is also an arch implemented function so it may
    be added in Documentation/trace/ftrace-design.rst along with
    ftrace_make_nop.
    In general also, adding some description about patchable-function-entry
    in kernel Documentation will be useful.

    Thanks,
    Amit Daniel
    > /**
    > * ftrace_make_call - convert a nop call site into a call to addr
    > - * @rec: the mcount call site record
    > + * @rec: the call site record (e.g. mcount/fentry)
    > * @addr: the address that the call site should call
    > *
    > * This is a very sensitive operation and great care needs
    > @@ -545,7 +574,7 @@ extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr);
    > #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
    > /**
    > * ftrace_modify_call - convert from one addr to another (no nop)
    > - * @rec: the mcount call site record
    > + * @rec: the call site record (e.g. mcount/fentry)
    > * @old_addr: the address expected to be currently called to
    > * @addr: the address to change to
    > *
    > diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
    > index f296d89be757..5259d4dea675 100644
    > --- a/kernel/trace/ftrace.c
    > +++ b/kernel/trace/ftrace.c
    > @@ -2494,14 +2494,14 @@ struct dyn_ftrace *ftrace_rec_iter_record(struct ftrace_rec_iter *iter)
    > }
    >
    > static int
    > -ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec)
    > +ftrace_nop_initialize(struct module *mod, struct dyn_ftrace *rec)
    > {
    > int ret;
    >
    > if (unlikely(ftrace_disabled))
    > return 0;
    >
    > - ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
    > + ret = ftrace_init_nop(mod, rec);
    > if (ret) {
    > ftrace_bug_type = FTRACE_BUG_INIT;
    > ftrace_bug(ret, rec);
    > @@ -2943,7 +2943,7 @@ static int ftrace_update_code(struct module *mod, struct ftrace_page *new_pgs)
    > * to the NOP instructions.
    > */
    > if (!__is_defined(CC_USING_NOP_MCOUNT) &&
    > - !ftrace_code_disable(mod, p))
    > + !ftrace_nop_initialize(mod, p))
    > break;
    >
    > update_cnt++;
    >

    \
     
     \ /
      Last update: 2019-11-02 13:20    [W:3.596 / U:0.484 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site