Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 #include <linux/module.h>
0003 #include <linux/kthread.h>
0004 #include <linux/trace.h>
0005 #include <linux/trace_events.h>
0006 #include <linux/timer.h>
0007 #include <linux/err.h>
0008 #include <linux/jiffies.h>
0009 #include <linux/workqueue.h>
0010 
0011 /*
0012  * Any file that uses trace points, must include the header.
0013  * But only one file, must include the header by defining
0014  * CREATE_TRACE_POINTS first.  This will make the C code that
0015  * creates the handles for the trace points.
0016  */
0017 #define CREATE_TRACE_POINTS
0018 #include "sample-trace-array.h"
0019 
0020 struct trace_array *tr;
0021 static void mytimer_handler(struct timer_list *unused);
0022 static struct task_struct *simple_tsk;
0023 
0024 static void trace_work_fn(struct work_struct *work)
0025 {
0026     /*
0027      * Disable tracing for event "sample_event".
0028      */
0029     trace_array_set_clr_event(tr, "sample-subsystem", "sample_event",
0030             false);
0031 }
0032 static DECLARE_WORK(trace_work, trace_work_fn);
0033 
0034 /*
0035  * mytimer: Timer setup to disable tracing for event "sample_event". This
0036  * timer is only for the purposes of the sample module to demonstrate access of
0037  * Ftrace instances from within kernel.
0038  */
0039 static DEFINE_TIMER(mytimer, mytimer_handler);
0040 
0041 static void mytimer_handler(struct timer_list *unused)
0042 {
0043     schedule_work(&trace_work);
0044 }
0045 
0046 static void simple_thread_func(int count)
0047 {
0048     set_current_state(TASK_INTERRUPTIBLE);
0049     schedule_timeout(HZ);
0050 
0051     /*
0052      * Printing count value using trace_array_printk() - trace_printk()
0053      * equivalent for the instance buffers.
0054      */
0055     trace_array_printk(tr, _THIS_IP_, "trace_array_printk: count=%d\n",
0056             count);
0057     /*
0058      * Tracepoint for event "sample_event". This will print the
0059      * current value of count and current jiffies.
0060      */
0061     trace_sample_event(count, jiffies);
0062 }
0063 
0064 static int simple_thread(void *arg)
0065 {
0066     int count = 0;
0067     unsigned long delay = msecs_to_jiffies(5000);
0068 
0069     /*
0070      * Enable tracing for "sample_event".
0071      */
0072     trace_array_set_clr_event(tr, "sample-subsystem", "sample_event", true);
0073 
0074     /*
0075      * Adding timer - mytimer. This timer will disable tracing after
0076      * delay seconds.
0077      *
0078      */
0079     add_timer(&mytimer);
0080     mod_timer(&mytimer, jiffies+delay);
0081 
0082     while (!kthread_should_stop())
0083         simple_thread_func(count++);
0084 
0085     del_timer(&mytimer);
0086     cancel_work_sync(&trace_work);
0087 
0088     /*
0089      * trace_array_put() decrements the reference counter associated with
0090      * the trace array - "tr". We are done using the trace array, hence
0091      * decrement the reference counter so that it can be destroyed using
0092      * trace_array_destroy().
0093      */
0094     trace_array_put(tr);
0095 
0096     return 0;
0097 }
0098 
0099 static int __init sample_trace_array_init(void)
0100 {
0101     /*
0102      * Return a pointer to the trace array with name "sample-instance" if it
0103      * exists, else create a new trace array.
0104      *
0105      * NOTE: This function increments the reference counter
0106      * associated with the trace array - "tr".
0107      */
0108     tr = trace_array_get_by_name("sample-instance");
0109 
0110     if (!tr)
0111         return -1;
0112     /*
0113      * If context specific per-cpu buffers havent already been allocated.
0114      */
0115     trace_printk_init_buffers();
0116 
0117     simple_tsk = kthread_run(simple_thread, NULL, "sample-instance");
0118     if (IS_ERR(simple_tsk)) {
0119         trace_array_put(tr);
0120         trace_array_destroy(tr);
0121         return -1;
0122     }
0123 
0124     return 0;
0125 }
0126 
0127 static void __exit sample_trace_array_exit(void)
0128 {
0129     kthread_stop(simple_tsk);
0130 
0131     /*
0132      * We are unloading our module and no longer require the trace array.
0133      * Remove/destroy "tr" using trace_array_destroy()
0134      */
0135     trace_array_destroy(tr);
0136 }
0137 
0138 module_init(sample_trace_array_init);
0139 module_exit(sample_trace_array_exit);
0140 
0141 MODULE_AUTHOR("Divya Indi");
0142 MODULE_DESCRIPTION("Sample module for kernel access to Ftrace instances");
0143 MODULE_LICENSE("GPL");