Commit 008a6371 authored by Alexey Marchuk's avatar Alexey Marchuk Committed by Konrad Sztyber
Browse files

accel/mlx5: Initial implementation of mlx5 platform driver



Now we just execute all tasks one by one.
The driver supports only limited scope of operations
and disabled by default

Signed-off-by: default avatarAlexey Marchuk <alexeymar@nvidia.com>
Change-Id: I1478db685b1621a4610be1c80929d62d1106e908
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/24698


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Community CI Samsung <spdk.community.ci.samsung@gmail.com>
parent cc533a3e
Loading
Loading
Loading
Loading
+83 −2
Original line number Diff line number Diff line
@@ -72,6 +72,9 @@ enum accel_mlx5_opcode {
	ACCEL_MLX5_OPC_LAST
};

SPDK_STATIC_ASSERT(ACCEL_MLX5_OPC_LAST <= 0xf,
		   "accel opcode exceeds 4 bits, update accel_mlx5 struct");

struct accel_mlx5_stats {
	uint64_t crypto_umrs;
	uint64_t sig_umrs;
@@ -152,8 +155,9 @@ struct accel_mlx5_task {
		uint8_t raw;
		struct {
			uint8_t inplace : 1;
			uint8_t driver_seq : 1;
			uint8_t enc_order : 2;
			uint8_t mlx5_opcode: 5;
			uint8_t mlx5_opcode: 4;
		};
	};
	/* Keep this array last since not all elements might be accessed, this reduces amount of data to be
@@ -167,7 +171,6 @@ struct accel_mlx5_qp {
	struct spdk_mlx5_qp *qp;
	struct ibv_qp *verbs_qp;
	struct accel_mlx5_dev *dev;
	struct accel_mlx5_io_channel *ch;
	/* tasks submitted to HW. We can't complete a task even in error case until we reap completions for all
	 * submitted requests */
	STAILQ_HEAD(, accel_mlx5_task) in_hw;
@@ -184,6 +187,7 @@ struct accel_mlx5_dev {
	struct spdk_mlx5_mkey_pool *sig_mkeys;
	struct spdk_rdma_utils_mem_map *mmap;
	struct accel_mlx5_dev_ctx *dev_ctx;
	struct spdk_io_channel *ch;
	uint16_t wrs_in_cq;
	uint16_t wrs_in_cq_max;
	uint16_t crypto_split_blocks;
@@ -224,6 +228,10 @@ struct accel_mlx5_dump_stats_ctx {
};

static struct accel_mlx5_module g_accel_mlx5;
static struct spdk_accel_driver g_accel_mlx5_driver;

static inline int accel_mlx5_execute_sequence(struct spdk_io_channel *ch,
		struct spdk_accel_sequence *seq);

static inline void
accel_mlx5_iov_sgl_init(struct accel_mlx5_iov_sgl *s, struct iovec *iov, uint32_t iovcnt)
@@ -311,6 +319,9 @@ static inline void
accel_mlx5_task_fail(struct accel_mlx5_task *task, int rc)
{
	struct accel_mlx5_dev *dev = task->qp->dev;
	struct spdk_accel_task *next;
	struct spdk_accel_sequence *seq;
	bool driver_seq;

	assert(task->num_reqs == task->num_completed_reqs);
	SPDK_DEBUGLOG(accel_mlx5, "Fail task %p, opc %d, rc %d\n", task, task->base.op_code, rc);
@@ -324,7 +335,24 @@ accel_mlx5_task_fail(struct accel_mlx5_task *task, int rc)
			spdk_mempool_put(dev->dev_ctx->psv_pool, task->psv);
		}
	}
	next = spdk_accel_sequence_next_task(&task->base);
	seq = task->base.seq;
	driver_seq = task->driver_seq;

	assert(task->num_reqs == task->num_completed_reqs);
	SPDK_DEBUGLOG(accel_mlx5, "Fail task %p, opc %d, rc %d\n", task, task->mlx5_opcode, rc);
	spdk_accel_task_complete(&task->base, rc);

	if (driver_seq) {
		struct spdk_io_channel *ch = task->qp->dev->ch;

		assert(seq);
		if (next) {
			accel_mlx5_execute_sequence(ch, seq);
		} else {
			spdk_accel_sequence_continue(seq);
		}
	}
}

