Skip to content

Commit 2f2b20f

Browse files
damien-lemoalkeithbusch
authored andcommitted
nvmet: Implement host identifier set feature support
The NVMe specifications mandate support for the host identifier set_features for controllers that also supports reservations. Satisfy this requirement by implementing handling of the NVME_FEAT_HOST_ID feature for the nvme_set_features command. This implementation is for now effective only for PCI target controllers. For other controller types, the set features command is failed with a NVME_SC_CMD_SEQ_ERROR status as before. As noted in the code, 128 bits host identifiers are supported since the NVMe base specifications version 2.1 indicate in section 5.1.25.1.28.1 that "The controller may support a 64-bit Host Identifier...". The RHII (Reservations and Host Identifier Interaction) bit of the controller attribute (ctratt) field of the identify controller data is also set to indicate that a host ID of "0" is supported but that the host ID must be a non-zero value to use reservations. Signed-off-by: Damien Le Moal <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Tested-by: Rick Wertenbroek <[email protected]> Tested-by: Manivannan Sadhasivam <[email protected]> Signed-off-by: Keith Busch <[email protected]>
1 parent 0846153 commit 2f2b20f

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

drivers/nvme/target/admin-cmd.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
659659
struct nvmet_ctrl *ctrl = req->sq->ctrl;
660660
struct nvmet_subsys *subsys = ctrl->subsys;
661661
struct nvme_id_ctrl *id;
662-
u32 cmd_capsule_size;
662+
u32 cmd_capsule_size, ctratt;
663663
u16 status = 0;
664664

665665
if (!subsys->subsys_discovered) {
@@ -707,8 +707,10 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
707707

708708
/* XXX: figure out what to do about RTD3R/RTD3 */
709709
id->oaes = cpu_to_le32(NVMET_AEN_CFG_OPTIONAL);
710-
id->ctratt = cpu_to_le32(NVME_CTRL_ATTR_HID_128_BIT |
711-
NVME_CTRL_ATTR_TBKAS);
710+
ctratt = NVME_CTRL_ATTR_HID_128_BIT | NVME_CTRL_ATTR_TBKAS;
711+
if (nvmet_is_pci_ctrl(ctrl))
712+
ctratt |= NVME_CTRL_ATTR_RHII;
713+
id->ctratt = cpu_to_le32(ctratt);
712714

713715
id->oacs = 0;
714716

@@ -1255,6 +1257,31 @@ u16 nvmet_set_feat_async_event(struct nvmet_req *req, u32 mask)
12551257
return 0;
12561258
}
12571259

1260+
static u16 nvmet_set_feat_host_id(struct nvmet_req *req)
1261+
{
1262+
struct nvmet_ctrl *ctrl = req->sq->ctrl;
1263+
1264+
if (!nvmet_is_pci_ctrl(ctrl))
1265+
return NVME_SC_CMD_SEQ_ERROR | NVME_STATUS_DNR;
1266+
1267+
/*
1268+
* The NVMe base specifications v2.1 recommends supporting 128-bits host
1269+
* IDs (section 5.1.25.1.28.1). However, that same section also says
1270+
* that "The controller may support a 64-bit Host Identifier and/or an
1271+
* extended 128-bit Host Identifier". So simplify this support and do
1272+
* not support 64-bits host IDs to avoid needing to check that all
1273+
* controllers associated with the same subsystem all use the same host
1274+
* ID size.
1275+
*/
1276+
if (!(req->cmd->common.cdw11 & cpu_to_le32(1 << 0))) {
1277+
req->error_loc = offsetof(struct nvme_common_command, cdw11);
1278+
return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
1279+
}
1280+
1281+
return nvmet_copy_from_sgl(req, 0, &req->sq->ctrl->hostid,
1282+
sizeof(req->sq->ctrl->hostid));
1283+
}
1284+
12581285
void nvmet_execute_set_features(struct nvmet_req *req)
12591286
{
12601287
struct nvmet_subsys *subsys = nvmet_req_subsys(req);
@@ -1285,7 +1312,7 @@ void nvmet_execute_set_features(struct nvmet_req *req)
12851312
status = nvmet_set_feat_async_event(req, NVMET_AEN_CFG_ALL);
12861313
break;
12871314
case NVME_FEAT_HOST_ID:
1288-
status = NVME_SC_CMD_SEQ_ERROR | NVME_STATUS_DNR;
1315+
status = nvmet_set_feat_host_id(req);
12891316
break;
12901317
case NVME_FEAT_WRITE_PROTECT:
12911318
status = nvmet_set_feat_write_protect(req);

include/linux/nvme.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ enum nvme_ctrl_attr {
276276
NVME_CTRL_ATTR_HID_128_BIT = (1 << 0),
277277
NVME_CTRL_ATTR_TBKAS = (1 << 6),
278278
NVME_CTRL_ATTR_ELBAS = (1 << 15),
279+
NVME_CTRL_ATTR_RHII = (1 << 18),
279280
};
280281

281282
struct nvme_id_ctrl {

0 commit comments

Comments
 (0)