All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 1/1] sample: bpf: introduce irqlat
@ 2022-04-14  9:07 Song Chen
  0 siblings, 0 replies; only message in thread
From: Song Chen @ 2022-04-14  9:07 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, netdev, bpf, linux-kernel
  Cc: Song Chen

irqlat presents max, min and avg value of time consumed in
irq handling for each cpu, from irq_handler_entry to
irq_handler_exit.

engineers can run it to evaluate the performance of irq handling,
especially for RT system.

Signed-off-by: Song Chen <chensong_2000@189.cn>
---
 samples/bpf/.gitignore    |   1 +
 samples/bpf/Makefile      |   5 ++
 samples/bpf/irqlat_kern.c |  81 ++++++++++++++++++++++++++++++
 samples/bpf/irqlat_user.c | 100 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 187 insertions(+)
 create mode 100644 samples/bpf/irqlat_kern.c
 create mode 100644 samples/bpf/irqlat_user.c

diff --git a/samples/bpf/.gitignore b/samples/bpf/.gitignore
index 0e7bfdbff80a..2d727f041f51 100644
--- a/samples/bpf/.gitignore
+++ b/samples/bpf/.gitignore
@@ -61,3 +61,4 @@ iperf.*
 /vmlinux.h
 /bpftool/
 /libbpf/
+irqlat
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 38638845db9d..df2daab128f0 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -60,6 +60,8 @@ tprogs-y += xdp_redirect_map
 tprogs-y += xdp_redirect
 tprogs-y += xdp_monitor
 
+tprogs-y += irqlat
+
 # Libbpf dependencies
 LIBBPF_SRC = $(TOOLS_PATH)/lib/bpf
 LIBBPF_OUTPUT = $(abspath $(BPF_SAMPLES_PATH))/libbpf
@@ -125,6 +127,8 @@ xdp_redirect_map-objs := xdp_redirect_map_user.o $(XDP_SAMPLE)
 xdp_redirect-objs := xdp_redirect_user.o $(XDP_SAMPLE)
 xdp_monitor-objs := xdp_monitor_user.o $(XDP_SAMPLE)
 
+irqlat-objs := irqlat_user.o
+
 # Tell kbuild to always build the programs
 always-y := $(tprogs-y)
 always-y += sockex1_kern.o
@@ -181,6 +185,7 @@ always-y += ibumad_kern.o
 always-y += hbm_out_kern.o
 always-y += hbm_edt_kern.o
 always-y += xdpsock_kern.o
+always-y += irqlat_kern.o
 
 ifeq ($(ARCH), arm)
 # Strip all except -D__LINUX_ARM_ARCH__ option needed to handle linux
