From 5a7b33ec67ca7a0f2fe3fdd840e00560246c0584 Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Thu, 9 Jan 2020 12:40:07 -0700 Subject: [PATCH] nvmf/tcp: In _pdu_write_done, free pdu before calling user callback By releasing the just-completed PDU prior to calling the callback, for flows that immediately submit another PDU inside the callback, the just-released PDU can be immediately reused. This reduces the number of PDUs required in the pool to continue forward progress to half of the previous value, while also making it more CPU cache friendly. Change-Id: I8031b8f9f57ac05f261d96433d9899fe5e31d318 Signed-off-by: Ben Walker Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/479904 Community-CI: SPDK CI Jenkins Tested-by: SPDK CI Jenkins Reviewed-by: Alexey Marchuk Reviewed-by: Jim Harris Reviewed-by: Ziye Yang Reviewed-by: Or Gerlitz Reviewed-by: Shuhei Matsumoto --- lib/nvmf/tcp.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/nvmf/tcp.c b/lib/nvmf/tcp.c index 9e60852d1..d6750cf08 100644 --- a/lib/nvmf/tcp.c +++ b/lib/nvmf/tcp.c @@ -764,10 +764,12 @@ spdk_nvmf_tcp_qpair_disconnect(struct spdk_nvmf_tcp_qpair *tqpair) } static void -_pdu_write_done(void *cb_arg, int err) +_pdu_write_done(void *_pdu, int err) { - struct nvme_tcp_pdu *pdu = cb_arg; - struct spdk_nvmf_tcp_qpair *tqpair = pdu->qpair; + struct nvme_tcp_pdu *pdu = _pdu; + struct spdk_nvmf_tcp_qpair *tqpair = pdu->qpair; + nvme_tcp_qpair_xfer_complete_cb cb_fn; + void *cb_arg; TAILQ_REMOVE(&tqpair->send_queue, pdu, tailq); @@ -783,9 +785,15 @@ _pdu_write_done(void *cb_arg, int err) } assert(pdu->cb_fn != NULL); - pdu->cb_fn(pdu->cb_arg); + + /* Capture the callback and argument so we can free the PDU + * prior to calling the callback. */ + cb_fn = pdu->cb_fn; + cb_arg = pdu->cb_arg; spdk_nvmf_tcp_pdu_put(tqpair, pdu); + + cb_fn(cb_arg); } static void