bpftrace get nvme trim range data

27 views Asked by At

I want to use bpftrace to get the nvme trim command 's starting lba and number of blocks, but no results due to the trim data structure(nvme_dsm_range) is in prp or prp list, I have no idea to parse it.

I want to know if have any other way to get the data in nvme trim command(dataset management command)?

static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req, struct nvme_command *cmnd)
{
    unsigned short segments = blk_rq_nr_discard_segments(req), n = 0;
    **struct nvme_dsm_range *range;**
    struct bio *bio;

    static const size_t alloc_size = sizeof(*range) * NVME_DSM_MAX_RANGES;

    range = kzalloc(alloc_size, GFP_ATOMIC | __GFP_NOWARN);
    if (!range) {
        /*
         * If we fail allocation our range, fallback to the controller
         * discard page. If that's also busy, it's safe to return
         * busy, as we know we can make progress once that's freed.
         */
        if (test_and_set_bit_lock(0, &ns->ctrl->discard_page_busy))
            return BLK_STS_RESOURCE;

        range = page_address(ns->ctrl->discard_page);
    }

    __rq_for_each_bio(bio, req) {
        u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector);
        u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift;

        if (n < segments) {
            **range[n].cattr = cpu_to_le32(0);
            range[n].nlb = cpu_to_le32(nlb);
            range[n].slba = cpu_to_le64(slba);**
        }
        n++;
    }

    if (WARN_ON_ONCE(n != segments)) {
        if (virt_to_page(range) == ns->ctrl->discard_page)
            clear_bit_unlock(0, &ns->ctrl->discard_page_busy);
        else
            kfree(range);
        return BLK_STS_IOERR;
    }

    cmnd->dsm.opcode = nvme_cmd_dsm;
    cmnd->dsm.nsid = cpu_to_le32(ns->head->ns_id);
    cmnd->dsm.nr = cpu_to_le32(segments - 1);
    cmnd->dsm.attributes = cpu_to_le32(NVME_DSMGMT_AD);

    req->special_vec.bv_page = virt_to_page(range);
    req->special_vec.bv_offset = offset_in_page(range);
    req->special_vec.bv_len = alloc_size;
    req->rq_flags |= RQF_SPECIAL_PAYLOAD;

    return BLK_STS_OK;
}

bpftrace trace-trim.bpftrace

result: start lba:0 number of blocks: 4

0

There are 0 answers