From: Andrew Boyer <andrew.boyer@amd.com>
To: <dev@dpdk.org>
Cc: Andrew Boyer <andrew.boyer@amd.com>
Subject: [PATCH v2 8/9] crypto/ionic: add a watchdog operation
Date: Tue, 30 Apr 2024 13:21:43 -0700 [thread overview]
Message-ID: <20240430202144.49899-9-andrew.boyer@amd.com> (raw)
In-Reply-To: <20240430202144.49899-1-andrew.boyer@amd.com>
If no progress has been made within the timeout, post a dummy operation
using session 0. This will restart the queue in the rare case that a
doorbell is lost inside the device.
Signed-off-by: Andrew Boyer <andrew.boyer@amd.com>
---
drivers/crypto/ionic/ionic_crypto.h | 16 ++++
drivers/crypto/ionic/ionic_crypto_main.c | 31 ++++++++
drivers/crypto/ionic/ionic_crypto_ops.c | 97 +++++++++++++++++++++++-
3 files changed, 142 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/ionic/ionic_crypto.h b/drivers/crypto/ionic/ionic_crypto.h
index e05b458926..69c17887fb 100644
--- a/drivers/crypto/ionic/ionic_crypto.h
+++ b/drivers/crypto/ionic/ionic_crypto.h
@@ -89,6 +89,14 @@ struct iocpt_dev_bars {
uint32_t num_bars;
};
+/* Queue watchdog */
+#define IOCPT_Q_WDOG_SESS_IDX 0
+#define IOCPT_Q_WDOG_KEY_LEN 16
+#define IOCPT_Q_WDOG_IV_LEN 12
+#define IOCPT_Q_WDOG_PLD_LEN 4
+#define IOCPT_Q_WDOG_TAG_LEN 16
+#define IOCPT_Q_WDOG_OP_TYPE RTE_CRYPTO_OP_TYPE_UNDEFINED
+
struct iocpt_qtype_info {
uint8_t version;
uint8_t supported;
@@ -162,7 +170,15 @@ struct iocpt_crypto_q {
IOCPT_COMMON_FIELDS;
/* cacheline2 */
+ uint64_t last_wdog_cycles;
uint16_t flags;
+
+ /* cacheline3 */
+ uint64_t enqueued_wdogs;
+ uint64_t dequeued_wdogs;
+ uint8_t wdog_iv[IOCPT_Q_WDOG_IV_LEN];
+ uint8_t wdog_pld[IOCPT_Q_WDOG_PLD_LEN];
+ uint8_t wdog_tag[IOCPT_Q_WDOG_TAG_LEN];
};
#define IOCPT_S_F_INITED BIT(0)
diff --git a/drivers/crypto/ionic/ionic_crypto_main.c b/drivers/crypto/ionic/ionic_crypto_main.c
index 7693377831..113347c57a 100644
--- a/drivers/crypto/ionic/ionic_crypto_main.c
+++ b/drivers/crypto/ionic/ionic_crypto_main.c
@@ -172,6 +172,22 @@ iocpt_session_write(struct iocpt_session_priv *priv,
return 0;
}
+static int
+iocpt_session_wdog(struct iocpt_dev *dev)
+{
+ struct iocpt_session_priv priv = {
+ .dev = dev,
+ .index = IOCPT_Q_WDOG_SESS_IDX,
+ .type = IOCPT_SESS_AEAD_AES_GCM,
+ .key_len = IOCPT_Q_WDOG_KEY_LEN,
+ };
+
+ /* Reserve session 0 for queue watchdog */
+ rte_bitmap_clear(dev->sess_bm, IOCPT_Q_WDOG_SESS_IDX);
+
+ return iocpt_session_write(&priv, IOCPT_SESS_INIT);
+}
+
int
iocpt_session_init(struct iocpt_session_priv *priv)
{
@@ -491,6 +507,9 @@ iocpt_cryptoq_deinit(struct iocpt_crypto_q *cptq)
IOCPT_PRINT(DEBUG, "Deinit queue %u returned %d after %u ms",
cptq->q.index, err, sleep_cnt * 100);
+ IOCPT_PRINT(DEBUG, "Queue %u watchdog: enq %"PRIu64" deq %"PRIu64,
+ cptq->q.index, cptq->enqueued_wdogs, cptq->dequeued_wdogs);
+
cptq->flags &= ~IOCPT_Q_F_INITED;
}
@@ -659,9 +678,21 @@ iocpt_init(struct iocpt_dev *dev)
if (err != 0)
return err;
+ /* Write the queue watchdog key */
+ err = iocpt_session_wdog(dev);
+ if (err != 0) {
+ IOCPT_PRINT(ERR, "Cannot setup watchdog session");
+ goto err_out_adminq_deinit;
+ }
+
dev->state |= IOCPT_DEV_F_INITED;
return 0;
+
+err_out_adminq_deinit:
+ iocpt_adminq_deinit(dev);
+
+ return err;
}
void
diff --git a/drivers/crypto/ionic/ionic_crypto_ops.c b/drivers/crypto/ionic/ionic_crypto_ops.c
index 28b099dea2..0330fd76ad 100644
--- a/drivers/crypto/ionic/ionic_crypto_ops.c
+++ b/drivers/crypto/ionic/ionic_crypto_ops.c
@@ -58,7 +58,8 @@ iocpt_op_info_get(struct rte_cryptodev *cdev, struct rte_cryptodev_info *info)
info->max_nb_queue_pairs = dev->max_qps;
info->feature_flags = dev->features;
info->capabilities = iocpt_get_caps(info->feature_flags);
- info->sym.max_nb_sessions = dev->max_sessions;
+ /* Reserve one session for watchdog */
+ info->sym.max_nb_sessions = dev->max_sessions - 1;
info->driver_id = dev->driver_id;
info->min_mbuf_headroom_req = 0;
info->min_mbuf_tailroom_req = 0;
@@ -380,12 +381,72 @@ iocpt_enqueue_sym(void *qp, struct rte_crypto_op **ops, uint16_t nb_ops)
count++;
}
- if (likely(count > 0))
+ if (likely(count > 0)) {
iocpt_q_flush(&cptq->q);
+ /* Restart timer if ops are being enqueued */
+ cptq->last_wdog_cycles = rte_get_timer_cycles();
+ }
+
return count;
}
+static void
+iocpt_enqueue_wdog(struct iocpt_crypto_q *cptq)
+{
+ struct iocpt_queue *q = &cptq->q;
+ struct iocpt_crypto_desc *desc, *desc_base = q->base;
+ struct iocpt_crypto_sg_desc *sg_desc, *sg_desc_base = q->sg_base;
+ struct iocpt_crypto_sg_elem *src;
+ struct rte_crypto_op *wdog_op;
+ rte_iova_t iv_addr, pld_addr, tag_addr;
+ uint8_t nsge_src = 0;
+ uint16_t avail;
+
+ avail = iocpt_q_space_avail(&cptq->q);
+ if (avail < 1)
+ goto out_flush;
+
+ wdog_op = rte_zmalloc_socket("iocpt", sizeof(*wdog_op),
+ RTE_CACHE_LINE_SIZE, rte_socket_id());
+ if (wdog_op == NULL)
+ goto out_flush;
+
+ wdog_op->type = IOCPT_Q_WDOG_OP_TYPE;
+ wdog_op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+
+ desc = &desc_base[q->head_idx];
+ sg_desc = &sg_desc_base[q->head_idx];
+ src = sg_desc->src_elems;
+
+ /* Fill the first SGE with the IV / Nonce */
+ iv_addr = rte_mem_virt2iova(cptq->wdog_iv);
+ iocpt_fill_sge(src, nsge_src++, iv_addr, IOCPT_Q_WDOG_IV_LEN);
+
+ /* Fill the second SGE with the payload segment */
+ pld_addr = rte_mem_virt2iova(cptq->wdog_pld);
+ iocpt_fill_sge(src, nsge_src++, pld_addr, IOCPT_Q_WDOG_PLD_LEN);
+
+ /* AEAD AES-GCM: digest == authentication tag */
+ tag_addr = rte_mem_virt2iova(cptq->wdog_tag);
+ iocpt_fill_sge(src, nsge_src++, tag_addr, IOCPT_Q_WDOG_TAG_LEN);
+
+ desc->opcode = IOCPT_DESC_OPCODE_GCM_AEAD_ENCRYPT;
+ desc->flags = 0;
+ desc->num_src_dst_sgs = iocpt_encode_nsge_src_dst(nsge_src, 0);
+ desc->session_tag = rte_cpu_to_le_32(IOCPT_Q_WDOG_SESS_IDX);
+
+ q->info[q->head_idx] = wdog_op;
+ q->head_idx = Q_NEXT_TO_POST(q, 1);
+
+ IOCPT_PRINT(DEBUG, "Queue %u wdog enq %p",
+ q->index, wdog_op);
+ cptq->enqueued_wdogs++;
+
+out_flush:
+ iocpt_q_flush(q);
+}
+
static uint16_t
iocpt_dequeue_sym(void *qp, struct rte_crypto_op **ops, uint16_t nb_ops)
{
@@ -395,6 +456,7 @@ iocpt_dequeue_sym(void *qp, struct rte_crypto_op **ops, uint16_t nb_ops)
struct rte_crypto_op *op;
struct iocpt_crypto_comp *cq_desc_base = cq->base;
volatile struct iocpt_crypto_comp *cq_desc;
+ uint64_t then, now, hz, delta;
uint16_t count = 0;
cq_desc = &cq_desc_base[cq->tail_idx];
@@ -442,6 +504,17 @@ iocpt_dequeue_sym(void *qp, struct rte_crypto_op **ops, uint16_t nb_ops)
op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED)
break;
+ /* Handle watchdog operations */
+ if (unlikely(op->type == IOCPT_Q_WDOG_OP_TYPE)) {
+ IOCPT_PRINT(DEBUG, "Queue %u wdog deq %p st %d",
+ q->index, op, op->status);
+ q->info[q->tail_idx] = NULL;
+ q->tail_idx = Q_NEXT_TO_SRVC(q, 1);
+ cptq->dequeued_wdogs++;
+ rte_free(op);
+ continue;
+ }
+
ops[count] = op;
q->info[q->tail_idx] = NULL;
@@ -449,6 +522,26 @@ iocpt_dequeue_sym(void *qp, struct rte_crypto_op **ops, uint16_t nb_ops)
count++;
}
+ if (!count) {
+ /*
+ * Ring the doorbell again if no work was dequeued and work
+ * is still pending after the deadline.
+ */
+ if (q->head_idx != q->tail_idx) {
+ then = cptq->last_wdog_cycles;
+ now = rte_get_timer_cycles();
+ hz = rte_get_timer_hz();
+ delta = (now - then) * 1000;
+
+ if (delta >= hz * IONIC_Q_WDOG_MS) {
+ iocpt_enqueue_wdog(cptq);
+ cptq->last_wdog_cycles = now;
+ }
+ }
+ } else
+ /* Restart timer if the queue is making progress */
+ cptq->last_wdog_cycles = rte_get_timer_cycles();
+
return count;
}
--
2.17.1
next prev parent reply other threads:[~2024-04-30 20:23 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-19 19:53 [PATCH 0/6] crypto/ionic: introduce AMD Pensando ionic crypto driver Andrew Boyer
2024-04-19 19:53 ` [PATCH 1/6] " Andrew Boyer
2024-04-19 19:53 ` [PATCH 2/6] crypto/ionic: add device and admin command handlers Andrew Boyer
2024-04-22 12:29 ` Boyer, Andrew
2024-04-19 19:53 ` [PATCH 3/6] common/ionic: add crypto vdev support Andrew Boyer
2024-04-19 19:53 ` [PATCH 4/6] crypto/ionic: add device object and " Andrew Boyer
2024-04-19 19:53 ` [PATCH 5/6] crypto/ionic: add datapath and capabilities support Andrew Boyer
2024-04-19 19:53 ` [PATCH 6/6] crypto/ionic: add documentation and connect to build Andrew Boyer
2024-04-24 18:21 ` [EXTERNAL] [PATCH 0/6] crypto/ionic: introduce AMD Pensando ionic crypto driver Akhil Goyal
2024-04-30 20:21 ` [PATCH v2 0/9] " Andrew Boyer
2024-04-30 20:21 ` [PATCH v2 1/9] " Andrew Boyer
2024-05-30 12:02 ` [EXTERNAL] " Akhil Goyal
2024-04-30 20:21 ` [PATCH v2 2/9] crypto/ionic: add the firmware interface definition file Andrew Boyer
2024-04-30 20:21 ` [PATCH v2 3/9] crypto/ionic: add device commands Andrew Boyer
2024-04-30 20:21 ` [PATCH v2 4/9] crypto/ionic: add adminq command support Andrew Boyer
2024-04-30 20:21 ` [PATCH v2 5/9] crypto/ionic: add capabilities and basic ops Andrew Boyer
2024-04-30 20:21 ` [PATCH v2 6/9] crypto/ionic: add session support Andrew Boyer
2024-04-30 20:21 ` [PATCH v2 7/9] crypto/ionic: add datapath Andrew Boyer
2024-04-30 20:21 ` Andrew Boyer [this message]
2024-04-30 20:21 ` [PATCH v2 9/9] crypto/ionic: add stats support Andrew Boyer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240430202144.49899-9-andrew.boyer@amd.com \
--to=andrew.boyer@amd.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).