forked from iovisor/bcc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request iovisor#3691 from chenhengqi/add-mdflush
libbpf-tools: Add mdflush
- Loading branch information
Showing
6 changed files
with
223 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,7 @@ | |
/llcstat | ||
/nfsdist | ||
/nfsslower | ||
/mdflush | ||
/mountsnoop | ||
/numamove | ||
/offcputime | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,6 +42,7 @@ APPS = \ | |
klockstat \ | ||
ksnoop \ | ||
llcstat \ | ||
mdflush \ | ||
mountsnoop \ | ||
numamove \ | ||
offcputime \ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ | ||
/* Copyright (c) 2021~2022 Hengqi Chen */ | ||
#include <vmlinux.h> | ||
#include <bpf/bpf_tracing.h> | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_core_read.h> | ||
#include "core_fixes.bpf.h" | ||
#include "mdflush.h" | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); | ||
__type(key, __u32); | ||
__type(value, __u32); | ||
} events SEC(".maps"); | ||
|
||
SEC("fentry/md_flush_request") | ||
int BPF_PROG(md_flush_request, void *mddev, void *bio) | ||
{ | ||
__u64 pid = bpf_get_current_pid_tgid() >> 32; | ||
struct event event = {}; | ||
struct gendisk *gendisk; | ||
|
||
event.pid = pid; | ||
gendisk = get_gendisk(bio); | ||
BPF_CORE_READ_STR_INTO(event.disk, gendisk, disk_name); | ||
bpf_get_current_comm(event.comm, sizeof(event.comm)); | ||
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event)); | ||
return 0; | ||
} | ||
|
||
char LICENSE[] SEC("license") = "Dual BSD/GPL"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ | ||
|
||
/* | ||
* mdflush Trace md flush events. | ||
* | ||
* Copyright (c) 2021~2022 Hengqi Chen | ||
* | ||
* Based on mdflush(8) from BCC by Brendan Gregg. | ||
* 08-Nov-2021 Hengqi Chen Created this. | ||
*/ | ||
#include <argp.h> | ||
#include <errno.h> | ||
#include <signal.h> | ||
#include <string.h> | ||
#include <time.h> | ||
|
||
#include <bpf/libbpf.h> | ||
#include <bpf/bpf.h> | ||
#include "mdflush.h" | ||
#include "mdflush.skel.h" | ||
#include "trace_helpers.h" | ||
|
||
#define PERF_BUFFER_PAGES 16 | ||
#define PERF_POLL_TIMEOUT_MS 100 | ||
#define warn(...) fprintf(stderr, __VA_ARGS__) | ||
|
||
static volatile sig_atomic_t exiting = 0; | ||
static bool verbose = false; | ||
|
||
const char *argp_program_version = "mdflush 0.1"; | ||
const char *argp_program_bug_address = | ||
"https://github.com/iovisor/bcc/tree/master/libbpf-tools"; | ||
const char argp_program_doc[] = | ||
"Trace md flush events.\n" | ||
"\n" | ||
"USAGE: mdflush\n"; | ||
|
||
static const struct argp_option opts[] = { | ||
{ "verbose", 'v', NULL, 0, "Verbose debug output" }, | ||
{ NULL, 'h', NULL, OPTION_HIDDEN, "Show the full help" }, | ||
{}, | ||
}; | ||
|
||
static error_t parse_arg(int key, char *arg, struct argp_state *state) | ||
{ | ||
switch (key) { | ||
case 'h': | ||
argp_state_help(state, stderr, ARGP_HELP_STD_HELP); | ||
break; | ||
case 'v': | ||
verbose = true; | ||
break; | ||
default: | ||
return ARGP_ERR_UNKNOWN; | ||
} | ||
return 0; | ||
} | ||
|
||
static void sig_int(int signo) | ||
{ | ||
exiting = 1; | ||
} | ||
|
||
static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) | ||
{ | ||
if (level == LIBBPF_DEBUG && !verbose) | ||
return 0; | ||
return vfprintf(stderr, format, args); | ||
} | ||
|
||
static void handle_event(void *ctx, int cpu, void *data, __u32 data_sz) | ||
{ | ||
struct event *e = data; | ||
time_t t; | ||
struct tm *tm; | ||
char ts[32]; | ||
|
||
time(&t); | ||
tm = localtime(&t); | ||
strftime(ts, sizeof(ts), "%H:%M:%S", tm); | ||
printf("%-8s %-7d %-16s %-s\n", | ||
ts, e->pid, e->comm, e->disk); | ||
} | ||
|
||
static void handle_lost_events(void *ctx, int cpu, __u64 lost_cnt) | ||
{ | ||
warn("lost %llu events on CPU #%d\n", lost_cnt, cpu); | ||
} | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
static const struct argp argp = { | ||
.options = opts, | ||
.parser = parse_arg, | ||
.doc = argp_program_doc, | ||
}; | ||
struct perf_buffer *pb = NULL; | ||
struct mdflush_bpf *obj; | ||
int err; | ||
|
||
err = argp_parse(&argp, argc, argv, 0, NULL, NULL); | ||
if (err) | ||
return err; | ||
|
||
libbpf_set_strict_mode(LIBBPF_STRICT_ALL); | ||
libbpf_set_print(libbpf_print_fn); | ||
|
||
obj = mdflush_bpf__open_and_load(); | ||
if (!obj) { | ||
warn("failed to open/load BPF object\n"); | ||
return 1; | ||
} | ||
|
||
err = mdflush_bpf__attach(obj); | ||
if (err) { | ||
warn("failed to attach BPF programs: %d\n", err); | ||
goto cleanup; | ||
} | ||
|
||
pb = perf_buffer__new(bpf_map__fd(obj->maps.events), PERF_BUFFER_PAGES, | ||
handle_event, handle_lost_events, NULL, NULL); | ||
if (!pb) { | ||
warn("failed to open perf buffer: %d\n", err); | ||
goto cleanup; | ||
} | ||
|
||
if (signal(SIGINT, sig_int) == SIG_ERR) { | ||
warn("can't set signal handler: %s\n", strerror(errno)); | ||
err = 1; | ||
goto cleanup; | ||
} | ||
|
||
printf("Tracing md flush requests... Hit Ctrl-C to end.\n"); | ||
printf("%-8s %-7s %-16s %-s\n", | ||
"TIME", "PID", "COMM", "DEVICE"); | ||
|
||
while (!exiting) { | ||
err = perf_buffer__poll(pb, PERF_POLL_TIMEOUT_MS); | ||
if (err < 0 && err != -EINTR) { | ||
warn("error polling perf buffer: %s\n", strerror(-err)); | ||
goto cleanup; | ||
} | ||
/* reset err to return 0 if exiting */ | ||
err = 0; | ||
} | ||
|
||
cleanup: | ||
perf_buffer__free(pb); | ||
mdflush_bpf__destroy(obj); | ||
|
||
return err != 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ | ||
/* Copyright (c) 2021~2022 Hengqi Chen */ | ||
#ifndef __MDFLUSH_H | ||
#define __MDFLUSH_H | ||
|
||
#define TASK_COMM_LEN 16 | ||
#define DISK_NAME_LEN 32 | ||
|
||
struct event { | ||
__u32 pid; | ||
char comm[TASK_COMM_LEN]; | ||
char disk[DISK_NAME_LEN]; | ||
}; | ||
|
||
#endif /* __MDFLUSH_H */ |