Commit 3f657ddb authored by Alexey Marchuk's avatar Alexey Marchuk Committed by Tomasz Zawadzki
Browse files

mlx5: Allow to filter devices by name



accel_mlx5 can be configured with a list
of comma separated device names to be used

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


Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
parent b30c1383
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
/*   SPDX-License-Identifier: BSD-3-Clause
 *   Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES.
 *   Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES.
 *   All rights reserved.
 */

@@ -8,6 +8,8 @@

#include <infiniband/mlx5dv.h>

#define SPDK_MLX5_DEV_MAX_NAME_LEN 64

struct spdk_mlx5_crypto_dek;
struct spdk_mlx5_crypto_keytag;

@@ -65,5 +67,22 @@ int spdk_mlx5_crypto_set_attr(struct mlx5dv_crypto_attr *attr_out,
			      struct spdk_mlx5_crypto_keytag *keytag, struct ibv_pd *pd,
			      uint32_t block_size, uint64_t iv, bool encrypt_on_tx);

/**
 * Specify which devices are allowed to be used for crypto operation.
 *
 * If the user doesn't call this function then all devices which support crypto will be used.
 * This function copies devices names. In order to free allocated memory, the user must call
 * this function with either NULL \b dev_names or with \b devs_count equal 0. This way can also
 * be used to allow all devices.
 *
 * Subsequent calls with non-NULL \b dev_names and non-zero \b devs_count current copied dev_names array.
 *
 * This function is not thread safe.
 *
 * \param dev_names Array of devices names which are allowed to be used for crypto operations
 * \param devs_count Size of \b devs_count array
 * \return 0 on success, negated errno on failure
 */
int spdk_mlx5_crypto_devs_allow(const char *const dev_names[], size_t devs_count);

#endif /* SPDK_MLX5_H */
+69 −0
Original line number Diff line number Diff line
@@ -28,6 +28,9 @@
/* key1_256b + key2_256b + 64b_keytag */
#define SPDK_MLX5_AES_XTS_256_DEK_BYTES_WITH_KEYTAG (SPDK_MLX5_AES_XTS_256_DEK_BYTES + SPDK_MLX5_AES_XTS_KEYTAG_SIZE)

static char **g_allowed_devices;
static size_t g_allowed_devices_count;

struct spdk_mlx5_crypto_dek {
	struct mlx5dv_dek *dek_obj;
	struct ibv_pd *pd;
@@ -41,6 +44,68 @@ struct spdk_mlx5_crypto_keytag {
	char keytag[8];
};

static void
mlx5_crypto_devs_free(void)
{
	size_t i;

	if (!g_allowed_devices) {
		return;
	}

	for (i = 0; i < g_allowed_devices_count; i++) {
		free(g_allowed_devices[i]);
	}
	free(g_allowed_devices);
	g_allowed_devices = NULL;
	g_allowed_devices_count = 0;
}

static bool
mlx5_crypto_dev_allowed(const char *dev)
{
	size_t i;

	if (!g_allowed_devices || !g_allowed_devices_count) {
		return true;
	}

	for (i = 0; i < g_allowed_devices_count; i++) {
		if (strcmp(g_allowed_devices[i], dev) == 0) {
			return true;
		}
	}

	return false;
}

int
spdk_mlx5_crypto_devs_allow(const char *const dev_names[], size_t devs_count)
{
	size_t i;

	mlx5_crypto_devs_free();

	if (!dev_names || !devs_count) {
		return 0;
	}

	g_allowed_devices = calloc(devs_count, sizeof(char *));
	if (!g_allowed_devices) {
		return -ENOMEM;
	}
	for (i = 0; i < devs_count; i++) {
		g_allowed_devices[i] = strndup(dev_names[i], SPDK_MLX5_DEV_MAX_NAME_LEN);
		if (!g_allowed_devices[i]) {
			mlx5_crypto_devs_free();
			return -ENOMEM;
		}
		g_allowed_devices_count++;
	}

	return 0;
}

struct ibv_context **
spdk_mlx5_crypto_devs_get(int *dev_num)
{
@@ -76,6 +141,10 @@ spdk_mlx5_crypto_devs_get(int *dev_num)
			continue;
		}

		if (!mlx5_crypto_dev_allowed(dev->device->name)) {
			continue;
		}

		memset(&dv_dev_attr, 0, sizeof(dv_dev_attr));
		dv_dev_attr.comp_mask |= MLX5DV_CONTEXT_MASK_CRYPTO_OFFLOAD;
		rc = mlx5dv_query_device(dev, &dv_dev_attr);
+1 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
    spdk_mlx5_crypto_keytag_create;
    spdk_mlx5_crypto_keytag_destroy;
    spdk_mlx5_crypto_set_attr;
    spdk_mlx5_crypto_devs_allow;

	local: *;
};
+98 −0
Original line number Diff line number Diff line
@@ -29,6 +29,9 @@
#define ACCEL_MLX5_MAX_WC (64u)
#define ACCEL_MLX5_ALLOC_REQS_IN_BATCH (16u)

/* Assume we have up to 16 devices */
#define ACCEL_MLX5_ALLOWED_DEVS_MAX_LEN ((SPDK_MLX5_DEV_MAX_NAME_LEN + 1) * 16)

struct accel_mlx5_io_channel;
struct accel_mlx5_task;

