Commit dc8788d1 authored by paul luse's avatar paul luse Committed by Tomasz Zawadzki
Browse files

module/crypto: handle enqueue errors



A recent change in the CryptoDev API means that failure to enqueue
all attempted submissions does not automtically mean busy. We need
to check the status of the last submitted op and only retry if
busy, otherwise fail the IO.

Signed-off-by: default avatarpaul luse <paul.e.luse@intel.com>
Change-Id: I0873d07a430a08f5aee25581e47187ef60ba8542
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/472400


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent c602bd81
Loading
Loading
Loading
Loading
+35 −17
Original line number Diff line number Diff line
@@ -818,12 +818,21 @@ _crypto_operation(struct spdk_bdev_io *bdev_io, enum rte_crypto_cipher_operation
			   &crypto_ops[0],
			   burst);

	/* If any didn't get submitted, queue them for the poller to de-queue later. */
	/* Add this bdev_io to our outstanding list if any of its crypto ops made it. */
	if (num_enqueued_ops > 0) {
		TAILQ_INSERT_TAIL(&crypto_ch->pending_cry_ios, bdev_io, module_link);
		io_ctx->on_pending_list = true;
	}
	/* We were unable to enqueue everything but did get some, so need to decide what
	 * to do based on the status of the last op.
	 */
	if (num_enqueued_ops < cryop_cnt) {
		switch (crypto_ops[num_enqueued_ops]->status) {
		case RTE_CRYPTO_OP_STATUS_NOT_PROCESSED:
			/* Queue them up on a linked list to be resubmitted via the poller. */
			for (crypto_index = num_enqueued_ops; crypto_index < cryop_cnt; crypto_index++) {
				op_to_queue = (struct vbdev_crypto_op *)rte_crypto_op_ctod_offset(crypto_ops[crypto_index],
					uint8_t *,
					QUEUED_OP_OFFSET);
						uint8_t *, QUEUED_OP_OFFSET);
				op_to_queue->cdev_id = cdev_id;
				op_to_queue->qp = crypto_ch->device_qp->qp;
				op_to_queue->crypto_op = crypto_ops[crypto_index];
@@ -832,13 +841,22 @@ _crypto_operation(struct spdk_bdev_io *bdev_io, enum rte_crypto_cipher_operation
						  op_to_queue,
						  link);
			}

			break;
		default:
			/* For all other statuses, set the io_ctx bdev_io status so that
			 * the poller will pick the failure up for the overall bdev status.
			 */
			io_ctx->bdev_io_status = SPDK_BDEV_IO_STATUS_FAILED;
			if (num_enqueued_ops == 0) {
				/* If nothing was enqueued, but the last one wasn't because of
				 * busy, fail it now as the poller won't know anything about it.
				 */
				_crypto_operation_complete(bdev_io);
				rc = -EINVAL;
				goto error_attach_session;
			}
			break;
		}

	/* Add this bdev_io to our outstanding list if any of its crypto ops made it. */
	if (num_enqueued_ops > 0) {
		TAILQ_INSERT_TAIL(&crypto_ch->pending_cry_ios, bdev_io, module_link);
		io_ctx->on_pending_list = true;
	}

	return rc;
+9 −1
Original line number Diff line number Diff line
@@ -539,6 +539,7 @@ test_dev_full(void)
{
	struct vbdev_crypto_op *queued_op;
	struct rte_crypto_sym_op *sym_op;
	struct crypto_bdev_io *io_ctx;

	/* Two element block size read */
	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
@@ -553,6 +554,7 @@ test_dev_full(void)
	g_enqueue_mock = g_dequeue_mock = 1;
	ut_rte_crypto_op_bulk_alloc = 2;

	g_test_crypto_ops[1]->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
	CU_ASSERT(TAILQ_EMPTY(&g_crypto_ch->queued_cry_ops) == true);

	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
@@ -582,9 +584,15 @@ test_dev_full(void)
	CU_ASSERT(sym_op->m_src->userdata == g_bdev_io);
	CU_ASSERT(sym_op->m_dst == NULL);
	CU_ASSERT(TAILQ_EMPTY(&g_crypto_ch->queued_cry_ops) == true);

	spdk_mempool_put(g_mbuf_mp, g_test_crypto_ops[0]->sym->m_src);
	spdk_mempool_put(g_mbuf_mp, g_test_crypto_ops[1]->sym->m_src);

	/* Non-busy reason for enqueue failure, all were rejected. */
	g_enqueue_mock = 0;
	g_test_crypto_ops[0]->status = RTE_CRYPTO_OP_STATUS_ERROR;
	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
	io_ctx = (struct crypto_bdev_io *)g_bdev_io->driver_ctx;
	CU_ASSERT(io_ctx->bdev_io_status == SPDK_BDEV_IO_STATUS_FAILED);
}

static void