Skip to content

Commit df21b6b

Browse files
lsgunthChristoph Hellwig
authored andcommitted
nvme: create helper function to obtain command effects
Separate the code to obtain command effects from the code to start a passthru request and move the nvme_passthru_start() and nvme_passthru_end() functions up above nvme_submit_user_cmd() in order that they may be used in a new helper a subsequent patch. The new helper function will be necessary for nvmet passthru code to determine if we need to change out of interrupt context to handle the effects. It is exported in the NVME_TARGET_PASSTHRU namespace. Signed-off-by: Logan Gunthorpe <[email protected]> Reviewed-by: Keith Busch <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]>
1 parent 2bf5d3b commit df21b6b

File tree

2 files changed

+103
-92
lines changed

2 files changed

+103
-92
lines changed

drivers/nvme/host/core.c

Lines changed: 100 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,106 @@ static void *nvme_add_user_metadata(struct bio *bio, void __user *ubuf,
928928
return ERR_PTR(ret);
929929
}
930930

931+
static u32 nvme_known_admin_effects(u8 opcode)
932+
{
933+
switch (opcode) {
934+
case nvme_admin_format_nvm:
935+
return NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC |
936+
NVME_CMD_EFFECTS_CSE_MASK;
937+
case nvme_admin_sanitize_nvm:
938+
return NVME_CMD_EFFECTS_CSE_MASK;
939+
default:
940+
break;
941+
}
942+
return 0;
943+
}
944+
945+
u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode)
946+
{
947+
u32 effects = 0;
948+
949+
if (ns) {
950+
if (ns->head->effects)
951+
effects = le32_to_cpu(ns->head->effects->iocs[opcode]);
952+
if (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC))
953+
dev_warn(ctrl->device,
954+
"IO command:%02x has unhandled effects:%08x\n",
955+
opcode, effects);
956+
return 0;
957+
}
958+
959+
if (ctrl->effects)
960+
effects = le32_to_cpu(ctrl->effects->acs[opcode]);
961+
effects |= nvme_known_admin_effects(opcode);
962+
963+
return effects;
964+
}
965+
EXPORT_SYMBOL_NS_GPL(nvme_command_effects, NVME_TARGET_PASSTHRU);
966+
967+
static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
968+
u8 opcode)
969+
{
970+
u32 effects = nvme_command_effects(ctrl, ns, opcode);
971+
972+
/*
973+
* For simplicity, IO to all namespaces is quiesced even if the command
974+
* effects say only one namespace is affected.
975+
*/
976+
if (effects & (NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_CSE_MASK)) {
977+
mutex_lock(&ctrl->scan_lock);
978+
mutex_lock(&ctrl->subsys->lock);
979+
nvme_mpath_start_freeze(ctrl->subsys);
980+
nvme_mpath_wait_freeze(ctrl->subsys);
981+
nvme_start_freeze(ctrl);
982+
nvme_wait_freeze(ctrl);
983+
}
984+
return effects;
985+
}
986+
987+
static void nvme_update_formats(struct nvme_ctrl *ctrl, u32 *effects)
988+
{
989+
struct nvme_ns *ns;
990+
991+
down_read(&ctrl->namespaces_rwsem);
992+
list_for_each_entry(ns, &ctrl->namespaces, list)
993+
if (_nvme_revalidate_disk(ns->disk))
994+
nvme_set_queue_dying(ns);
995+
else if (blk_queue_is_zoned(ns->disk->queue)) {
996+
/*
997+
* IO commands are required to fully revalidate a zoned
998+
* device. Force the command effects to trigger rescan
999+
* work so report zones can run in a context with
1000+
* unfrozen IO queues.
1001+
*/
1002+
*effects |= NVME_CMD_EFFECTS_NCC;
1003+
}
1004+
up_read(&ctrl->namespaces_rwsem);
1005+
}
1006+
1007+
static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects)
1008+
{
1009+
/*
1010+
* Revalidate LBA changes prior to unfreezing. This is necessary to
1011+
* prevent memory corruption if a logical block size was changed by
1012+
* this command.
1013+
*/
1014+
if (effects & NVME_CMD_EFFECTS_LBCC)
1015+
nvme_update_formats(ctrl, &effects);
1016+
if (effects & (NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_CSE_MASK)) {
1017+
nvme_unfreeze(ctrl);
1018+
nvme_mpath_unfreeze(ctrl->subsys);
1019+
mutex_unlock(&ctrl->subsys->lock);
1020+
nvme_remove_invalid_namespaces(ctrl, NVME_NSID_ALL);
1021+
mutex_unlock(&ctrl->scan_lock);
1022+
}
1023+
if (effects & NVME_CMD_EFFECTS_CCC)
1024+
nvme_init_identify(ctrl);
1025+
if (effects & (NVME_CMD_EFFECTS_NIC | NVME_CMD_EFFECTS_NCC)) {
1026+
nvme_queue_scan(ctrl);
1027+
flush_work(&ctrl->scan_work);
1028+
}
1029+
}
1030+
9311031
static int nvme_submit_user_cmd(struct request_queue *q,
9321032
struct nvme_command *cmd, void __user *ubuffer,
9331033
unsigned bufflen, void __user *meta_buffer, unsigned meta_len,
@@ -1394,98 +1494,6 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
13941494
metadata, meta_len, lower_32_bits(io.slba), NULL, 0);
13951495
}
13961496

