nvmf/tcp: Implement correct behavior of timeout for C2Htermreq case
From TP8000 spec 7.4.7, "In response to a C2HTermReq PDU, the host shall terminate the connection. If the host does not terminate the connection in an implementation specific period that does not exceed 30 seconds, the controller may terminate the connection on its own". It means that the timeout is designed for: when the target is sending out C2hTermReq, if the host does not terminate the connection, the target should terminate the connection. PS: For detecting the malicous connection without sending response (such as no response of R2T PDU) which should be another patch. Change-Id: I586dbb235d99aeab5d748a19b9128cd8b0cef183 Signed-off-by: Ziye Yang <optimistyzy@gmail.com> Reviewed-on: https://review.gerrithub.io/c/440831 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
dadb948585
commit
2d0ce5b48b
@ -260,7 +260,12 @@ struct spdk_nvmf_tcp_qpair {
|
||||
uint16_t initiator_port;
|
||||
uint16_t target_port;
|
||||
|
||||
TAILQ_ENTRY(spdk_nvmf_tcp_qpair) link;
|
||||
/* Timer used to destroy qpair after detecting transport error issue if initiator does
|
||||
* not close the connection.
|
||||
*/
|
||||
struct spdk_poller *timeout_poller;
|
||||
|
||||
TAILQ_ENTRY(spdk_nvmf_tcp_qpair) link;
|
||||
};
|
||||
|
||||
struct spdk_nvmf_tcp_poll_group {
|
||||
@ -1245,9 +1250,32 @@ spdk_nvmf_tcp_qpair_set_recv_state(struct spdk_nvmf_tcp_qpair *tqpair,
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
spdk_nvmf_tcp_qpair_handle_timeout(void *ctx)
|
||||
{
|
||||
struct spdk_nvmf_tcp_qpair *tqpair = ctx;
|
||||
|
||||
assert(tqpair->recv_state == NVME_TCP_PDU_RECV_STATE_ERROR);
|
||||
|
||||
SPDK_ERRLOG("No pdu coming for tqpair=%p within %d seconds\n", tqpair,
|
||||
SPDK_NVME_TCP_QPAIR_EXIT_TIMEOUT);
|
||||
tqpair->state = NVME_TCP_QPAIR_STATE_EXITED;
|
||||
SPDK_DEBUGLOG(SPDK_LOG_NVMF_TCP, "will disconect the tqpair=%p\n", tqpair);
|
||||
spdk_poller_unregister(&tqpair->timeout_poller);
|
||||
spdk_nvmf_qpair_disconnect(&tqpair->qpair, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
spdk_nvmf_tcp_send_c2h_term_req_complete(void *cb_arg)
|
||||
{
|
||||
struct spdk_nvmf_tcp_qpair *tqpair = (struct spdk_nvmf_tcp_qpair *)cb_arg;
|
||||
|
||||
if (!tqpair->timeout_poller) {
|
||||
tqpair->timeout_poller = spdk_poller_register(spdk_nvmf_tcp_qpair_handle_timeout, tqpair,
|
||||
SPDK_NVME_TCP_QPAIR_EXIT_TIMEOUT * 1000000);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2591,6 +2619,7 @@ spdk_nvmf_tcp_sock_cb(void *arg, struct spdk_sock_group *group, struct spdk_sock
|
||||
tqpair->state = NVME_TCP_QPAIR_STATE_EXITED;
|
||||
spdk_nvmf_tcp_qpair_flush_pdus(tqpair);
|
||||
SPDK_DEBUGLOG(SPDK_LOG_NVMF_TCP, "will disconect the tqpair=%p\n", tqpair);
|
||||
spdk_poller_unregister(&tqpair->timeout_poller);
|
||||
spdk_nvmf_qpair_disconnect(&tqpair->qpair, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user