@@ -397,7 +397,16 @@ void nvme_complete_rq(struct request *req)
397
397
trace_nvme_complete_rq (req );
398
398
nvme_cleanup_cmd (req );
399
399
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 )
401
410
ctrl -> comp_seen = true;
402
411
403
412
switch (nvme_decide_disposition (req )) {
@@ -1115,7 +1124,7 @@ u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode)
1115
1124
}
1116
1125
EXPORT_SYMBOL_NS_GPL (nvme_passthru_start , NVME_TARGET_PASSTHRU );
1117
1126
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 ,
1119
1128
struct nvme_command * cmd , int status )
1120
1129
{
1121
1130
if (effects & NVME_CMD_EFFECTS_CSE_MASK ) {
@@ -1132,6 +1141,8 @@ void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects,
1132
1141
nvme_queue_scan (ctrl );
1133
1142
flush_work (& ctrl -> scan_work );
1134
1143
}
1144
+ if (ns )
1145
+ return ;
1135
1146
1136
1147
switch (cmd -> common .opcode ) {
1137
1148
case nvme_admin_set_features :
@@ -1161,9 +1172,25 @@ EXPORT_SYMBOL_NS_GPL(nvme_passthru_end, NVME_TARGET_PASSTHRU);
1161
1172
* The host should send Keep Alive commands at half of the Keep Alive Timeout
1162
1173
* accounting for transport roundtrip times [..].
1163
1174
*/
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
+
1164
1190
static void nvme_queue_keep_alive_work (struct nvme_ctrl * ctrl )
1165
1191
{
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 ));
1167
1194
}
1168
1195
1169
1196
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,
1172
1199
struct nvme_ctrl * ctrl = rq -> end_io_data ;
1173
1200
unsigned long flags ;
1174
1201
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
+ }
1175
1216
1176
1217
blk_mq_free_request (rq );
1177
1218
@@ -1182,14 +1223,15 @@ static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq,
1182
1223
return RQ_END_IO_NONE ;
1183
1224
}
1184
1225
1226
+ ctrl -> ka_last_check_time = jiffies ;
1185
1227
ctrl -> comp_seen = false;
1186
1228
spin_lock_irqsave (& ctrl -> lock , flags );
1187
1229
if (ctrl -> state == NVME_CTRL_LIVE ||
1188
1230
ctrl -> state == NVME_CTRL_CONNECTING )
1189
1231
startka = true;
1190
1232
spin_unlock_irqrestore (& ctrl -> lock , flags );
1191
1233
if (startka )
1192
- nvme_queue_keep_alive_work ( ctrl );
1234
+ queue_delayed_work ( nvme_wq , & ctrl -> ka_work , delay );
1193
1235
return RQ_END_IO_NONE ;
1194
1236
}
1195
1237
@@ -1200,6 +1242,8 @@ static void nvme_keep_alive_work(struct work_struct *work)
1200
1242
bool comp_seen = ctrl -> comp_seen ;
1201
1243
struct request * rq ;
1202
1244
1245
+ ctrl -> ka_last_check_time = jiffies ;
1246
+
1203
1247
if ((ctrl -> ctratt & NVME_CTRL_ATTR_TBKAS ) && comp_seen ) {
1204
1248
dev_dbg (ctrl -> device ,
1205
1249
"reschedule traffic based keep-alive timer\n" );
0 commit comments