Skip to content

Commit 2e45a49

Browse files
committed
Merge tag 'nvme-6.4-2023-06-01' of git://git.infradead.org/nvme into block-6.4
Pull NVMe fixes from Keith: "nvme fixes for Linux 6.4 - Fixes for spurious Keep Alive timeouts (Uday) - Fix for command type check on passthrough actions (Min) - Fix for nvme command name for error logging (Christoph)" * tag 'nvme-6.4-2023-06-01' of git://git.infradead.org/nvme: nvme: fix the name of Zone Append for verbose logging nvme: improve handling of long keep alives nvme: check IO start time when deciding to defer KA nvme: double KA polling frequency to avoid KATO with TBKAS on nvme: fix miss command type check
2 parents 47fe1c3 + 8563037 commit 2e45a49

File tree

5 files changed

+53
-8
lines changed

5 files changed

+53
-8
lines changed

drivers/nvme/host/constants.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ static const char * const nvme_ops[] = {
2121
[nvme_cmd_resv_release] = "Reservation Release",
2222
[nvme_cmd_zone_mgmt_send] = "Zone Management Send",
2323
[nvme_cmd_zone_mgmt_recv] = "Zone Management Receive",
24-
[nvme_cmd_zone_append] = "Zone Management Append",
24+
[nvme_cmd_zone_append] = "Zone Append",
2525
};
2626

2727
static const char * const nvme_admin_ops[] = {

drivers/nvme/host/core.c

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,16 @@ void nvme_complete_rq(struct request *req)
397397
trace_nvme_complete_rq(req);
398398
nvme_cleanup_cmd(req);
399399

400-
if (ctrl->kas)
400+
/*
401+
* Completions of long-running commands should not be able to
402+
* defer sending of periodic keep alives, since the controller
403+
* may have completed processing such commands a long time ago
404+
* (arbitrarily close to command submission time).
405+
* req->deadline - req->timeout is the command submission time
406+
* in jiffies.
407+
*/
408+
if (ctrl->kas &&
409+
req->deadline - req->timeout >= ctrl->ka_last_check_time)
401410
ctrl->comp_seen = true;
402411

403412
switch (nvme_decide_disposition(req)) {
@@ -1115,7 +1124,7 @@ u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode)
11151124
}
11161125
EXPORT_SYMBOL_NS_GPL(nvme_passthru_start, NVME_TARGET_PASSTHRU);
11171126

