Skip to content

Commit

Permalink
NVMe dtrace probes (#39)
Browse files Browse the repository at this point in the history
Add probes for NVMe read/write operations and example dtrace script.
  • Loading branch information
luqmana committed Sep 2, 2021
1 parent e016a5b commit faebb4f
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
/*/target
**/Cargo.lock
debug.out
core
12 changes: 12 additions & 0 deletions propolis/src/hw/nvme/ns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ impl NvmeNs {
cq: Arc<Mutex<CompQueue>>,
sq: Arc<Mutex<SubQueue>>,
) {
probe_nvme_read_enqueue!(|| (cid, cmd.slba, cmd.nlb));
let off = self.nlb_to_size(cmd.slba as usize);
let size = self.nlb_to_size(cmd.nlb as usize);
// TODO: handles if it gets unmapped?
Expand All @@ -180,6 +181,7 @@ impl NvmeNs {
cq: Arc<Mutex<CompQueue>>,
sq: Arc<Mutex<SubQueue>>,
) {
probe_nvme_write_enqueue!(|| (cid, cmd.slba, cmd.nlb));
let off = self.nlb_to_size(cmd.slba as usize);
let size = self.nlb_to_size(cmd.nlb as usize);
// TODO: handles if it gets unmapped?
Expand Down Expand Up @@ -257,6 +259,16 @@ impl BlockReq for Request {
),
};

match self.op {
BlockOp::Read => {
probe_nvme_read_complete!(|| (self.cid));
}
BlockOp::Write => {
probe_nvme_write_complete!(|| (self.cid));
}
_ => {}
}

let sq = self.sq.lock().unwrap();
let mut cq = self.cq.lock().unwrap();

Expand Down
10 changes: 10 additions & 0 deletions propolis/usdt.d
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,14 @@ provider propolis {

/* vm_exit(vcpuid, rip, code) */
probe vm_exit(uint32_t, uint64_t, uint32_t);

/* nvme_read_enqueue(cid, slba, nlb) */
probe nvme_read_enqueue(uint16_t, uint64_t, uint16_t);
/* nvme_read_complete(cid) */
probe nvme_read_complete(uint16_t);

/* nvme_write_enqueue(cid, slba, nlb) */
probe nvme_write_enqueue(uint16_t, uint64_t, uint16_t);
/* nvme_write_complete(cid) */
probe nvme_write_complete(uint16_t);
};
50 changes: 50 additions & 0 deletions scripts/nvme-trace.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/sbin/dtrace -s

/*
* nvme-trace.d Print propolis emulated NVMe read/write latency.
*
* USAGE: ./nvme-trace.d -p propolis-pid
*/

#pragma D option quiet

dtrace:::BEGIN
{
printf("Tracing propolis PID %d... Hit Ctrl-C to end.\n", $target);
}

struct io_info {
string op;
uint64_t ts;
uint64_t slba;
uint16_t nlb;
};

struct io_info io[uint64_t];

propolis$target:::nvme_read_enqueue,
propolis$target:::nvme_write_enqueue
{
this->cid = args[0];
this->op = (probename == "nvme_read_enqueue") ? "read" : "write";
io[this->cid].op = this->op;
io[this->cid].ts = timestamp;
io[this->cid].slba = args[1];
io[this->cid].nlb = args[2];
}

propolis$target:::nvme_read_complete,
propolis$target:::nvme_write_complete
/io[args[0]].ts != 0/
{
this->cid = args[0];
this->elapsed = timestamp - io[this->cid].ts;
this->elapsed_us = this->elapsed / 1000;
@time[io[this->cid].op] = quantize(this->elapsed_us);
printf("%s(cid=%u) %d blocks from LBA 0x%x in %uus\n",
io[this->cid].op, this->cid, io[this->cid].nlb, io[this->cid].slba, this->elapsed_us);
}

dtrace:::END
{
}

0 comments on commit faebb4f

Please sign in to comment.