struct cmdprio cmdprio;
- struct nvme_dsm_range *dsm;
+ struct nvme_dsm *dsm;
};
struct ioring_options {
struct fio_file *f = io_u->file;
struct nvme_uring_cmd *cmd;
struct io_uring_sqe *sqe;
+ struct nvme_dsm *dsm;
+ void *ptr = ld->dsm;
+ unsigned int dsm_size;
/* only supports nvme_uring_cmd */
if (o->cmd_type != FIO_URING_CMD_NVME)
}
cmd = (struct nvme_uring_cmd *)sqe->cmd;
+ dsm_size = sizeof(*ld->dsm) + td->o.num_range * sizeof(struct nvme_dsm_range);
+ ptr += io_u->index * dsm_size;
+ dsm = (struct nvme_dsm *)ptr;
+
return fio_nvme_uring_cmd_prep(cmd, io_u,
o->nonvectored ? NULL : &ld->iovecs[io_u->index],
- &ld->dsm[io_u->index]);
+ dsm);
}
static struct io_u *fio_ioring_event(struct thread_data *td, int event)
{
struct ioring_options *o = td->eo;
struct ioring_data *ld;
+ struct nvme_dsm *dsm;
+ void *ptr;
+ unsigned int dsm_size;
unsigned long long md_size;
- int ret;
+ int ret, i;
/* sqthread submission requires registered files */
if (o->sqpoll_thread)
* in zbd mode where trim means zone reset.
*/
if (!strcmp(td->io_ops->name, "io_uring_cmd") && td_trim(td) &&
- td->o.zone_mode == ZONE_MODE_ZBD)
+ td->o.zone_mode == ZONE_MODE_ZBD) {
td->io_ops->flags |= FIO_ASYNCIO_SYNC_TRIM;
- else
- ld->dsm = calloc(td->o.iodepth, sizeof(*ld->dsm));
+ } else {
+ dsm_size = sizeof(*ld->dsm) +
+ td->o.num_range * sizeof(struct nvme_dsm_range);
+ ld->dsm = calloc(td->o.iodepth, dsm_size);
+ ptr = ld->dsm;
+ for (i = 0; i < td->o.iodepth; i++) {
+ dsm = (struct nvme_dsm *)ptr;
+ dsm->nr_ranges = td->o.num_range;
+ ptr += dsm_size;
+ }
+ }
return 0;
}
.name = "io_uring_cmd",
.version = FIO_IOOPS_VERSION,
.flags = FIO_NO_OFFLOAD | FIO_MEMALIGN | FIO_RAWIO |
- FIO_ASYNCIO_SETS_ISSUE_TIME,
+ FIO_ASYNCIO_SETS_ISSUE_TIME |
+ FIO_MULTI_RANGE_TRIM,
.init = fio_ioring_init,
.post_init = fio_ioring_cmd_post_init,
.io_u_init = fio_ioring_io_u_init,
return 0;
}
void fio_nvme_uring_cmd_trim_prep(struct nvme_uring_cmd *cmd, struct io_u *io_u,
- struct nvme_dsm_range *dsm)
+ struct nvme_dsm *dsm)
{
struct nvme_data *data = FILE_ENG_DATA(io_u->file);
+ struct trim_range *range;
+ uint8_t *buf_point;
+ int i;
cmd->opcode = nvme_cmd_dsm;
cmd->nsid = data->nsid;
- cmd->cdw10 = 0;
cmd->cdw11 = NVME_ATTRIBUTE_DEALLOCATE;
- cmd->addr = (__u64) (uintptr_t) dsm;
- cmd->data_len = sizeof(*dsm);
-
- dsm->slba = get_slba(data, io_u);
- /* nlb is a 1-based value for deallocate */
- dsm->nlb = get_nlb(data, io_u) + 1;
+ cmd->addr = (__u64) (uintptr_t) (&dsm->range[0]);
+
+ if (dsm->nr_ranges == 1) {
+ dsm->range[0].slba = get_slba(data, io_u->offset);
+ /* nlb is a 1-based value for deallocate */
+ dsm->range[0].nlb = get_nlb(data, io_u->xfer_buflen) + 1;
+ cmd->cdw10 = 0;
+ cmd->data_len = sizeof(struct nvme_dsm_range);
+ } else {
+ buf_point = io_u->xfer_buf;
+ for (i = 0; i < io_u->number_trim; i++) {
+ range = (struct trim_range *)buf_point;
+ dsm->range[i].slba = get_slba(data, range->start);
+ /* nlb is a 1-based value for deallocate */
+ dsm->range[i].nlb = get_nlb(data, range->len) + 1;
+ buf_point += sizeof(struct trim_range);
+ }
+ cmd->cdw10 = io_u->number_trim - 1;
+ cmd->data_len = io_u->number_trim * sizeof(struct nvme_dsm_range);
+ }
}
int fio_nvme_uring_cmd_prep(struct nvme_uring_cmd *cmd, struct io_u *io_u,
- struct iovec *iov, struct nvme_dsm_range *dsm)
+ struct iovec *iov, struct nvme_dsm *dsm)
{
struct nvme_data *data = FILE_ENG_DATA(io_u->file);
__u64 slba;
__le64 slba;
};
+struct nvme_dsm {
+ __u32 nr_ranges;
+ struct nvme_dsm_range range[];
+};
+
struct nvme_cmd_ext_io_opts {
__u32 io_flags;
__u16 apptag;
struct nvme_data *data);
int fio_nvme_uring_cmd_prep(struct nvme_uring_cmd *cmd, struct io_u *io_u,
- struct iovec *iov, struct nvme_dsm_range *dsm);
+ struct iovec *iov, struct nvme_dsm *dsm);
void fio_nvme_pi_fill(struct nvme_uring_cmd *cmd, struct io_u *io_u,
struct nvme_cmd_ext_io_opts *opts);
--- /dev/null
+# Multi-range trim command test with io_uring_cmd I/O engine for nvme-ns
+# generic character device.
+#
+[global]
+filename=/dev/ng0n1
+ioengine=io_uring_cmd
+cmd_type=nvme
+size=10M
+iodepth=32
+thread=1
+stonewall=1
+
+[write_bs]
+bs=4096
+rw=randtrim
+num_range=8
+
+[write_bssplit]
+bssplit=4k/10:64k/50:32k/40
+rw=trim
+num_range=8