Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a51afb54 authored by Keith Busch's avatar Keith Busch Committed by Matthew Wilcox
Browse files

NVMe: Fix nvme get/put queue semantics



The routines to get and lock nvme queues required the caller to "put"
or "unlock" them even if getting one returned NULL. This patch fixes that.

Signed-off-by: default avatarKeith Busch <keith.busch@intel.com>
Signed-off-by: default avatarMatthew Wilcox <matthew.r.wilcox@intel.com>
parent de672b97
Loading
Loading
Loading
Loading
+21 −8
Original line number Diff line number Diff line
@@ -285,9 +285,17 @@ static struct nvme_queue *raw_nvmeq(struct nvme_dev *dev, int qid)

static struct nvme_queue *get_nvmeq(struct nvme_dev *dev) __acquires(RCU)
{
	struct nvme_queue *nvmeq;
	unsigned queue_id = get_cpu_var(*dev->io_queue);

	rcu_read_lock();
	return rcu_dereference(dev->queues[queue_id]);
	nvmeq = rcu_dereference(dev->queues[queue_id]);
	if (nvmeq)
		return nvmeq;

	rcu_read_unlock();
	put_cpu_var(*dev->io_queue);
	return NULL;
}

static void put_nvmeq(struct nvme_queue *nvmeq) __releases(RCU)
@@ -299,8 +307,15 @@ static void put_nvmeq(struct nvme_queue *nvmeq) __releases(RCU)
static struct nvme_queue *lock_nvmeq(struct nvme_dev *dev, int q_idx)
							__acquires(RCU)
{
	struct nvme_queue *nvmeq;

	rcu_read_lock();
	return rcu_dereference(dev->queues[q_idx]);
	nvmeq = rcu_dereference(dev->queues[q_idx]);
	if (nvmeq)
		return nvmeq;

	rcu_read_unlock();
	return NULL;
}

static void unlock_nvmeq(struct nvme_queue *nvmeq) __releases(RCU)
@@ -809,7 +824,6 @@ static void nvme_make_request(struct request_queue *q, struct bio *bio)
	int result = -EBUSY;

	if (!nvmeq) {
		put_nvmeq(NULL);
		bio_endio(bio, -EIO);
		return;
	}
@@ -884,10 +898,8 @@ static int nvme_submit_sync_cmd(struct nvme_dev *dev, int q_idx,
	struct nvme_queue *nvmeq;

	nvmeq = lock_nvmeq(dev, q_idx);
	if (!nvmeq) {
		unlock_nvmeq(nvmeq);
	if (!nvmeq)
		return -ENODEV;
	}

	cmdinfo.task = current;
	cmdinfo.status = -EINTR;
@@ -912,9 +924,10 @@ static int nvme_submit_sync_cmd(struct nvme_dev *dev, int q_idx,

	if (cmdinfo.status == -EINTR) {
		nvmeq = lock_nvmeq(dev, q_idx);
		if (nvmeq)
		if (nvmeq) {
			nvme_abort_command(nvmeq, cmdid);
			unlock_nvmeq(nvmeq);
		}
		return -EINTR;
	}