trace_osnoise.c (b96285e10aad234acfa0628f7e8336990f778c03) trace_osnoise.c (f7d9f6370e006400655ff96cb148f56598492d91)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * OS Noise Tracer: computes the OS Noise suffered by a running thread.
4 * Timerlat Tracer: measures the wakeup latency of a timer triggered IRQ and thread.
5 *
6 * Based on "hwlat_detector" tracer by:
7 * Copyright (C) 2008-2009 Jon Masters, Red Hat, Inc. <jcm@redhat.com>
8 * Copyright (C) 2013-2016 Steven Rostedt, Red Hat, Inc. <srostedt@redhat.com>

--- 722 unchanged lines hidden (view full) ---

731}
732
733/*
734 * hook_irq_events - Hook IRQ handling events
735 *
736 * This function hooks the IRQ related callbacks to the respective trace
737 * events.
738 */
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * OS Noise Tracer: computes the OS Noise suffered by a running thread.
4 * Timerlat Tracer: measures the wakeup latency of a timer triggered IRQ and thread.
5 *
6 * Based on "hwlat_detector" tracer by:
7 * Copyright (C) 2008-2009 Jon Masters, Red Hat, Inc. <jcm@redhat.com>
8 * Copyright (C) 2013-2016 Steven Rostedt, Red Hat, Inc. <srostedt@redhat.com>

--- 722 unchanged lines hidden (view full) ---