diff --git a/samples/bpf/irqlat_kern.c b/samples/bpf/irqlat_kern.c
new file mode 100644
index 000000000000..0037dcda67cf
--- /dev/null
+++ b/samples/bpf/irqlat_kern.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Kylin
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+#include <linux/version.h>
+#include <linux/ptrace.h>
+#include <uapi/linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+
+#define MAX_CPUS		128
+
+struct {
+	__uint(type, BPF_MAP_TYPE_ARRAY);
+	__type(key, int);
+	__type(value, u64);
+	__uint(max_entries, MAX_CPUS);
+} irq_ts SEC(".maps");
+
+SEC("tracepoint/irq/irq_handler_entry")
+int on_irq_entry(struct pt_regs *ctx)
+{
+	int cpu = bpf_get_smp_processor_id();
+	u64 *ts = bpf_map_lookup_elem(&irq_ts, &cpu);
+
+	if (ts)
+		*ts = bpf_ktime_get_ns();
+
+	return 0;
+}
+
+struct datares {
+	u64 entries;
+	u64 total;
+	u64 max;
+	u64 min;
+};
+
+struct {
+	__uint(type, BPF_MAP_TYPE_ARRAY);
+	__type(key, int);
+	__type(value, struct datares);
+	__uint(max_entries, MAX_CPUS);
+} irq_lat SEC(".maps");
+
+SEC("tracepoint/irq/irq_handler_exit")
+int on_irq_exit(struct pt_regs *ctx)
+{
+	u64 *ts, cur_ts, delta, *val;
+	int cpu;
+	struct datares *res;
+
+	cpu = bpf_get_smp_processor_id();
+	ts = bpf_map_lookup_elem(&irq_ts, &cpu);
+	if (!ts)
+		return 0;
+
+	cur_ts = bpf_ktime_get_ns();
+	delta = cur_ts - *ts;
+
+	res = bpf_map_lookup_elem(&irq_lat, &cpu);
+	if (!res)
+		return 0;
+
+	res->entries++;
+	res->total += delta;
+	if (res->max < delta)
+		res->max = delta;
+	if (res->min == 0 || res->min > delta)
+		res->min = delta;
+
+	if (res->total >= U64_MAX)
+		__builtin_memset(res, 0, sizeof(struct datares));
+
+	return 0;
+}
+
+char _license[] SEC("license") = "GPL";
diff --git a/samples/bpf/irqlat_user.c b/samples/bpf/irqlat_user.c
new file mode 100644
index 000000000000..3a5a43b9fce9
--- /dev/null
+++ b/samples/bpf/irqlat_user.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Kylin
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <linux/perf_event.h>
+#include <linux/bpf.h>
+#include <bpf/libbpf.h>
+#include <bpf/bpf.h>
+#include "trace_helpers.h"
+
+#define MAX_CPUS 128
+static int map_fd[2];
+
+struct datares {
+	__u64 entries;
+	__u64 total;
+	__u64 max;
+	__u64 min;
+};
+
+static void get_data(int fd)
+{
+	int i;
+	struct datares res;
+	__u64 avg;
+
+	/* Clear screen */
+	printf("\033[2J");
+
+	/* Header */
+	printf("\nirq Latency statistics: (ns)\n");
+	for (i = 0; i < MAX_CPUS; i++) {
+		bpf_map_lookup_elem(fd, &i, &res);
+
+		if (res.entries == 0)
+			continue;
+
+		avg = res.total / res.entries;
+		printf("cpu:%d, max:%llu, min:%llu, avg:%llu\n",
+					i, res.max, res.min, avg);
+	}
+}
+
+int main(int argc, char **argv)
+{
+	char filename[256];
+	struct bpf_object *obj = NULL;
+	struct bpf_link *links[2];
+	struct bpf_program *prog;
+	int delay = 1, i = 0;
+
+	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+
+	obj = bpf_object__open_file(filename, NULL);
+	if (libbpf_get_error(obj)) {
+		fprintf(stderr, "ERROR: opening BPF object file failed\n");
+		obj = NULL;
+		goto cleanup;
+	}
+
+	/* load BPF program */
+	if (bpf_object__load(obj)) {
+		fprintf(stderr, "ERROR: loading BPF object file failed\n");
+		goto cleanup;
+	}
+
+	map_fd[0] = bpf_object__find_map_fd_by_name(obj, "irq_ts");
+	map_fd[1] = bpf_object__find_map_fd_by_name(obj, "irq_lat");
+	if (map_fd[0] < 0 || map_fd[1] < 0) {
+		fprintf(stderr, "ERROR: finding a map in obj file failed\n");
+		goto cleanup;
+	}
+
+	bpf_object__for_each_program(prog, obj) {
+		links[i] = bpf_program__attach(prog);
+		if (libbpf_get_error(links[i])) {
+			fprintf(stderr, "ERROR: bpf_program__attach failed\n");
+			links[i] = NULL;
+			goto cleanup;
+		}
+		i++;
+	}
+
+	while (1) {
+		sleep(delay);
+		get_data(map_fd[1]);
+	}
+
+cleanup:
+	for (i--; i >= 0; i--)
+		bpf_link__destroy(links[i]);
+
+	bpf_object__close(obj);
+	return 0;
+}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2022-04-14  9:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-14  9:07 [RFC PATCH 1/1] sample: bpf: introduce irqlat Song Chen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.