1118-
void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects,
1127+
void nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects,
11191128
struct nvme_command *cmd, int status)
11201129
{
11211130
if (effects & NVME_CMD_EFFECTS_CSE_MASK) {
@@ -1132,6 +1141,8 @@ void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects,
11321141
nvme_queue_scan(ctrl);
11331142
flush_work(&ctrl->scan_work);
11341143
}
1144+
if (ns)
1145+
return;
11351146

11361147
switch (cmd->common.opcode) {
11371148
case nvme_admin_set_features:
@@ -1161,9 +1172,25 @@ EXPORT_SYMBOL_NS_GPL(nvme_passthru_end, NVME_TARGET_PASSTHRU);
11611172
* The host should send Keep Alive commands at half of the Keep Alive Timeout
11621173
* accounting for transport roundtrip times [..].
11631174
*/
1175+
static unsigned long nvme_keep_alive_work_period(struct nvme_ctrl *ctrl)
1176+
{
1177+
unsigned long delay = ctrl->kato * HZ / 2;
1178+
1179+
/*
1180+
* When using Traffic Based Keep Alive, we need to run
1181+
* nvme_keep_alive_work at twice the normal frequency, as one
1182+
* command completion can postpone sending a keep alive command
1183+
* by up to twice the delay between runs.
1184+
*/
1185+
if (ctrl->ctratt & NVME_CTRL_ATTR_TBKAS)
1186+
delay /= 2;
1187+
return delay;
1188+
}
1189+
11641190
static void nvme_queue_keep_alive_work(struct nvme_ctrl *ctrl)
11651191
{
1166-
queue_delayed_work(nvme_wq, &ctrl->ka_work, ctrl->kato * HZ / 2);
1192+
queue_delayed_work(nvme_wq, &ctrl->ka_work,
1193+
nvme_keep_alive_work_period(ctrl));
11671194
}
11681195

11691196
static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq,
@@ -1172,6 +1199,20 @@ static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq,
11721199
struct nvme_ctrl *ctrl = rq->end_io_data;
11731200
unsigned long flags;
11741201
bool startka = false;
1202+
unsigned long rtt = jiffies - (rq->deadline - rq->timeout);
1203+
unsigned long delay = nvme_keep_alive_work_period(ctrl);
1204+
1205+
/*
1206+
* Subtract off the keepalive RTT so nvme_keep_alive_work runs
1207+
* at the desired frequency.
1208+
*/
1209+
if (rtt <= delay) {
1210+
delay -= rtt;
1211+
} else {
1212+
dev_warn(ctrl->device, "long keepalive RTT (%u ms)\n",
1213+
jiffies_to_msecs(rtt));
1214+
delay = 0;
1215+
}
11751216

11761217
blk_mq_free_request(rq);
11771218

@@ -1182,14 +1223,15 @@ static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq,
11821223
return RQ_END_IO_NONE;
11831224
}
11841225

1226+
ctrl->ka_last_check_time = jiffies;
11851227
ctrl->comp_seen = false;
11861228
spin_lock_irqsave(&ctrl->lock, flags);
11871229
if (ctrl->state == NVME_CTRL_LIVE ||
11881230
ctrl->state == NVME_CTRL_CONNECTING)
11891231
startka = true;
11901232
spin_unlock_irqrestore(&ctrl->lock, flags);
11911233
if (startka)
1192-
nvme_queue_keep_alive_work(ctrl);
1234+
queue_delayed_work(nvme_wq, &ctrl->ka_work, delay);
11931235
return RQ_END_IO_NONE;
11941236
}
11951237

@@ -1200,6 +1242,8 @@ static void nvme_keep_alive_work(struct work_struct *work)
12001242
bool comp_seen = ctrl->comp_seen;
12011243
struct request *rq;
12021244

1245+
ctrl->ka_last_check_time = jiffies;
1246+
12031247
if ((ctrl->ctratt & NVME_CTRL_ATTR_TBKAS) && comp_seen) {
12041248
dev_dbg(ctrl->device,
12051249
"reschedule traffic based keep-alive timer\n");

drivers/nvme/host/ioctl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ static int nvme_submit_user_cmd(struct request_queue *q,
254254
blk_mq_free_request(req);
255255

256256
if (effects)
257-
nvme_passthru_end(ctrl, effects, cmd, ret);
257+
nvme_passthru_end(ctrl, ns, effects, cmd, ret);
258258

259259
return ret;
260260
}

drivers/nvme/host/nvme.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ struct nvme_ctrl {
328328
struct delayed_work ka_work;
329329
struct delayed_work failfast_work;
330330
struct nvme_command ka_cmd;
331+
unsigned long ka_last_check_time;
331332
struct work_struct fw_act_work;
332333
unsigned long events;
333334

@@ -1077,7 +1078,7 @@ u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
10771078
u8 opcode);
10781079
u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode);
10791080
int nvme_execute_rq(struct request *rq, bool at_head);
1080-
void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects,
1081+
void nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects,
10811082
struct nvme_command *cmd, int status);
10821083
struct nvme_ctrl *nvme_ctrl_from_file(struct file *file);
10831084
struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid);

drivers/nvme/target/passthru.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ static void nvmet_passthru_execute_cmd_work(struct work_struct *w)
243243
blk_mq_free_request(rq);
244244

245245
if (effects)
246-
nvme_passthru_end(ctrl, effects, req->cmd, status);
246+
nvme_passthru_end(ctrl, ns, effects, req->cmd, status);
247247
}
248248

249249
static enum rq_end_io_ret nvmet_passthru_req_done(struct request *rq,

0 commit comments

Comments
 (0)