[PATCH 6/7] nvmet: make fused commands be atomic
Dmitry Bogdanov
d.bogdanov at yadro.com
Wed Sep 11 23:42:58 PDT 2024
Ensure that the fused commands are executed in atomic manner. One Fused
pair per whole namespace.
Signed-off-by: Dmitry Bogdanov <d.bogdanov at yadro.com>
---
drivers/nvme/target/core.c | 6 ++++++
drivers/nvme/target/nvmet.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index d5cc760ba2f4..1ab6d8f7a7b1 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -705,6 +705,7 @@ struct nvmet_ns *nvmet_ns_alloc(struct nvmet_subsys *subsys, u32 nsid)
uuid_gen(&ns->uuid);
ns->buffered_io = false;
ns->csi = NVME_CSI_NVM;
+ sema_init(&ns->caw_lock, 1);
return ns;
}
@@ -872,6 +873,8 @@ static void __nvmet_fused_req_complete(struct nvmet_req *req,
spin_unlock(&second_req->fused_lock);
spin_unlock_irqrestore(&first_req->fused_lock, flags);
+ up(&req->ns->caw_lock);
+
if (first_req->ns)
nvmet_put_namespace(first_req->ns);
first_req->ops->queue_response(first_req);
@@ -1376,6 +1379,8 @@ void nvmet_req_execute(struct nvmet_req *req)
if (req->fused_pair->fused_state == NVMET_FUSED_STATE_EXECUTING) {
spin_unlock(&req->fused_pair->fused_lock);
spin_unlock(&req->fused_lock);
+
+ down(&req->ns->caw_lock);
req->execute(req);
return;
}
@@ -1411,6 +1416,7 @@ void nvmet_req_execute(struct nvmet_req *req)
spin_unlock(&req->fused_lock);
spin_unlock(&first_req->fused_lock);
/* both fused command are ready to execute */
+ down(&req->ns->caw_lock);
first_req->execute(first_req);
return;
}
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 1278b81c85a7..1dc9814c7a8c 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -85,6 +85,7 @@ struct nvmet_ns {
int pi_type;
int metadata_size;
u8 csi;
+ struct semaphore caw_lock;
};
static inline struct nvmet_ns *to_nvmet_ns(struct config_item *item)
--
2.25.1
More information about the Linux-nvme
mailing list