static int
@@ -1706,10 +1734,28 @@ static struct accel_mlx5_task_operations g_accel_mlx5_tasks_ops[] = {
static inline void
accel_mlx5_task_complete(struct accel_mlx5_task *task)
{
	struct spdk_accel_sequence *seq = task->base.seq;
	struct spdk_accel_task *next;
	bool driver_seq;

	next = spdk_accel_sequence_next_task(&task->base);
	driver_seq = task->driver_seq;

	assert(task->num_reqs == task->num_completed_reqs);
	SPDK_DEBUGLOG(accel_mlx5, "Complete task %p, opc %d\n", task, task->base.op_code);

	g_accel_mlx5_tasks_ops[task->mlx5_opcode].complete(task);

	if (driver_seq) {
		struct spdk_io_channel *ch = task->qp->dev->ch;

		assert(seq);
		if (next) {
			accel_mlx5_execute_sequence(ch, seq);
		} else {
			spdk_accel_sequence_continue(seq);
		}
	}
}

static inline int
@@ -2182,6 +2228,7 @@ accel_mlx5_create_cb(void *io_device, void *ctx_buf)
		dev->crypto_multi_block = dev_ctx->crypto_multi_block;
		dev->crypto_split_blocks = dev_ctx->crypto_multi_block ? g_accel_mlx5.attr.crypto_split_blocks : 0;
		dev->wrs_in_cq_max = g_accel_mlx5.attr.qp_size;
		dev->ch = spdk_io_channel_from_ctx(ctx_buf);
		STAILQ_INIT(&dev->nomem);
	}

@@ -2203,6 +2250,7 @@ accel_mlx5_get_default_attr(struct accel_mlx5_attr *attr)
	attr->num_requests = ACCEL_MLX5_NUM_REQUESTS;
	attr->allowed_devs = NULL;
	attr->crypto_split_blocks = 0;
	attr->enable_driver = false;
}

static void
@@ -2707,6 +2755,12 @@ accel_mlx5_init(void)
	free(rdma_devs);
	free(caps);

	if (g_accel_mlx5.attr.enable_driver) {
		SPDK_NOTICELOG("Enabling mlx5 platform driver\n");
		spdk_accel_driver_register(&g_accel_mlx5_driver);
		spdk_accel_set_driver(g_accel_mlx5_driver.name);
	}

	return 0;

cleanup:
@@ -2731,6 +2785,7 @@ accel_mlx5_write_config_json(struct spdk_json_write_ctx *w)
			spdk_json_write_named_string(w, "allowed_devs", g_accel_mlx5.attr.allowed_devs);
		}
		spdk_json_write_named_uint16(w, "crypto_split_blocks", g_accel_mlx5.attr.crypto_split_blocks);
		spdk_json_write_named_bool(w, "enable_driver", g_accel_mlx5.attr.enable_driver);
		spdk_json_write_object_end(w);
		spdk_json_write_object_end(w);
	}
@@ -2973,6 +3028,26 @@ accel_mlx5_get_memory_domains(struct spdk_memory_domain **domains, int array_siz
	return (int)g_accel_mlx5.num_ctxs;
}

static inline int
accel_mlx5_execute_sequence(struct spdk_io_channel *ch, struct spdk_accel_sequence *seq)
{
	struct accel_mlx5_io_channel *accel_ch = spdk_io_channel_get_ctx(ch);
	struct spdk_accel_task *task;
	struct accel_mlx5_task *mlx5_task;

	task = spdk_accel_sequence_first_task(seq);
	assert(task);
	mlx5_task = SPDK_CONTAINEROF(task, struct accel_mlx5_task, base);
	mlx5_task->raw = 0;
	mlx5_task->driver_seq = 1;
	accel_mlx5_task_assign_qp(mlx5_task, accel_ch);
	accel_mlx5_task_reset(mlx5_task);
	accel_mlx5_task_init_opcode(mlx5_task);
	SPDK_DEBUGLOG(accel_mlx5, "driver starts seq %p, ch %p, task %p\n", seq, accel_ch, task);

	return _accel_mlx5_submit_tasks(accel_ch, task);
}

