numam-spdk/lib/nvme
Alexey Marchuk d296fcd8d9 nvme_tcp: Fix icreq/icresp handing with zcopy enabled.
There is a problem with TCP zcopy enabled:
1. TCP initiator sends icreq and start polling a qpair. Polling of qpair
actively calls nvme_tcp_read_pdu function
2. nvme_tcp_read_pdu: qpair is in NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_CH state,
it reads 8 bytes of common PDU header. It determines the type of the PDU
and finds the size of PDU_PSH header.
3. nvme_tcp_read_pdu: qpair is in NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_PSH state.
It should read 120 bytes of icresp PDU. The number of bytes which needs to be
read is pdu->psh_len - pdu->psh_valid_bytes. qpair receives 120 bytes
(the full PDU) and calls nvme_tcp_pdu_psh_handle -> nvme_tcp_icresp_handle.
Here we check that we haven't yet received buffer reclaim notification and
simply return from this function. At the same time we continue to poll the qpair.
4. nvme_tcp_read_pdu: qpair is in NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_PSH state
and tries to read data from a socket again. The number of bytes is
pdu->psh_len - pdu->psh_valid_bytes. But now pdu->psh_len == pdu->psh_valid_bytes,
so we call nvme_tcp_read_data with zero length.
readv with zero length is commonly used to check errors on the socket,
but in our case there is no errors and readv returns 0.
5. nvme_tcp_read_data treats zero as error and return NVME_TCP_CONNECTION_FATAL.

Fix is to handle icresp, but leave qpair in INITIALIZING state until
we receive acknowledgement for icreqsend_ack. We also move qpair to
NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_READY recv_state so recv_pdu
will be zerofied and qpair will try to read a common PDU header.
But since it is not initialized yet, it won't receive anything
from the target.

Fixes issue #1633

Change-Id: I22cedefe530a8ac3b51495988ed6265d8fad15bb
Signed-off-by: Alexey Marchuk <alexeymar@mellanox.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4969
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
2020-10-30 09:05:35 +00:00
..
Makefile nvme: add getters for ZNS specific data structures 2020-09-30 07:26:04 +00:00
nvme_ctrlr_cmd.c nvme: add a csi parameter to nvme_ctrlr_cmd_identify() 2020-09-22 11:39:53 +00:00
nvme_ctrlr_ocssd_cmd.c ocssd: hold lock when calling nvme_ctrlr_submit_admin_request 2019-02-15 21:27:58 +00:00
nvme_ctrlr.c nvme: break completion loop when ctrlr is invalid 2020-10-29 08:11:35 +00:00
nvme_cuse.c nvme: fix signed/unsigned error with cuse ioctls 2020-10-19 10:00:29 +00:00
nvme_cuse.h lib/nvme: add RPC for interacting with CUSE devices 2019-10-24 23:43:59 +00:00
nvme_fabric.c log: simplify SPDK_LOG_REGISTER_COMPONENT 2020-10-14 08:00:35 +00:00
nvme_internal.h nvme: break completion loop when ctrlr is invalid 2020-10-29 08:11:35 +00:00
nvme_io_msg.c lib/nvme: update io msg producers on ns manage 2020-06-05 09:01:44 +00:00
nvme_io_msg.h lib/nvme: update io msg producers on ns manage 2020-06-05 09:01:44 +00:00
nvme_ns_cmd.c log: simplify SPDK_LOG_REGISTER_COMPONENT 2020-10-14 08:00:35 +00:00
nvme_ns_ocssd_cmd.c nvme: save separate metadata size to nvme request 2020-04-02 07:02:38 +00:00
nvme_ns.c log: simplify SPDK_LOG_REGISTER_COMPONENT 2020-10-14 08:00:35 +00:00
nvme_opal_internal.h nvme/opal: deprecate spdk_opal_supported() 2020-05-20 14:16:44 +00:00
nvme_opal.c log: remove internal log.h header 2020-10-15 08:23:39 +00:00
nvme_pcie.c lib/nvme: Hold ctrlr->ctrlr_lock before calling nvme_ctrlr_fail 2020-10-15 08:24:47 +00:00
nvme_poll_group.c lib/nvme: switch poll group to use connect/disconnect semantics. 2020-04-22 19:06:26 +00:00
nvme_qpair.c nvme: Don't log an error when we can't resubmit all requests 2020-10-26 11:48:46 +00:00
nvme_quirks.c log: simplify SPDK_LOG_REGISTER_COMPONENT 2020-10-14 08:00:35 +00:00
nvme_rdma.c nvme/nvme_rdma: Fix possible used uninitialized value. 2020-10-16 08:15:57 +00:00
nvme_tcp.c nvme_tcp: Fix icreq/icresp handing with zcopy enabled. 2020-10-30 09:05:35 +00:00
nvme_transport.c log: simplify SPDK_LOG_REGISTER_COMPONENT 2020-10-14 08:00:35 +00:00
nvme_uevent.c nvme: increase size of uevent buffer to 1MB 2020-09-08 07:49:32 +00:00
nvme_uevent.h nvme: read all uevents 2020-08-24 07:38:33 +00:00
nvme_zns.c nvme: add support for ZNS zone management receive command 2020-10-21 12:18:44 +00:00
nvme.c nvme: break completion loop when ctrlr is invalid 2020-10-29 08:11:35 +00:00
spdk_nvme.map nvme: add support for ZNS zone management receive command 2020-10-21 12:18:44 +00:00