731}
732
733/*
734 * hook_irq_events - Hook IRQ handling events
735 *
736 * This function hooks the IRQ related callbacks to the respective trace
737 * events.
738 */
739int hook_irq_events(void)
739static int hook_irq_events(void)
740{
741 int ret;
742
743 ret = register_trace_irq_handler_entry(trace_irqentry_callback, NULL);
744 if (ret)
745 goto out_err;
746
747 ret = register_trace_irq_handler_exit(trace_irqexit_callback, NULL);

--- 15 unchanged lines hidden (view full) ---

763}
764
765/*
766 * unhook_irq_events - Unhook IRQ handling events
767 *
768 * This function unhooks the IRQ related callbacks to the respective trace
769 * events.
770 */
740{
741 int ret;
742
743 ret = register_trace_irq_handler_entry(trace_irqentry_callback, NULL);
744 if (ret)
745 goto out_err;
746
747 ret = register_trace_irq_handler_exit(trace_irqexit_callback, NULL);

--- 15 unchanged lines hidden (view full) ---

763}
764
765/*
766 * unhook_irq_events - Unhook IRQ handling events
767 *
768 * This function unhooks the IRQ related callbacks to the respective trace
769 * events.
770 */
771void unhook_irq_events(void)
771static void unhook_irq_events(void)
772{
773 osnoise_arch_unregister();
774 unregister_trace_irq_handler_exit(trace_irqexit_callback, NULL);
775 unregister_trace_irq_handler_entry(trace_irqentry_callback, NULL);
776}
777
778#ifndef CONFIG_PREEMPT_RT
779/*
780 * trace_softirq_entry_callback - Note the starting of a softirq
781 *
782 * Save the starting time of a softirq. As softirqs are non-preemptive to
783 * other softirqs, it is safe to use a single variable (ons_var->softirq)
784 * to save the statistics. The arrival_time is used to report... the
785 * arrival time. The delta_start is used to compute the duration at the
786 * softirq exit handler. See cond_move_softirq_delta_start().
787 */
772{
773 osnoise_arch_unregister();
774 unregister_trace_irq_handler_exit(trace_irqexit_callback, NULL);
775 unregister_trace_irq_handler_entry(trace_irqentry_callback, NULL);
776}
777
778#ifndef CONFIG_PREEMPT_RT
779/*
780 * trace_softirq_entry_callback - Note the starting of a softirq
781 *
782 * Save the starting time of a softirq. As softirqs are non-preemptive to
783 * other softirqs, it is safe to use a single variable (ons_var->softirq)
784 * to save the statistics. The arrival_time is used to report... the
785 * arrival time. The delta_start is used to compute the duration at the
786 * softirq exit handler. See cond_move_softirq_delta_start().
787 */
788void trace_softirq_entry_callback(void *data, unsigned int vec_nr)
788static void trace_softirq_entry_callback(void *data, unsigned int vec_nr)
789{
790 struct osnoise_variables *osn_var = this_cpu_osn_var();
791
792 if (!osn_var->sampling)
793 return;
794 /*
795 * This value will be used in the report, but not to compute
796 * the execution time, so it is safe to get it unsafe.

--- 6 unchanged lines hidden (view full) ---

803}
804
805/*
806 * trace_softirq_exit_callback - Note the end of an softirq
807 *
808 * Computes the duration of the softirq noise, and trace it. Also discounts the
809 * interference from other sources of noise could be currently being accounted.
810 */
789{
790 struct osnoise_variables *osn_var = this_cpu_osn_var();
791
792 if (!osn_var->sampling)
793 return;
794 /*
795 * This value will be used in the report, but not to compute
796 * the execution time, so it is safe to get it unsafe.

--- 6 unchanged lines hidden (view full) ---

803}
804
805/*
806 * trace_softirq_exit_callback - Note the end of an softirq
807 *
808 * Computes the duration of the softirq noise, and trace it. Also discounts the
809 * interference from other sources of noise could be currently being accounted.
810 */
811void trace_softirq_exit_callback(void *data, unsigned int vec_nr)
811static void trace_softirq_exit_callback(void *data, unsigned int vec_nr)
812{
813 struct osnoise_variables *osn_var = this_cpu_osn_var();
814 int duration;
815
816 if (!osn_var->sampling)
817 return;
818
819#ifdef CONFIG_TIMERLAT_TRACER

--- 124 unchanged lines hidden (view full) ---

944}
945
946/*
947 * trace_sched_switch - sched:sched_switch trace event handler
948 *
949 * This function is hooked to the sched:sched_switch trace event, and it is
950 * used to record the beginning and to report the end of a thread noise window.
951 */
812{
813 struct osnoise_variables *osn_var = this_cpu_osn_var();
814 int duration;
815
816 if (!osn_var->sampling)
817 return;
818
819#ifdef CONFIG_TIMERLAT_TRACER

--- 124 unchanged lines hidden (view full) ---

944}
945
946/*
947 * trace_sched_switch - sched:sched_switch trace event handler
948 *
949 * This function is hooked to the sched:sched_switch trace event, and it is
950 * used to record the beginning and to report the end of a thread noise window.
951 */
952void
952static void
953trace_sched_switch_callback(void *data, bool preempt, struct task_struct *p,
954 struct task_struct *n)
955{
956 struct osnoise_variables *osn_var = this_cpu_osn_var();
957
958 if (p->pid != osn_var->pid)
959 thread_exit(osn_var, p);
960
961 if (n->pid != osn_var->pid)
962 thread_entry(osn_var, n);
963}
964
965/*
966 * hook_thread_events - Hook the insturmentation for thread noise
967 *
968 * Hook the osnoise tracer callbacks to handle the noise from other
969 * threads on the necessary kernel events.
970 */
953trace_sched_switch_callback(void *data, bool preempt, struct task_struct *p,
954 struct task_struct *n)
955{
956 struct osnoise_variables *osn_var = this_cpu_osn_var();
957
958 if (p->pid != osn_var->pid)
959 thread_exit(osn_var, p);
960
961 if (n->pid != osn_var->pid)
962 thread_entry(osn_var, n);
963}
964
965/*
966 * hook_thread_events - Hook the insturmentation for thread noise
967 *
968 * Hook the osnoise tracer callbacks to handle the noise from other
969 * threads on the necessary kernel events.
970 */
971int hook_thread_events(void)
971static int hook_thread_events(void)
972{
973 int ret;
974
975 ret = register_trace_sched_switch(trace_sched_switch_callback, NULL);
976 if (ret)
977 return -EINVAL;
978
979 return 0;
980}
981
982/*
983 * unhook_thread_events - *nhook the insturmentation for thread noise
984 *
985 * Unook the osnoise tracer callbacks to handle the noise from other
986 * threads on the necessary kernel events.
987 */
972{
973 int ret;
974
975 ret = register_trace_sched_switch(trace_sched_switch_callback, NULL);
976 if (ret)
977 return -EINVAL;
978
979 return 0;
980}
981
982/*
983 * unhook_thread_events - *nhook the insturmentation for thread noise
984 *
985 * Unook the osnoise tracer callbacks to handle the noise from other
986 * threads on the necessary kernel events.
987 */
988void unhook_thread_events(void)
988static void unhook_thread_events(void)
989{
990 unregister_trace_sched_switch(trace_sched_switch_callback, NULL);
991}
992
993/*
994 * save_osn_sample_stats - Save the osnoise_sample statistics
995 *
996 * Save the osnoise_sample statistics before the sampling phase. These
997 * values will be used later to compute the diff betwneen the statistics
998 * before and after the osnoise sampling.
999 */
989{
990 unregister_trace_sched_switch(trace_sched_switch_callback, NULL);
991}
992
993/*
994 * save_osn_sample_stats - Save the osnoise_sample statistics
995 *
996 * Save the osnoise_sample statistics before the sampling phase. These
997 * values will be used later to compute the diff betwneen the statistics
998 * before and after the osnoise sampling.
999 */
1000void save_osn_sample_stats(struct osnoise_variables *osn_var, struct osnoise_sample *s)
1000static void
1001save_osn_sample_stats(struct osnoise_variables *osn_var, struct osnoise_sample *s)
1001{
1002 s->nmi_count = osn_var->nmi.count;
1003 s->irq_count = osn_var->irq.count;
1004 s->softirq_count = osn_var->softirq.count;
1005 s->thread_count = osn_var->thread.count;
1006}
1007
1008/*
1009 * diff_osn_sample_stats - Compute the osnoise_sample statistics
1010 *
1011 * After a sample period, compute the difference on the osnoise_sample
1012 * statistics. The struct osnoise_sample *s contains the statistics saved via
1013 * save_osn_sample_stats() before the osnoise sampling.
1014 */
1002{
1003 s->nmi_count = osn_var->nmi.count;
1004 s->irq_count = osn_var->irq.count;
1005 s->softirq_count = osn_var->softirq.count;
1006 s->thread_count = osn_var->thread.count;
1007}
1008
1009/*
1010 * diff_osn_sample_stats - Compute the osnoise_sample statistics
1011 *
1012 * After a sample period, compute the difference on the osnoise_sample
1013 * statistics. The struct osnoise_sample *s contains the statistics saved via
1014 * save_osn_sample_stats() before the osnoise sampling.
1015 */
1015void diff_osn_sample_stats(struct osnoise_variables *osn_var, struct osnoise_sample *s)
1016static void
1017diff_osn_sample_stats(struct osnoise_variables *osn_var, struct osnoise_sample *s)
1016{
1017 s->nmi_count = osn_var->nmi.count - s->nmi_count;
1018 s->irq_count = osn_var->irq.count - s->irq_count;
1019 s->softirq_count = osn_var->softirq.count - s->softirq_count;
1020 s->thread_count = osn_var->thread.count - s->thread_count;
1021}
1022
1023/*

--- 1033 unchanged lines hidden ---
1018{
1019 s->nmi_count = osn_var->nmi.count - s->nmi_count;
1020 s->irq_count = osn_var->irq.count - s->irq_count;
1021 s->softirq_count = osn_var->softirq.count - s->softirq_count;
1022 s->thread_count = osn_var->thread.count - s->thread_count;
1023}
1024
1025/*

--- 1033 unchanged lines hidden ---