static struct accel_mlx5_module g_accel_mlx5 = {
	.module = {
		.module_init		= accel_mlx5_init,
@@ -2990,4 +3065,10 @@ static struct accel_mlx5_module g_accel_mlx5 = {
	}
};

static struct spdk_accel_driver g_accel_mlx5_driver = {
	.name			= "mlx5",
	.execute_sequence	= accel_mlx5_execute_sequence,
	.get_io_channel		= accel_mlx5_get_io_channel
};

SPDK_LOG_REGISTER_COMPONENT(accel_mlx5)
+2 −0
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@ struct accel_mlx5_attr {
	/* Apply crypto operation for each X data blocks. Works only if multiblock crypto operation is supported by HW.
	 * 0 means no limit */
	uint16_t crypto_split_blocks;
	/* Enables accel_mlx5 platform driver. The driver can execute a limited scope of operations */
	bool enable_driver;
};

enum accel_mlx5_dump_state_level {
+1 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ static const struct spdk_json_object_decoder rpc_mlx5_module_decoder[] = {
	{"num_requests", offsetof(struct accel_mlx5_attr, num_requests), spdk_json_decode_uint32, true},
	{"allowed_devs", offsetof(struct accel_mlx5_attr, allowed_devs), spdk_json_decode_string, true},
	{"crypto_split_blocks", offsetof(struct accel_mlx5_attr, crypto_split_blocks), spdk_json_decode_uint16, true},
	{"enable_driver", offsetof(struct accel_mlx5_attr, enable_driver), spdk_json_decode_bool, true},
};

static void
+5 −1
Original line number Diff line number Diff line
@@ -5,7 +5,8 @@
from spdk.rpc.helpers import deprecated_alias


def mlx5_scan_accel_module(client, qp_size=None, num_requests=None, allowed_devs=None, crypto_split_blocks=None):
def mlx5_scan_accel_module(client, qp_size=None, num_requests=None, allowed_devs=None, crypto_split_blocks=None,
                           enable_driver=None):
    """Enable mlx5 accel module. Scans all mlx5 devices which can perform needed operations

    Args:
@@ -13,6 +14,7 @@ def mlx5_scan_accel_module(client, qp_size=None, num_requests=None, allowed_devs
        num_requests: size of a global requests pool per mlx5 device (optional)
        allowed_devs: Comma separated list of allowed device names, e.g. mlx5_0,mlx5_1
        crypto_split_blocks: Number of data blocks to be processed in 1 crypto UMR. [0-65535], 0 means no limit
        enable_driver: Enable mlx5 platform driver. Note: the driver supports reduced scope of operations, enable with care
    """
    params = {}

@@ -24,6 +26,8 @@ def mlx5_scan_accel_module(client, qp_size=None, num_requests=None, allowed_devs
        params['allowed_devs'] = allowed_devs
    if crypto_split_blocks is not None:
        params['crypto_split_blocks'] = crypto_split_blocks
    if enable_driver is not None:
        params['enable_driver'] = enable_driver
    return client.call('mlx5_scan_accel_module', params)


+4 −1
Original line number Diff line number Diff line
@@ -3401,7 +3401,8 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
                                        qp_size=args.qp_size,
                                        num_requests=args.num_requests,
                                        allowed_devs=args.allowed_devs,
                                        crypto_split_blocks=args.crypto_split_blocks)
                                        crypto_split_blocks=args.crypto_split_blocks,
                                        enable_driver=args.enable_driver)

    p = subparsers.add_parser('mlx5_scan_accel_module', help='Enable mlx5 accel module.')
    p.add_argument('-q', '--qp-size', type=int, help='QP size')
@@ -3409,6 +3410,8 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
    p.add_argument('-d', '--allowed-devs', help="Comma separated list of allowed device names, e.g. mlx5_0,mlx5_1")
    p.add_argument('-s', '--crypto-split-blocks', type=int,
                   help="Number of data blocks to be processed in 1 crypto UMR. [0-65535], 0 means no limit")
    p.add_argument('-e', '--enable-driver', dest='enable_driver', action='store_true', default=None,
                   help="Enable mlx5 platform driver. Note: the driver supports reduced scope of operations, enable with care")
    p.set_defaults(func=mlx5_scan_accel_module)

    def accel_mlx5_dump_stats(args):
Loading