biotop and biosnoop: save __data_len at blk_start_request
Commit 95c9229ea9f029a1b9e8dcbe86fc67f037c0dfa2 replaced the
blk_account_io_completion kprobe with blk_account_io_done. Unfortunately
the req->__data_len field is 0 in blk_account_io_done, therefore we need
to save the __data_len field in blk_start_request
Resolves #3099
diff --git a/tools/biosnoop.py b/tools/biosnoop.py
index 5bbc77c..333949b 100755
--- a/tools/biosnoop.py
+++ b/tools/biosnoop.py
@@ -39,6 +39,12 @@
#include <uapi/linux/ptrace.h>
#include <linux/blkdev.h>
+// for saving the timestamp and __data_len of each request
+struct start_req_t {
+ u64 ts;
+ u64 data_len;
+};
+
struct val_t {
u64 ts;
u32 pid;
@@ -57,7 +63,7 @@
char name[TASK_COMM_LEN];
};
-BPF_HASH(start, struct request *);
+BPF_HASH(start, struct request *, struct start_req_t);
BPF_HASH(infobyreq, struct request *, struct val_t);
BPF_PERF_OUTPUT(events);
@@ -80,42 +86,43 @@
// time block I/O
int trace_req_start(struct pt_regs *ctx, struct request *req)
{
- u64 ts;
- ts = bpf_ktime_get_ns();
- start.update(&req, &ts);
+ struct start_req_t start_req = {
+ .ts = bpf_ktime_get_ns(),
+ .data_len = req->__data_len
+ };
+ start.update(&req, &start_req);
return 0;
}
// output
int trace_req_completion(struct pt_regs *ctx, struct request *req)
{
- u64 *tsp;
+ struct start_req_t *startp;
struct val_t *valp;
struct data_t data = {};
u64 ts;
// fetch timestamp and calculate delta
- tsp = start.lookup(&req);
- if (tsp == 0) {
+ startp = start.lookup(&req);
+ if (startp == 0) {
// missed tracing issue
return 0;
}
ts = bpf_ktime_get_ns();
- data.delta = ts - *tsp;
+ data.delta = ts - startp->ts;
data.ts = ts / 1000;
data.qdelta = 0;
valp = infobyreq.lookup(&req);
+ data.len = startp->data_len;
if (valp == 0) {
- data.len = req->__data_len;
data.name[0] = '?';
data.name[1] = 0;
} else {
if (##QUEUE##) {
- data.qdelta = *tsp - valp->ts;
+ data.qdelta = startp->ts - valp->ts;
}
data.pid = valp->pid;
- data.len = req->__data_len;
data.sector = req->__sector;
bpf_probe_read_kernel(&data.name, sizeof(data.name), valp->name);
struct gendisk *rq_disk = req->rq_disk;