Path: blob/master/samples/trace_events/trace-events-sample.c
26278 views
// SPDX-License-Identifier: GPL-2.0-only1#include <linux/module.h>2#include <linux/kthread.h>34/*5* Any file that uses trace points, must include the header.6* But only one file, must include the header by defining7* CREATE_TRACE_POINTS first. This will make the C code that8* creates the handles for the trace points.9*/10#define CREATE_TRACE_POINTS11#include "trace-events-sample.h"1213static const char *random_strings[] = {14"Mother Goose",15"Snoopy",16"Gandalf",17"Frodo",18"One ring to rule them all"19};2021static void do_simple_thread_func(int cnt, const char *fmt, ...)22{23unsigned long bitmask[1] = {0xdeadbeefUL};24va_list va;25int array[6];26int len = cnt % 5;27int i;2829set_current_state(TASK_INTERRUPTIBLE);30schedule_timeout(HZ);3132for (i = 0; i < len; i++)33array[i] = i + 1;34array[i] = 0;3536va_start(va, fmt);3738/* Silly tracepoints */39trace_foo_bar("hello", cnt, array, random_strings[len],40current->cpus_ptr, fmt, &va);4142va_end(va);4344trace_foo_with_template_simple("HELLO", cnt);4546trace_foo_bar_with_cond("Some times print", cnt);4748trace_foo_with_template_cond("prints other times", cnt);4950trace_foo_with_template_print("I have to be different", cnt);5152trace_foo_rel_loc("Hello __rel_loc", cnt, bitmask, current->cpus_ptr);53}5455static void simple_thread_func(int cnt)56{57do_simple_thread_func(cnt, "iter=%d", cnt);58}5960static int simple_thread(void *arg)61{62int cnt = 0;6364while (!kthread_should_stop())65simple_thread_func(cnt++);6667return 0;68}6970static struct task_struct *simple_tsk;71static struct task_struct *simple_tsk_fn;7273static void simple_thread_func_fn(int cnt)74{75set_current_state(TASK_INTERRUPTIBLE);76schedule_timeout(HZ);7778/* More silly tracepoints */79trace_foo_bar_with_fn("Look at me", cnt);80trace_foo_with_template_fn("Look at me too", cnt);81}8283static int simple_thread_fn(void *arg)84{85int cnt = 0;8687while (!kthread_should_stop())88simple_thread_func_fn(cnt++);8990return 0;91}9293static DEFINE_MUTEX(thread_mutex);94static int simple_thread_cnt;9596int foo_bar_reg(void)97{98mutex_lock(&thread_mutex);99if (simple_thread_cnt++)100goto out;101102pr_info("Starting thread for foo_bar_fn\n");103/*104* We shouldn't be able to start a trace when the module is105* unloading (there's other locks to prevent that). But106* for consistency sake, we still take the thread_mutex.107*/108simple_tsk_fn = kthread_run(simple_thread_fn, NULL, "event-sample-fn");109out:110mutex_unlock(&thread_mutex);111return 0;112}113114void foo_bar_unreg(void)115{116mutex_lock(&thread_mutex);117if (--simple_thread_cnt)118goto out;119120pr_info("Killing thread for foo_bar_fn\n");121if (simple_tsk_fn)122kthread_stop(simple_tsk_fn);123simple_tsk_fn = NULL;124out:125mutex_unlock(&thread_mutex);126}127128static int __init trace_event_init(void)129{130simple_tsk = kthread_run(simple_thread, NULL, "event-sample");131if (IS_ERR(simple_tsk))132return -1;133134return 0;135}136137static void __exit trace_event_exit(void)138{139kthread_stop(simple_tsk);140mutex_lock(&thread_mutex);141if (simple_tsk_fn)142kthread_stop(simple_tsk_fn);143simple_tsk_fn = NULL;144mutex_unlock(&thread_mutex);145}146147module_init(trace_event_init);148module_exit(trace_event_exit);149150MODULE_AUTHOR("Steven Rostedt");151MODULE_DESCRIPTION("trace-events-sample");152MODULE_LICENSE("GPL");153154155