xref: /aosp_15_r20/external/bcc/tools/mdflush.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/env python
2*387f9dfdSAndroid Build Coastguard Worker# @lint-avoid-python-3-compatibility-imports
3*387f9dfdSAndroid Build Coastguard Worker#
4*387f9dfdSAndroid Build Coastguard Worker# mdflush  Trace md flush events.
5*387f9dfdSAndroid Build Coastguard Worker#          For Linux, uses BCC, eBPF.
6*387f9dfdSAndroid Build Coastguard Worker#
7*387f9dfdSAndroid Build Coastguard Worker# Todo: add more details of the flush (latency, I/O count).
8*387f9dfdSAndroid Build Coastguard Worker#
9*387f9dfdSAndroid Build Coastguard Worker# Copyright 2016 Netflix, Inc.
10*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License")
11*387f9dfdSAndroid Build Coastguard Worker#
12*387f9dfdSAndroid Build Coastguard Worker# 13-Feb-2015   Brendan Gregg   Created this.
13*387f9dfdSAndroid Build Coastguard Worker
14*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function
15*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF
16*387f9dfdSAndroid Build Coastguard Workerfrom time import strftime
17*387f9dfdSAndroid Build Coastguard Worker
18*387f9dfdSAndroid Build Coastguard Worker# define BPF program
19*387f9dfdSAndroid Build Coastguard Workerbpf_text="""
20*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
21*387f9dfdSAndroid Build Coastguard Worker#include <linux/sched.h>
22*387f9dfdSAndroid Build Coastguard Worker#include <linux/blkdev.h>
23*387f9dfdSAndroid Build Coastguard Worker#include <linux/bio.h>
24*387f9dfdSAndroid Build Coastguard Worker
25*387f9dfdSAndroid Build Coastguard Workerstruct data_t {
26*387f9dfdSAndroid Build Coastguard Worker    u32 pid;
27*387f9dfdSAndroid Build Coastguard Worker    char comm[TASK_COMM_LEN];
28*387f9dfdSAndroid Build Coastguard Worker    char disk[DISK_NAME_LEN];
29*387f9dfdSAndroid Build Coastguard Worker};
30*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(events);
31*387f9dfdSAndroid Build Coastguard Worker
32*387f9dfdSAndroid Build Coastguard Workerint kprobe__md_flush_request(struct pt_regs *ctx, void *mddev, struct bio *bio)
33*387f9dfdSAndroid Build Coastguard Worker{
34*387f9dfdSAndroid Build Coastguard Worker    struct data_t data = {};
35*387f9dfdSAndroid Build Coastguard Worker    data.pid = bpf_get_current_pid_tgid() >> 32;
36*387f9dfdSAndroid Build Coastguard Worker    bpf_get_current_comm(&data.comm, sizeof(data.comm));
37*387f9dfdSAndroid Build Coastguard Worker/*
38*387f9dfdSAndroid Build Coastguard Worker * The following deals with kernel version changes (in mainline 4.14 and 5.12, although
39*387f9dfdSAndroid Build Coastguard Worker * it may be backported to earlier kernels) with how the disk name is accessed.
40*387f9dfdSAndroid Build Coastguard Worker * We handle both pre- and post-change versions here. Please avoid kernel
41*387f9dfdSAndroid Build Coastguard Worker * version tests like this as much as possible: they inflate the code, test,
42*387f9dfdSAndroid Build Coastguard Worker * and maintenance burden.
43*387f9dfdSAndroid Build Coastguard Worker */
44*387f9dfdSAndroid Build Coastguard Worker#ifdef bio_dev
45*387f9dfdSAndroid Build Coastguard Worker    struct gendisk *bi_disk = bio->__BI_DISK__;
46*387f9dfdSAndroid Build Coastguard Worker#else
47*387f9dfdSAndroid Build Coastguard Worker    struct gendisk *bi_disk = bio->bi_bdev->bd_disk;
48*387f9dfdSAndroid Build Coastguard Worker#endif
49*387f9dfdSAndroid Build Coastguard Worker    bpf_probe_read_kernel(&data.disk, sizeof(data.disk), bi_disk->disk_name);
50*387f9dfdSAndroid Build Coastguard Worker    events.perf_submit(ctx, &data, sizeof(data));
51*387f9dfdSAndroid Build Coastguard Worker    return 0;
52*387f9dfdSAndroid Build Coastguard Worker}
53*387f9dfdSAndroid Build Coastguard Worker"""
54*387f9dfdSAndroid Build Coastguard Worker
55*387f9dfdSAndroid Build Coastguard Workerif BPF.kernel_struct_has_field('bio', 'bi_bdev') == 1:
56*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace('__BI_DISK__', 'bi_bdev->bd_disk')
57*387f9dfdSAndroid Build Coastguard Workerelse:
58*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace('__BI_DISK__', 'bi_disk')
59*387f9dfdSAndroid Build Coastguard Worker
60*387f9dfdSAndroid Build Coastguard Worker# initialize BPF
61*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text)
62*387f9dfdSAndroid Build Coastguard Worker
63*387f9dfdSAndroid Build Coastguard Worker# header
64*387f9dfdSAndroid Build Coastguard Workerprint("Tracing md flush requests... Hit Ctrl-C to end.")
65*387f9dfdSAndroid Build Coastguard Workerprint("%-8s %-7s %-16s %s" % ("TIME", "PID", "COMM", "DEVICE"))
66*387f9dfdSAndroid Build Coastguard Worker
67*387f9dfdSAndroid Build Coastguard Worker# process event
68*387f9dfdSAndroid Build Coastguard Workerdef print_event(cpu, data, size):
69*387f9dfdSAndroid Build Coastguard Worker    event = b["events"].event(data)
70*387f9dfdSAndroid Build Coastguard Worker    print("%-8s %-7d %-16s %s" % (strftime("%H:%M:%S"), event.pid,
71*387f9dfdSAndroid Build Coastguard Worker        event.comm.decode('utf-8', 'replace'),
72*387f9dfdSAndroid Build Coastguard Worker        event.disk.decode('utf-8', 'replace')))
73*387f9dfdSAndroid Build Coastguard Worker
74*387f9dfdSAndroid Build Coastguard Worker# read events
75*387f9dfdSAndroid Build Coastguard Workerb["events"].open_perf_buffer(print_event)
76*387f9dfdSAndroid Build Coastguard Workerwhile 1:
77*387f9dfdSAndroid Build Coastguard Worker    try:
78*387f9dfdSAndroid Build Coastguard Worker        b.perf_buffer_poll()
79*387f9dfdSAndroid Build Coastguard Worker    except KeyboardInterrupt:
80*387f9dfdSAndroid Build Coastguard Worker        exit()
81