at v5.6 3.3 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2#include <linux/module.h> 3#include <linux/kthread.h> 4#include <linux/trace.h> 5#include <linux/trace_events.h> 6#include <linux/timer.h> 7#include <linux/err.h> 8#include <linux/jiffies.h> 9 10/* 11 * Any file that uses trace points, must include the header. 12 * But only one file, must include the header by defining 13 * CREATE_TRACE_POINTS first. This will make the C code that 14 * creates the handles for the trace points. 15 */ 16#define CREATE_TRACE_POINTS 17#include "sample-trace-array.h" 18 19struct trace_array *tr; 20static void mytimer_handler(struct timer_list *unused); 21static struct task_struct *simple_tsk; 22 23/* 24 * mytimer: Timer setup to disable tracing for event "sample_event". This 25 * timer is only for the purposes of the sample module to demonstrate access of 26 * Ftrace instances from within kernel. 27 */ 28static DEFINE_TIMER(mytimer, mytimer_handler); 29 30static void mytimer_handler(struct timer_list *unused) 31{ 32 /* 33 * Disable tracing for event "sample_event". 34 */ 35 trace_array_set_clr_event(tr, "sample-subsystem", "sample_event", 36 false); 37} 38 39static void simple_thread_func(int count) 40{ 41 set_current_state(TASK_INTERRUPTIBLE); 42 schedule_timeout(HZ); 43 44 /* 45 * Printing count value using trace_array_printk() - trace_printk() 46 * equivalent for the instance buffers. 47 */ 48 trace_array_printk(tr, _THIS_IP_, "trace_array_printk: count=%d\n", 49 count); 50 /* 51 * Tracepoint for event "sample_event". This will print the 52 * current value of count and current jiffies. 53 */ 54 trace_sample_event(count, jiffies); 55} 56 57static int simple_thread(void *arg) 58{ 59 int count = 0; 60 unsigned long delay = msecs_to_jiffies(5000); 61 62 /* 63 * Enable tracing for "sample_event". 64 */ 65 trace_array_set_clr_event(tr, "sample-subsystem", "sample_event", true); 66 67 /* 68 * Adding timer - mytimer. This timer will disable tracing after 69 * delay seconds. 70 * 71 */ 72 add_timer(&mytimer); 73 mod_timer(&mytimer, jiffies+delay); 74 75 while (!kthread_should_stop()) 76 simple_thread_func(count++); 77 78 del_timer(&mytimer); 79 80 /* 81 * trace_array_put() decrements the reference counter associated with 82 * the trace array - "tr". We are done using the trace array, hence 83 * decrement the reference counter so that it can be destroyed using 84 * trace_array_destroy(). 85 */ 86 trace_array_put(tr); 87 88 return 0; 89} 90 91static int __init sample_trace_array_init(void) 92{ 93 /* 94 * Return a pointer to the trace array with name "sample-instance" if it 95 * exists, else create a new trace array. 96 * 97 * NOTE: This function increments the reference counter 98 * associated with the trace array - "tr". 99 */ 100 tr = trace_array_get_by_name("sample-instance"); 101 102 if (!tr) 103 return -1; 104 /* 105 * If context specific per-cpu buffers havent already been allocated. 106 */ 107 trace_printk_init_buffers(); 108 109 simple_tsk = kthread_run(simple_thread, NULL, "sample-instance"); 110 if (IS_ERR(simple_tsk)) 111 return -1; 112 return 0; 113} 114 115static void __exit sample_trace_array_exit(void) 116{ 117 kthread_stop(simple_tsk); 118 119 /* 120 * We are unloading our module and no longer require the trace array. 121 * Remove/destroy "tr" using trace_array_destroy() 122 */ 123 trace_array_destroy(tr); 124} 125 126module_init(sample_trace_array_init); 127module_exit(sample_trace_array_exit); 128 129MODULE_AUTHOR("Divya Indi"); 130MODULE_DESCRIPTION("Sample module for kernel access to Ftrace instances"); 131MODULE_LICENSE("GPL");