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

Commit d11ea004 authored by Sagi Grimberg's avatar Sagi Grimberg
Browse files

nvmet: confirm sq percpu has scheduled and switched to atomic



percpu_ref_kill is not enough to prevent subsequent
percpu_ref_tryget_live from failing. Hence call
perfcpu_ref_kill_confirm to make it safe.

Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarSagi Grimberg <sagi@grimberg.me>
parent e4c5d376
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -425,6 +425,13 @@ void nvmet_sq_setup(struct nvmet_ctrl *ctrl, struct nvmet_sq *sq,
	ctrl->sqs[qid] = sq;
}

static void nvmet_confirm_sq(struct percpu_ref *ref)
{
	struct nvmet_sq *sq = container_of(ref, struct nvmet_sq, ref);

	complete(&sq->confirm_done);
}

void nvmet_sq_destroy(struct nvmet_sq *sq)
{
	/*
@@ -433,7 +440,8 @@ void nvmet_sq_destroy(struct nvmet_sq *sq)
	 */
	if (sq->ctrl && sq->ctrl->sqs && sq->ctrl->sqs[0] == sq)
		nvmet_async_events_free(sq->ctrl);
	percpu_ref_kill(&sq->ref);
	percpu_ref_kill_and_confirm(&sq->ref, nvmet_confirm_sq);
	wait_for_completion(&sq->confirm_done);
	wait_for_completion(&sq->free_done);
	percpu_ref_exit(&sq->ref);

@@ -461,6 +469,7 @@ int nvmet_sq_init(struct nvmet_sq *sq)
		return ret;
	}
	init_completion(&sq->free_done);
	init_completion(&sq->confirm_done);

	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ struct nvmet_sq {
	u16			qid;
	u16			size;
	struct completion	free_done;
	struct completion	confirm_done;
};

/**