summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wilcox <matthew.r.wilcox@intel.com>2011-02-04 16:14:30 -0500
committerMatthew Wilcox <matthew.r.wilcox@intel.com>2011-11-04 15:52:55 -0400
commitb1ad37efcafe396ac3944853589688dd0ec3c64e (patch)
tree49f8d3fa7080ccf85edbb75239e98a89cdd037c9
parent3c0cf138d7789feb3f335f6f1d24ad8fc8b3a23f (diff)
NVMe: Call put_nvmeq() before calling nvme_submit_sync_cmd()
We can't have preemption disabled when we call schedule(). Accept the possibility that we'll get preempted, and it'll cost us some cacheline bounces. Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com>
-rw-r--r--drivers/block/nvme.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c
index 4bfed59f362..1c3cd6cc0ad 100644
--- a/drivers/block/nvme.c
+++ b/drivers/block/nvme.c
@@ -842,8 +842,13 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
nvme_setup_prps(&c.common, sg, length);
nvmeq = get_nvmeq(ns);
- status = nvme_submit_sync_cmd(nvmeq, &c, &result);
+ /* Since nvme_submit_sync_cmd sleeps, we can't keep preemption
+ * disabled. We may be preempted at any point, and be rescheduled
+ * to a different CPU. That will cause cacheline bouncing, but no
+ * additional races since q_lock already protects against other CPUs.
+ */
put_nvmeq(nvmeq);
+ status = nvme_submit_sync_cmd(nvmeq, &c, &result);
nvme_unmap_user_pages(dev, io.opcode & 1, io.addr, length, sg, nents);
put_user(result, &uio->result);