Skip to content

Commit f1ecd49

Browse files
damien-lemoalkeithbusch
authored andcommitted
nvmet: Implement interrupt config feature support
The NVMe base specifications v2.1 mandate supporting the interrupt config feature (NVME_FEAT_IRQ_CONFIG) for PCI controllers. Introduce the data structure struct nvmet_feat_irq_config to define the coalescing disabled (cd) and interrupt vector (iv) fields of this feature and implement the functions nvmet_get_feat_irq_config() and nvmet_set_feat_irq_config() functions to get and set these fields. These functions respectively use the controller get_feature() and set_feature() operations to fill and handle the fields of struct nvmet_feat_irq_config. Support for this feature is prohibited for fabrics controllers. If a get feature command or a set feature command for this feature is received for a fabrics controller, the command is failed with an invalid field error. 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 89b94a6 commit f1ecd49

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

drivers/nvme/target/admin-cmd.c

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,27 @@ static u16 nvmet_set_feat_irq_coalesce(struct nvmet_req *req)
13031303
return ctrl->ops->set_feature(ctrl, NVME_FEAT_IRQ_COALESCE, &irqc);
13041304
}
13051305

1306+
static u16 nvmet_set_feat_irq_config(struct nvmet_req *req)
1307+
{
1308+
struct nvmet_ctrl *ctrl = req->sq->ctrl;
1309+
u32 cdw11 = le32_to_cpu(req->cmd->common.cdw11);
1310+
struct nvmet_feat_irq_config irqcfg = {
1311+
.iv = cdw11 & 0xffff,
1312+
.cd = (cdw11 >> 16) & 0x1,
1313+
};
1314+
1315+
/*
1316+
* This feature is not supported for fabrics controllers and mandatory
1317+
* for PCI controllers.
1318+
*/
1319+
if (!nvmet_is_pci_ctrl(ctrl)) {
1320+
req->error_loc = offsetof(struct nvme_common_command, cdw10);
1321+
return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
1322+
}
1323+
1324+
return ctrl->ops->set_feature(ctrl, NVME_FEAT_IRQ_CONFIG, &irqcfg);
1325+
}
1326+
13061327
void nvmet_execute_set_features(struct nvmet_req *req)
13071328
{
13081329
struct nvmet_subsys *subsys = nvmet_req_subsys(req);
@@ -1329,6 +1350,9 @@ void nvmet_execute_set_features(struct nvmet_req *req)
13291350
case NVME_FEAT_IRQ_COALESCE:
13301351
status = nvmet_set_feat_irq_coalesce(req);
13311352
break;
1353+
case NVME_FEAT_IRQ_CONFIG:
1354+
status = nvmet_set_feat_irq_config(req);
1355+
break;
13321356
case NVME_FEAT_KATO:
13331357
status = nvmet_set_feat_kato(req);
13341358
break;
@@ -1397,6 +1421,31 @@ static u16 nvmet_get_feat_irq_coalesce(struct nvmet_req *req)
13971421
return NVME_SC_SUCCESS;
13981422
}
13991423

1424+
static u16 nvmet_get_feat_irq_config(struct nvmet_req *req)
1425+
{
1426+
struct nvmet_ctrl *ctrl = req->sq->ctrl;
1427+
u32 iv = le32_to_cpu(req->cmd->common.cdw11) & 0xffff;
1428+
struct nvmet_feat_irq_config irqcfg = { .iv = iv };
1429+
u16 status;
1430+
1431+
/*
1432+
* This feature is not supported for fabrics controllers and mandatory
1433+
* for PCI controllers.
1434+
*/
1435+
if (!nvmet_is_pci_ctrl(ctrl)) {
1436+
req->error_loc = offsetof(struct nvme_common_command, cdw10);
1437+
return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
1438+
}
1439+
1440+
status = ctrl->ops->get_feature(ctrl, NVME_FEAT_IRQ_CONFIG, &irqcfg);
1441+
if (status != NVME_SC_SUCCESS)
1442+
return status;
1443+
1444+
nvmet_set_result(req, ((u32)irqcfg.cd << 16) | iv);
1445+
1446+
return NVME_SC_SUCCESS;
1447+
}
1448+
14001449
void nvmet_get_feat_kato(struct nvmet_req *req)
14011450
{
14021451
nvmet_set_result(req, req->sq->ctrl->kato * 1000);
@@ -1431,14 +1480,15 @@ void nvmet_execute_get_features(struct nvmet_req *req)
14311480
break;
14321481
case NVME_FEAT_ERR_RECOVERY:
14331482
break;
1434-
case NVME_FEAT_IRQ_CONFIG:
1435-
break;
14361483
case NVME_FEAT_WRITE_ATOMIC:
14371484
break;
14381485
#endif
14391486
case NVME_FEAT_IRQ_COALESCE:
14401487
status = nvmet_get_feat_irq_coalesce(req);
14411488
break;
1489+
case NVME_FEAT_IRQ_CONFIG:
1490+
status = nvmet_get_feat_irq_config(req);
1491+
break;
14421492
case NVME_FEAT_ASYNC_EVENT:
14431493
nvmet_get_feat_async_event(req);
14441494
break;

drivers/nvme/target/nvmet.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,4 +916,9 @@ struct nvmet_feat_irq_coalesce {
916916
u8 time;
917917
};
918918

919+
struct nvmet_feat_irq_config {
920+
u16 iv;
921+
bool cd;
922+
};
923+
919924
#endif /* _NVMET_H */

0 commit comments

Comments
 (0)