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 arbitration feature support

NVMe base specification v2.1 mandates support for the arbitration
feature (NVME_FEAT_ARBITRATION). Introduce the data structure
struct nvmet_feat_arbitration to define the high, medium and low
priority weight fields and the arbitration burst field of this feature
and implement the functions nvmet_get_feat_arbitration() and
nvmet_set_feat_arbitration() functions to get and set these fields.

Since there is no generic way to implement support for the arbitration
feature, these functions respectively use the controller get_feature()
and set_feature() operations to process the feature with the help of
the controller driver. If the controller driver does not implement these
operations and a get feature command or a set feature command for this
feature is received, 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
a0ed77d4 f1ecd491

+56 -2
+49 -2
drivers/nvme/target/admin-cmd.c
··· 1324 1324 return ctrl->ops->set_feature(ctrl, NVME_FEAT_IRQ_CONFIG, &irqcfg); 1325 1325 } 1326 1326 1327 + static u16 nvmet_set_feat_arbitration(struct nvmet_req *req) 1328 + { 1329 + struct nvmet_ctrl *ctrl = req->sq->ctrl; 1330 + u32 cdw11 = le32_to_cpu(req->cmd->common.cdw11); 1331 + struct nvmet_feat_arbitration arb = { 1332 + .hpw = (cdw11 >> 24) & 0xff, 1333 + .mpw = (cdw11 >> 16) & 0xff, 1334 + .lpw = (cdw11 >> 8) & 0xff, 1335 + .ab = cdw11 & 0x3, 1336 + }; 1337 + 1338 + if (!ctrl->ops->set_feature) { 1339 + req->error_loc = offsetof(struct nvme_common_command, cdw10); 1340 + return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; 1341 + } 1342 + 1343 + return ctrl->ops->set_feature(ctrl, NVME_FEAT_ARBITRATION, &arb); 1344 + } 1345 + 1327 1346 void nvmet_execute_set_features(struct nvmet_req *req) 1328 1347 { 1329 1348 struct nvmet_subsys *subsys = nvmet_req_subsys(req); ··· 1356 1337 return; 1357 1338 1358 1339 switch (cdw10 & 0xff) { 1340 + case NVME_FEAT_ARBITRATION: 1341 + status = nvmet_set_feat_arbitration(req); 1342 + break; 1359 1343 case NVME_FEAT_NUM_QUEUES: 1360 1344 ncqr = (cdw11 >> 16) & 0xffff; 1361 1345 nsqr = cdw11 & 0xffff; ··· 1468 1446 return NVME_SC_SUCCESS; 1469 1447 } 1470 1448 1449 + static u16 nvmet_get_feat_arbitration(struct nvmet_req *req) 1450 + { 1451 + struct nvmet_ctrl *ctrl = req->sq->ctrl; 1452 + struct nvmet_feat_arbitration arb = { }; 1453 + u16 status; 1454 + 1455 + if (!ctrl->ops->get_feature) { 1456 + req->error_loc = offsetof(struct nvme_common_command, cdw10); 1457 + return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; 1458 + } 1459 + 1460 + status = ctrl->ops->get_feature(ctrl, NVME_FEAT_ARBITRATION, &arb); 1461 + if (status != NVME_SC_SUCCESS) 1462 + return status; 1463 + 1464 + nvmet_set_result(req, 1465 + ((u32)arb.hpw << 24) | 1466 + ((u32)arb.mpw << 16) | 1467 + ((u32)arb.lpw << 8) | 1468 + (arb.ab & 0x3)); 1469 + 1470 + return NVME_SC_SUCCESS; 1471 + } 1472 + 1471 1473 void nvmet_get_feat_kato(struct nvmet_req *req) 1472 1474 { 1473 1475 nvmet_set_result(req, req->sq->ctrl->kato * 1000); ··· 1518 1472 * need to come up with some fake values for these. 1519 1473 */ 1520 1474 #if 0 1521 - case NVME_FEAT_ARBITRATION: 1522 - break; 1523 1475 case NVME_FEAT_POWER_MGMT: 1524 1476 break; 1525 1477 case NVME_FEAT_TEMP_THRESH: ··· 1527 1483 case NVME_FEAT_WRITE_ATOMIC: 1528 1484 break; 1529 1485 #endif 1486 + case NVME_FEAT_ARBITRATION: 1487 + status = nvmet_get_feat_arbitration(req); 1488 + break; 1530 1489 case NVME_FEAT_IRQ_COALESCE: 1531 1490 status = nvmet_get_feat_irq_coalesce(req); 1532 1491 break;
+7
drivers/nvme/target/nvmet.h
··· 921 921 bool cd; 922 922 }; 923 923 924 + struct nvmet_feat_arbitration { 925 + u8 hpw; 926 + u8 mpw; 927 + u8 lpw; 928 + u8 ab; 929 + }; 930 + 924 931 #endif /* _NVMET_H */