@@ -132,7 +132,7 @@ static int nvme_submit_user_cmd(struct request_queue *q,
struct nvme_command *cmd, u64 ubuffer,
unsigned bufflen, void __user *meta_buffer, unsigned meta_len,
u32 meta_seed, u64 *result, unsigned timeout,
- struct io_uring_cmd *ioucmd)
+ struct io_uring_cmd *ioucmd, unsigned int rq_flags)
{
bool write = nvme_is_write(cmd);
struct nvme_ns *ns = q->queuedata;
@@ -140,7 +140,6 @@ static int nvme_submit_user_cmd(struct request_queue *q,
struct request *req;
struct bio *bio = NULL;
void *meta = NULL;
- unsigned int rq_flags = 0;
blk_mq_req_flags_t blk_flags = 0;
int ret;
@@ -216,11 +215,12 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
struct nvme_command c;
unsigned length, meta_len;
void __user *metadata;
+ unsigned int rq_flags = 0;
if (copy_from_user(&io, uio, sizeof(io)))
return -EFAULT;
- if (io.flags)
- return -EINVAL;
+ if (io.flags & NVME_HIPRI)
+ rq_flags |= REQ_POLLED;
switch (io.opcode) {
case nvme_cmd_write:
@@ -258,7 +258,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
memset(&c, 0, sizeof(c));
c.rw.opcode = io.opcode;
- c.rw.flags = io.flags;
+ c.rw.flags = 0;
c.rw.nsid = cpu_to_le32(ns->head->ns_id);
c.rw.slba = cpu_to_le64(io.slba);
c.rw.length = cpu_to_le16(io.nblocks);
@@ -270,7 +270,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
return nvme_submit_user_cmd(ns->queue, &c,
io.addr, length, metadata, meta_len,
- lower_32_bits(io.slba), NULL, 0, NULL);
+ lower_32_bits(io.slba), NULL, 0, NULL, rq_flags);
}
static bool nvme_validate_passthru_nsid(struct nvme_ctrl *ctrl,
@@ -292,6 +292,7 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
{
struct nvme_passthru_cmd cmd;
struct nvme_command c;
+ unsigned int rq_flags = 0;
unsigned timeout = 0;
u64 result;
int status;
@@ -300,14 +301,14 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
return -EACCES;
if (copy_from_user(&cmd, ucmd, sizeof(cmd)))
return -EFAULT;
- if (cmd.flags)
- return -EINVAL;
+ if (cmd.flags & NVME_HIPRI)
+ rq_flags |= REQ_POLLED;
if (!nvme_validate_passthru_nsid(ctrl, ns, cmd.nsid))
return -EINVAL;
memset(&c, 0, sizeof(c));
c.common.opcode = cmd.opcode;
- c.common.flags = cmd.flags;
+ c.common.flags = 0;
c.common.nsid = cpu_to_le32(cmd.nsid);
c.common.cdw2[0] = cpu_to_le32(cmd.cdw2);
c.common.cdw2[1] = cpu_to_le32(cmd.cdw3);
@@ -323,7 +324,7 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
cmd.addr, cmd.data_len, nvme_to_user_ptr(cmd.metadata),
- cmd.metadata_len, 0, &result, timeout, NULL);
+ cmd.metadata_len, 0, &result, timeout, NULL, rq_flags);
if (status >= 0) {
if (put_user(result, &ucmd->result))
@@ -339,6 +340,7 @@ static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
{
struct nvme_passthru_cmd64 cmd, *cptr;
struct nvme_command c;
+ unsigned int rq_flags = 0;
unsigned timeout = 0;
int status;
@@ -353,14 +355,14 @@ static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
return -EINVAL;
cptr = (struct nvme_passthru_cmd64 *)ioucmd->cmd;
}
- if (cptr->flags)
- return -EINVAL;
+ if (cptr->flags & NVME_HIPRI)
+ rq_flags |= REQ_POLLED;
if (!nvme_validate_passthru_nsid(ctrl, ns, cptr->nsid))
return -EINVAL;
memset(&c, 0, sizeof(c));
c.common.opcode = cptr->opcode;
- c.common.flags = cptr->flags;
+ c.common.flags = 0;
c.common.nsid = cpu_to_le32(cptr->nsid);
c.common.cdw2[0] = cpu_to_le32(cptr->cdw2);
c.common.cdw2[1] = cpu_to_le32(cptr->cdw3);
@@ -377,7 +379,7 @@ static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
cptr->addr, cptr->data_len,
nvme_to_user_ptr(cptr->metadata), cptr->metadata_len,
- 0, &cptr->result, timeout, ioucmd);
+ 0, &cptr->result, timeout, ioucmd, rq_flags);
if (!ioucmd && status >= 0) {
if (put_user(cptr->result, &ucmd->result))
@@ -9,6 +9,10 @@
#include <linux/types.h>
+enum nvme_io_flags {
+ NVME_HIPRI = 1 << 0, /* use polling queue if available */
+};
+
struct nvme_user_io {
__u8 opcode;
__u8 flags;