1397-
static u32 nvme_known_admin_effects(u8 opcode)
1398-
{
1399-
switch (opcode) {
1400-
case nvme_admin_format_nvm:
1401-
return NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC |
1402-
NVME_CMD_EFFECTS_CSE_MASK;
1403-
case nvme_admin_sanitize_nvm:
1404-
return NVME_CMD_EFFECTS_CSE_MASK;
1405-
default:
1406-
break;
1407-
}
1408-
return 0;
1409-
}
1410-
1411-
static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
1412-
u8 opcode)
1413-
{
1414-
u32 effects = 0;
1415-
1416-
if (ns) {
1417-
if (ns->head->effects)
1418-
effects = le32_to_cpu(ns->head->effects->iocs[opcode]);
1419-
if (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC))
1420-
dev_warn(ctrl->device,
1421-
"IO command:%02x has unhandled effects:%08x\n",
1422-
opcode, effects);
1423-
return 0;
1424-
}
1425-
1426-
if (ctrl->effects)
1427-
effects = le32_to_cpu(ctrl->effects->acs[opcode]);
1428-
effects |= nvme_known_admin_effects(opcode);
1429-
1430-
/*
1431-
* For simplicity, IO to all namespaces is quiesced even if the command
1432-
* effects say only one namespace is affected.
1433-
*/
1434-
if (effects & (NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_CSE_MASK)) {
1435-
mutex_lock(&ctrl->scan_lock);
1436-
mutex_lock(&ctrl->subsys->lock);
1437-
nvme_mpath_start_freeze(ctrl->subsys);
1438-
nvme_mpath_wait_freeze(ctrl->subsys);
1439-
nvme_start_freeze(ctrl);
1440-
nvme_wait_freeze(ctrl);
1441-
}
1442-
return effects;
1443-
}
1444-
1445-
static void nvme_update_formats(struct nvme_ctrl *ctrl, u32 *effects)
1446-
{
1447-
struct nvme_ns *ns;
1448-
1449-
down_read(&ctrl->namespaces_rwsem);
1450-
list_for_each_entry(ns, &ctrl->namespaces, list)
1451-
if (_nvme_revalidate_disk(ns->disk))
1452-
nvme_set_queue_dying(ns);
1453-
else if (blk_queue_is_zoned(ns->disk->queue)) {
1454-
/*
1455-
* IO commands are required to fully revalidate a zoned
1456-
* device. Force the command effects to trigger rescan
1457-
* work so report zones can run in a context with
1458-
* unfrozen IO queues.
1459-
*/
1460-
*effects |= NVME_CMD_EFFECTS_NCC;
1461-
}
1462-
up_read(&ctrl->namespaces_rwsem);
1463-
}
1464-
1465-
static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects)
1466-
{
1467-
/*
1468-
* Revalidate LBA changes prior to unfreezing. This is necessary to
1469-
* prevent memory corruption if a logical block size was changed by
1470-
* this command.
1471-
*/
1472-
if (effects & NVME_CMD_EFFECTS_LBCC)
1473-
nvme_update_formats(ctrl, &effects);
1474-
if (effects & (NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_CSE_MASK)) {
1475-
nvme_unfreeze(ctrl);
1476-
nvme_mpath_unfreeze(ctrl->subsys);
1477-
mutex_unlock(&ctrl->subsys->lock);
1478-
nvme_remove_invalid_namespaces(ctrl, NVME_NSID_ALL);
1479-
mutex_unlock(&ctrl->scan_lock);
1480-
}
1481-
if (effects & NVME_CMD_EFFECTS_CCC)
1482-
nvme_init_identify(ctrl);
1483-
if (effects & (NVME_CMD_EFFECTS_NIC | NVME_CMD_EFFECTS_NCC)) {
1484-
nvme_queue_scan(ctrl);
1485-
flush_work(&ctrl->scan_work);
1486-
}
1487-
}
1488-
14891497
static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
14901498
struct nvme_passthru_cmd __user *ucmd)
14911499
{

drivers/nvme/host/nvme.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,4 +790,7 @@ void nvme_hwmon_init(struct nvme_ctrl *ctrl);
790790
static inline void nvme_hwmon_init(struct nvme_ctrl *ctrl) { }
791791
#endif
792792

793+
u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
794+
u8 opcode);
795+
793796
#endif /* _NVME_H */

0 commit comments

Comments
 (0)