Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <dlemoal@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Tested-by: Rick Wertenbroek <rick.wertenbroek@gmail.com>
Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Keith Busch <kbusch@kernel.org>

authored by

Damien Le Moal and committed by
Keith Busch
f1ecd491 89b94a6c

+57 -2
+52 -2
drivers/nvme/target/admin-cmd.c
··· 1303 1303 return ctrl->ops->set_feature(ctrl, NVME_FEAT_IRQ_COALESCE, &irqc); 1304 1304 } 1305 1305 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 + 1306 1327 void nvmet_execute_set_features(struct nvmet_req *req) 1307 1328 { 1308 1329 struct nvmet_subsys *subsys = nvmet_req_subsys(req); ··· 1349 1328 break; 1350 1329 case NVME_FEAT_IRQ_COALESCE: 1351 1330 status = nvmet_set_feat_irq_coalesce(req); 1331 + break; 1332 + case NVME_FEAT_IRQ_CONFIG: 1333 + status = nvmet_set_feat_irq_config(req); 1352 1334 break; 1353 1335 case NVME_FEAT_KATO: 1354 1336 status = nvmet_set_feat_kato(req); ··· 1421 1397 return NVME_SC_SUCCESS; 1422 1398 } 1423 1399 1400 + static u16 nvmet_get_feat_irq_config(struct nvmet_req *req) 1401 + { 1402 + struct nvmet_ctrl *ctrl = req->sq->ctrl; 1403 + u32 iv = le32_to_cpu(req->cmd->common.cdw11) & 0xffff; 1404 + struct nvmet_feat_irq_config irqcfg = { .iv = iv }; 1405 + u16 status; 1406 + 1407 + /* 1408 + * This feature is not supported for fabrics controllers and mandatory 1409 + * for PCI controllers. 1410 + */ 1411 + if (!nvmet_is_pci_ctrl(ctrl)) { 1412 + req->error_loc = offsetof(struct nvme_common_command, cdw10); 1413 + return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; 1414 + } 1415 + 1416 + status = ctrl->ops->get_feature(ctrl, NVME_FEAT_IRQ_CONFIG, &irqcfg); 1417 + if (status != NVME_SC_SUCCESS) 1418 + return status; 1419 + 1420 + nvmet_set_result(req, ((u32)irqcfg.cd << 16) | iv); 1421 + 1422 + return NVME_SC_SUCCESS; 1423 + } 1424 + 1424 1425 void nvmet_get_feat_kato(struct nvmet_req *req) 1425 1426 { 1426 1427 nvmet_set_result(req, req->sq->ctrl->kato * 1000); ··· 1480 1431 break; 1481 1432 case NVME_FEAT_ERR_RECOVERY: 1482 1433 break; 1483 - case NVME_FEAT_IRQ_CONFIG: 1484 - break; 1485 1434 case NVME_FEAT_WRITE_ATOMIC: 1486 1435 break; 1487 1436 #endif 1488 1437 case NVME_FEAT_IRQ_COALESCE: 1489 1438 status = nvmet_get_feat_irq_coalesce(req); 1439 + break; 1440 + case NVME_FEAT_IRQ_CONFIG: 1441 + status = nvmet_get_feat_irq_config(req); 1490 1442 break; 1491 1443 case NVME_FEAT_ASYNC_EVENT: 1492 1444 nvmet_get_feat_async_event(req);
+5
drivers/nvme/target/nvmet.h
··· 916 916 u8 time; 917 917 }; 918 918 919 + struct nvmet_feat_irq_config { 920 + u16 iv; 921 + bool cd; 922 + }; 923 + 919 924 #endif /* _NVMET_H */