@@ -45,6 +48,8 @@ struct accel_mlx5_module {
	struct accel_mlx5_crypto_dev_ctx *crypto_ctxs;
	uint32_t num_crypto_ctxs;
	struct accel_mlx5_attr attr;
	char **allowed_devs;
	size_t allowed_devs_count;
	bool enabled;
};

@@ -955,16 +960,102 @@ accel_mlx5_get_default_attr(struct accel_mlx5_attr *attr)

	attr->qp_size = ACCEL_MLX5_QP_SIZE;
	attr->num_requests = ACCEL_MLX5_NUM_REQUESTS;
	attr->allowed_devs = NULL;
}

static void
accel_mlx5_allowed_devs_free(void)
{
	size_t i;

	if (!g_accel_mlx5.allowed_devs) {
		return;
	}

	for (i = 0; i < g_accel_mlx5.allowed_devs_count; i++) {
		free(g_accel_mlx5.allowed_devs[i]);
	}
	free(g_accel_mlx5.attr.allowed_devs);
	free(g_accel_mlx5.allowed_devs);
	g_accel_mlx5.attr.allowed_devs = NULL;
	g_accel_mlx5.allowed_devs = NULL;
	g_accel_mlx5.allowed_devs_count = 0;
}

static int
accel_mlx5_allowed_devs_parse(const char *allowed_devs)
{
	char *str, *tmp, *tok;
	size_t devs_count = 0;

	str = strdup(allowed_devs);
	if (!str) {
		return -ENOMEM;
	}

	accel_mlx5_allowed_devs_free();

	tmp = str;
	while ((tmp = strchr(tmp, ',')) != NULL) {
		tmp++;
		devs_count++;
	}
	devs_count++;

	g_accel_mlx5.allowed_devs = calloc(devs_count, sizeof(char *));
	if (!g_accel_mlx5.allowed_devs) {
		free(str);
		return -ENOMEM;
	}

	devs_count = 0;
	tok = strtok(str, ",");
	while (tok) {
		g_accel_mlx5.allowed_devs[devs_count] = strdup(tok);
		if (!g_accel_mlx5.allowed_devs[devs_count]) {
			free(str);
			accel_mlx5_allowed_devs_free();
			return -ENOMEM;
		}
		tok = strtok(NULL, ",");
		devs_count++;
		g_accel_mlx5.allowed_devs_count++;
	}

	free(str);

	return 0;
}

int
accel_mlx5_enable(struct accel_mlx5_attr *attr)
{
	int rc;

	if (g_accel_mlx5.enabled) {
		return -EEXIST;
	}
	if (attr) {
		g_accel_mlx5.attr = *attr;
		g_accel_mlx5.attr.allowed_devs = NULL;

		if (attr->allowed_devs) {
			/* Contains a copy of user's string */
			g_accel_mlx5.attr.allowed_devs = strndup(attr->allowed_devs, ACCEL_MLX5_ALLOWED_DEVS_MAX_LEN);
			if (!g_accel_mlx5.attr.allowed_devs) {
				return -ENOMEM;
			}
			rc = accel_mlx5_allowed_devs_parse(g_accel_mlx5.attr.allowed_devs);
			if (rc) {
				return rc;
			}
			rc = spdk_mlx5_crypto_devs_allow((const char *const *)g_accel_mlx5.allowed_devs,
							 g_accel_mlx5.allowed_devs_count);
			if (rc) {
				accel_mlx5_allowed_devs_free();
				return rc;
			}
		}
	} else {
		accel_mlx5_get_default_attr(&g_accel_mlx5.attr);
	}
@@ -1020,6 +1111,10 @@ accel_mlx5_deinit_cb(void *ctx)
static void
accel_mlx5_deinit(void *ctx)
{
	if (g_accel_mlx5.allowed_devs) {
		accel_mlx5_allowed_devs_free();
	}
	spdk_mlx5_crypto_devs_allow(NULL, 0);
	if (g_accel_mlx5.crypto_ctxs) {
		spdk_io_device_unregister(&g_accel_mlx5, accel_mlx5_deinit_cb);
	} else {
@@ -1159,6 +1254,9 @@ accel_mlx5_write_config_json(struct spdk_json_write_ctx *w)
		spdk_json_write_named_object_begin(w, "params");
		spdk_json_write_named_uint16(w, "qp_size", g_accel_mlx5.attr.qp_size);
		spdk_json_write_named_uint32(w, "num_requests", g_accel_mlx5.attr.num_requests);
		if (g_accel_mlx5.attr.allowed_devs) {
			spdk_json_write_named_string(w, "allowed_devs", g_accel_mlx5.attr.allowed_devs);
		}
		spdk_json_write_object_end(w);
		spdk_json_write_object_end(w);
	}
+3 −1
Original line number Diff line number Diff line
/*   SPDX-License-Identifier: BSD-3-Clause
 *   Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 *   Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 */

#include "spdk/stdinc.h"
@@ -9,6 +9,8 @@ struct accel_mlx5_attr {
	uint16_t qp_size;
	/* The number of requests in the global pool */
	uint32_t num_requests;
	/* Comma separated list of allowed device names */
	char *allowed_devs;
};

void accel_mlx5_get_default_attr(struct accel_mlx5_attr *attr);
Loading