linux/samples/ftrace/ftrace-direct-modify.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2#include <linux/module.h>
   3#include <linux/kthread.h>
   4#include <linux/ftrace.h>
   5
   6void my_direct_func1(void)
   7{
   8        trace_printk("my direct func1\n");
   9}
  10
  11void my_direct_func2(void)
  12{
  13        trace_printk("my direct func2\n");
  14}
  15
  16extern void my_tramp1(void *);
  17extern void my_tramp2(void *);
  18
  19static unsigned long my_ip = (unsigned long)schedule;
  20
  21asm (
  22"       .pushsection    .text, \"ax\", @progbits\n"
  23"       .type           my_tramp1, @function\n"
  24"       .globl          my_tramp1\n"
  25"   my_tramp1:"
  26"       pushq %rbp\n"
  27"       movq %rsp, %rbp\n"
  28"       call my_direct_func1\n"
  29"       leave\n"
  30"       .size           my_tramp1, .-my_tramp1\n"
  31"       ret\n"
  32"       .type           my_tramp2, @function\n"
  33"       .globl          my_tramp2\n"
  34"   my_tramp2:"
  35"       pushq %rbp\n"
  36"       movq %rsp, %rbp\n"
  37"       call my_direct_func2\n"
  38"       leave\n"
  39"       ret\n"
  40"       .size           my_tramp2, .-my_tramp2\n"
  41"       .popsection\n"
  42);
  43
  44static unsigned long my_tramp = (unsigned long)my_tramp1;
  45static unsigned long tramps[2] = {
  46        (unsigned long)my_tramp1,
  47        (unsigned long)my_tramp2,
  48};
  49
  50static int simple_thread(void *arg)
  51{
  52        static int t;
  53        int ret = 0;
  54
  55        while (!kthread_should_stop()) {
  56                set_current_state(TASK_INTERRUPTIBLE);
  57                schedule_timeout(2 * HZ);
  58
  59                if (ret)
  60                        continue;
  61                t ^= 1;
  62                ret = modify_ftrace_direct(my_ip, my_tramp, tramps[t]);
  63                if (!ret)
  64                        my_tramp = tramps[t];
  65                WARN_ON_ONCE(ret);
  66        }
  67
  68        return 0;
  69}
  70
  71static struct task_struct *simple_tsk;
  72
  73static int __init ftrace_direct_init(void)
  74{
  75        int ret;
  76
  77        ret = register_ftrace_direct(my_ip, my_tramp);
  78        if (!ret)
  79                simple_tsk = kthread_run(simple_thread, NULL, "event-sample-fn");
  80        return ret;
  81}
  82
  83static void __exit ftrace_direct_exit(void)
  84{
  85        kthread_stop(simple_tsk);
  86        unregister_ftrace_direct(my_ip, my_tramp);
  87}
  88
  89module_init(ftrace_direct_init);
  90module_exit(ftrace_direct_exit);
  91
  92MODULE_AUTHOR("Steven Rostedt");
  93MODULE_DESCRIPTION("Example use case of using modify_ftrace_direct()");
  94MODULE_LICENSE("GPL");
  95