Lines Matching +full:entry +full:- +full:latency +full:- +full:us

1 // SPDX-License-Identifier: GPL-2.0
3 * trace_hwlat.c - A simple Hardware Latency detector.
20 * Although certain hardware-inducing latencies are necessary (for example,
22 * and remote management) they can wreak havoc upon any OS-level performance
23 * guarantees toward low-latency, especially when the OS is not even made
27 * sampling the built-in CPU timer, looking for discontiguous readings.
31 * environment requiring any kind of low-latency performance
34 * Copyright (C) 2008-2009 Jon Masters, Red Hat, Inc. <jcm@redhat.com>
35 * Copyright (C) 2013-2016 Steven Rostedt, Red Hat, Inc. <srostedt@redhat.com>
55 #define DEFAULT_LAT_THRESHOLD 10 /* 10us */
57 static struct dentry *hwlat_sample_width; /* sample width us */
58 static struct dentry *hwlat_sample_window; /* sample window us */
67 static char *thread_mode_str[] = { "none", "round-robin", "per-cpu" };
91 /* Individual latency samples are stored here when detected. */
134 struct trace_buffer *buffer = tr->array_buffer.buffer;
136 struct hwlat_entry *entry;
138 event = trace_buffer_lock_reserve(buffer, TRACE_HWLAT, sizeof(*entry),
142 entry = ring_buffer_event_data(event);
143 entry->seqnum = sample->seqnum;
144 entry->duration = sample->duration;
145 entry->outer_duration = sample->outer_duration;
146 entry->timestamp = sample->timestamp;
147 entry->nmi_total_ts = sample->nmi_total_ts;
148 entry->nmi_count = sample->nmi_count;
149 entry->count = sample->count;
151 if (!call_filter_check_discard(call, entry, buffer, event))
159 #define time_sub(a, b) ((a) - (b))
167 if (!kdata->kthread)
176 kdata->nmi_ts_start = time_get();
178 kdata->nmi_total_ts += time_get() - kdata->nmi_ts_start;
182 kdata->nmi_count++;
186 * hwlat_err - report a hwlat error.
191 trace_array_printk_buf(tr->array_buffer.buffer, _THIS_IP_, msg); \
195 * get_sample - sample the CPU TSC and look for likely hardware latencies
198 * hardware-induced latency. Called with interrupts disabled and with
211 int ret = -1;
216 kdata->nmi_total_ts = 0;
217 kdata->nmi_count = 0;
280 /* If we exceed the threshold value, we have found a hardware latency */
282 u64 latency;
287 if (kdata->nmi_total_ts)
288 do_div(kdata->nmi_total_ts, NSEC_PER_USEC);
294 s.nmi_total_ts = kdata->nmi_total_ts;
295 s.nmi_count = kdata->nmi_count;
299 latency = max(sample, outer_sample);
301 /* Keep a running maximum ever recorded hardware latency */
302 if (latency > tr->max_latency) {
303 tr->max_latency = latency;
325 if (!cpumask_equal(current_mask, current->cpus_ptr))
329 cpumask_and(current_mask, cpu_online_mask, tr->tracing_cpumask);
347 pr_info(BANNER "cpumask changed while in round-robin mode, switching to mode none\n");
351 * kthread_fn - The CPU time sampling/hardware latency detection kernel thread
354 * disable interrupts, which does (intentionally) introduce latency since we
374 interval = hwlat_data.sample_window - hwlat_data.sample_width;
391 * stop_stop_kthread - Inform the hardware latency sampling/detector kthread to stop
393 * This kicks the running hardware latency sampling/detector kernel thread and
402 kthread = kdata->kthread;
408 kdata->kthread = NULL;
416 * start_single_kthread - Kick off the hardware latency sampling/detector kthread
429 if (kdata->kthread)
436 return -ENOMEM;
440 cpumask_and(current_mask, cpu_online_mask, tr->tracing_cpumask);
451 kdata->kthread = kthread;
460 * stop_cpu_kthread - Stop a hwlat cpu kthread
473 * stop_per_cpu_kthreads - Inform the hardware latency sampling/detector kthread to stop
475 * This kicks the running hardware latency sampling/detector kernel threads and
489 * start_cpu_kthread - Start a hwlat cpu kthread
502 return -ENOMEM;
525 if (!cpumask_test_cpu(cpu, tr->tracing_cpumask))
539 * hwlat_cpu_init - CPU hotplug online callback function
548 * hwlat_cpu_die - CPU hotplug offline callback function
575 * start_per_cpu_kthreads - Kick off the hardware latency sampling/detector kthreads
591 cpumask_and(current_mask, cpu_online_mask, tr->tracing_cpumask);
640 if (mode < MODE_MAX - 1) /* if mode is any but last */
668 * hwlat_mode_write - Write function for "mode" entry
675 * to the hardware latency detector. hwlatd has different operation modes.
678 * the "round-robin" one, in which a single hwlatd thread runs, migrating
679 * among the allowed CPUs in a round-robin fashion. The "per-cpu" mode
691 return -EINVAL;
694 return -EFAULT;
700 ret = -EINVAL;
764 * init_tracefs - A function to initialize the tracefs interface files
778 return -ENOMEM;
782 return -ENOMEM;
809 return -ENOMEM;
836 return -EBUSY;
841 tr->max_latency = 0;