From 855390a58514c5a59647bba9e0d274ce5a28b5e2 Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Wed, 13 Apr 2022 09:24:12 -0700 Subject: [PATCH] idxd: Release batches based on refcnt Instead of releasing the batch memory when the batch generates a completion, instead do it via refcnt. This will allow us to later hold onto batch memory longer if vectored transactions end up spanning a batch. Change-Id: I942d6aa5052029eb0951e51a046dd98943108b94 Signed-off-by: Ben Walker Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12259 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Reviewed-by: Shuhei Matsumoto Reviewed-by: Jim Harris Reviewed-by: Aleksey Marchuk Reviewed-by: Paul Luse Tested-by: SPDK CI Jenkins --- lib/idxd/idxd.c | 19 +++++++++++++------ lib/idxd/idxd.h | 1 + 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/idxd/idxd.c b/lib/idxd/idxd.c index 011320487..13b3e8d0a 100644 --- a/lib/idxd/idxd.c +++ b/lib/idxd/idxd.c @@ -413,6 +413,7 @@ static void _free_batch(struct idxd_batch *batch, struct spdk_idxd_io_channel *chan) { SPDK_DEBUGLOG(idxd, "Free batch %p\n", batch); + assert(batch->refcnt == 0); batch->index = 0; batch->chan = NULL; TAILQ_INSERT_TAIL(&chan->batch_pool, batch, link); @@ -489,11 +490,11 @@ idxd_batch_submit(struct spdk_idxd_io_channel *chan, desc->opcode = IDXD_OPCODE_BATCH; desc->desc_list_addr = batch->user_desc_addr; desc->desc_count = batch->index; - op->batch = batch; assert(batch->index <= DESC_PER_BATCH); /* Add the batch elements completion contexts to the outstanding list to be polled. */ for (i = 0 ; i < batch->index; i++) { + batch->refcnt++; STAILQ_INSERT_TAIL(&chan->ops_outstanding, (struct idxd_ops *)&batch->user_ops[i], link); } @@ -1302,13 +1303,19 @@ spdk_idxd_process_events(struct spdk_idxd_io_channel *chan) break; } + op->hw.status = 0; + cb_fn = op->cb_fn; cb_arg = op->cb_arg; - op->hw.status = 0; - if (op->desc->opcode == IDXD_OPCODE_BATCH) { - _free_batch(op->batch, chan); - STAILQ_INSERT_HEAD(&chan->ops_pool, op, link); - } else if (!op->batch) { + + if (op->batch != NULL) { + assert(op->batch->refcnt > 0); + op->batch->refcnt--; + + if (op->batch->refcnt == 0) { + _free_batch(op->batch, chan); + } + } else { STAILQ_INSERT_HEAD(&chan->ops_pool, op, link); } diff --git a/lib/idxd/idxd.h b/lib/idxd/idxd.h index b67835c58..675c62ac5 100644 --- a/lib/idxd/idxd.h +++ b/lib/idxd/idxd.h @@ -77,6 +77,7 @@ struct idxd_batch { struct idxd_ops *user_ops; uint64_t user_desc_addr; uint8_t index; + uint8_t refcnt; struct spdk_idxd_io_channel *chan; TAILQ_ENTRY(idxd_batch) link; };