197 lines
5.6 KiB
Diff
197 lines
5.6 KiB
Diff
From 83caf9baa742d811e59cdd6cf185986f6301cd90 Mon Sep 17 00:00:00 2001
|
|
From: zhangnan <zhangnan134@huawei.com>
|
|
Date: Wed, 16 Oct 2024 10:58:24 +0800
|
|
Subject: [PATCH] ebpf fix kyqin miss rq_driver data
|
|
|
|
---
|
|
src/c/ebpf_collector/ebpf_collector.bpf.c | 139 +++++++++++++++++++++-
|
|
1 file changed, 133 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/src/c/ebpf_collector/ebpf_collector.bpf.c b/src/c/ebpf_collector/ebpf_collector.bpf.c
|
|
index 870a677..9f03dbe 100644
|
|
--- a/src/c/ebpf_collector/ebpf_collector.bpf.c
|
|
+++ b/src/c/ebpf_collector/ebpf_collector.bpf.c
|
|
@@ -120,7 +120,6 @@ struct bpf_map_def SEC("maps") tag_res_2 = {
|
|
.max_entries = MAX_IO_TIME,
|
|
};
|
|
|
|
-
|
|
struct blk_mq_alloc_data {
|
|
/* input parameter */
|
|
struct request_queue *q;
|
|
@@ -132,6 +131,133 @@ struct blk_mq_alloc_data {
|
|
struct blk_mq_hw_ctx *hctx;
|
|
};
|
|
|
|
+struct request_kylin {
|
|
+ struct request_queue *q;
|
|
+ struct blk_mq_ctx *mq_ctx;
|
|
+
|
|
+ int cpu;
|
|
+ unsigned int cmd_flags; /* op and common flags */
|
|
+ req_flags_t rq_flags;
|
|
+
|
|
+ int internal_tag;
|
|
+
|
|
+ /* the following two fields are internal, NEVER access directly */
|
|
+ unsigned int __data_len; /* total data len */
|
|
+ int tag;
|
|
+ sector_t __sector; /* sector cursor */
|
|
+
|
|
+ struct bio *bio;
|
|
+ struct bio *biotail;
|
|
+
|
|
+ struct list_head queuelist;
|
|
+
|
|
+ /*
|
|
+ * The hash is used inside the scheduler, and killed once the
|
|
+ * request reaches the dispatch list. The ipi_list is only used
|
|
+ * to queue the request for softirq completion, which is long
|
|
+ * after the request has been unhashed (and even removed from
|
|
+ * the dispatch list).
|
|
+ */
|
|
+ union {
|
|
+ struct hlist_node hash; /* merge hash */
|
|
+ struct list_head ipi_list;
|
|
+ };
|
|
+
|
|
+ struct hlist_node front_hash; /* front merge hash */
|
|
+
|
|
+ /*
|
|
+ * The rb_node is only used inside the io scheduler, requests
|
|
+ * are pruned when moved to the dispatch queue. So let the
|
|
+ * completion_data share space with the rb_node.
|
|
+ */
|
|
+ union {
|
|
+ struct rb_node rb_node; /* sort/lookup */
|
|
+ struct bio_vec special_vec;
|
|
+ void *completion_data;
|
|
+ int error_count; /* for legacy drivers, don't use */
|
|
+ };
|
|
+
|
|
+ /*
|
|
+ * Three pointers are available for the IO schedulers, if they need
|
|
+ * more they have to dynamically allocate it. Flush requests are
|
|
+ * never put on the IO scheduler. So let the flush fields share
|
|
+ * space with the elevator data.
|
|
+ */
|
|
+ union {
|
|
+ struct {
|
|
+ struct io_cq *icq;
|
|
+ void *priv[2];
|
|
+ } elv;
|
|
+
|
|
+ struct {
|
|
+ unsigned int seq;
|
|
+ struct list_head list;
|
|
+ rq_end_io_fn *saved_end_io;
|
|
+ } flush;
|
|
+ };
|
|
+
|
|
+ struct gendisk *rq_disk;
|
|
+ struct hd_struct *part;
|
|
+ /* Time that I/O was submitted to the kernel. */
|
|
+ u64 start_time_ns;
|
|
+ /* Time that I/O was submitted to the device. */
|
|
+ u64 io_start_time_ns;
|
|
+
|
|
+#ifdef CONFIG_BLK_WBT
|
|
+ unsigned short wbt_flags;
|
|
+#endif
|
|
+#ifdef CONFIG_BLK_DEV_THROTTLING_LOW
|
|
+ unsigned short throtl_size;
|
|
+#endif
|
|
+
|
|
+ /*
|
|
+ * Number of scatter-gather DMA addr+len pairs after
|
|
+ * physical address coalescing is performed.
|
|
+ */
|
|
+ unsigned short nr_phys_segments;
|
|
+
|
|
+#if defined(CONFIG_BLK_DEV_INTEGRITY)
|
|
+ unsigned short nr_integrity_segments;
|
|
+#endif
|
|
+
|
|
+ unsigned short write_hint;
|
|
+ unsigned short ioprio;
|
|
+
|
|
+ void *special; /* opaque pointer available for LLD use */
|
|
+
|
|
+ unsigned int extra_len; /* length of alignment and padding */
|
|
+
|
|
+ enum mq_rq_state state;
|
|
+ refcount_t ref;
|
|
+
|
|
+ unsigned int timeout;
|
|
+
|
|
+ /* access through blk_rq_set_deadline, blk_rq_deadline */
|
|
+ unsigned long __deadline;
|
|
+
|
|
+ struct list_head timeout_list;
|
|
+
|
|
+ union {
|
|
+ struct __call_single_data csd;
|
|
+ u64 fifo_time;
|
|
+ };
|
|
+
|
|
+ /*
|
|
+ * completion callback.
|
|
+ */
|
|
+ rq_end_io_fn *end_io;
|
|
+ void *end_io_data;
|
|
+
|
|
+ /* for bidi */
|
|
+ struct request_kylin *next_rq;
|
|
+
|
|
+#ifdef CONFIG_BLK_CGROUP
|
|
+ struct request_list *rl; /* rl this rq is alloced from */
|
|
+#endif
|
|
+ KABI_RESERVE(1);
|
|
+ KABI_RESERVE(2);
|
|
+};
|
|
+
|
|
static __always_inline void blk_fill_rwbs(char *rwbs, unsigned int op)
|
|
{
|
|
switch (op & REQ_OP_MASK) {
|
|
@@ -710,7 +836,7 @@ u32 find_matching_wbt_5_keys(int major, int minor) {
|
|
SEC("kprobe/blk_mq_start_request")
|
|
int kprobe_blk_mq_start_request(struct pt_regs *regs)
|
|
{
|
|
- struct request *rq = (struct request *)PT_REGS_PARM1(regs);
|
|
+ struct request_kylin *rq = (struct request_kylin *)PT_REGS_PARM1(regs);
|
|
struct gendisk *curr_rq_disk = _(rq->rq_disk);
|
|
int major = _(curr_rq_disk->major);
|
|
int first_minor = _(curr_rq_disk->first_minor);
|
|
@@ -734,15 +860,16 @@ int kprobe_blk_mq_start_request(struct pt_regs *regs)
|
|
}
|
|
}
|
|
}
|
|
-
|
|
init_io_counter(&zero, major, first_minor);
|
|
|
|
counterp = bpf_map_lookup_elem(&blk_map, &rq);
|
|
- if (counterp || major == 0)
|
|
+ if (counterp || major == 0) {
|
|
return 0;
|
|
+ }
|
|
long err = bpf_map_update_elem(&blk_map, &rq, &zero, BPF_NOEXIST);
|
|
- if (err)
|
|
+ if (err) {
|
|
return 0;
|
|
+ }
|
|
|
|
u64 curr_start_range = zero.start_time / THRESHOLD;
|
|
|
|
@@ -789,7 +916,7 @@ int kprobe_blk_mq_start_request(struct pt_regs *regs)
|
|
SEC("kprobe/blk_mq_free_request")
|
|
int kprobe_blk_mq_free_request(struct pt_regs *regs)
|
|
{
|
|
- struct request *rq = (struct request *)PT_REGS_PARM1(regs);
|
|
+ struct request_kylin *rq = (struct request_kylin *)PT_REGS_PARM1(regs);
|
|
struct gendisk *curr_rq_disk = _(rq->rq_disk);
|
|
int major = _(curr_rq_disk->major);
|
|
int first_minor = _(curr_rq_disk->first_minor);
|
|
--
|
|
2.33.0
|
|
|