Commit 8625cc18 authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Tomasz Zawadzki
Browse files

accel/error: add accel_error_inject RPC



This RPC will allow users to configure error injections for a given
operation.  To disable error injection, either type=disable or count=0
needs be specified.

Of course, in order for the error injection to actually take place, the
error module needs to be assigned to a given operation via
spdk_accel_assign_opc().

Signed-off-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Change-Id: I4935adf305eb202d8db89ac07743ff321bab8df2
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/20438


Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 849d3939
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -449,6 +449,7 @@ Example response:
    "accel_assign_opc",
    "accel_get_module_info",
    "accel_get_opc_assignments",
    "accel_error_inject_error",
    "ioat_scan_accel_module",
    "dsa_scan_accel_module",
    "dpdk_cryptodev_scan_accel_module",
@@ -2036,6 +2037,44 @@ Example response:
}
~~~

### accel_error_inject_error {#rpc_accel_error_inject_error}

Inject an error to execution of a given operation.  Note, that in order for the errors to be
actually injected, the error module must be assigned to that operation via `accel_assign_opc`.

#### Parameters

Name                    | Optional | Type        | Description
----------------------- |----------| ----------- | -----------------
opcode                  | Required | string      | Operation to inject errors.
type                    | Required | string      | Type of errors to inject ("corrupt": corrupt the data, "disable": disable error injection).
count                   | Optional | number      | Numbers of errors to inject on each IO channel (`UINT64_MAX` by default).

#### Example

Example request:

~~~json
{
  "method": "accel_error_inject_error",
  "params": {
    "opcode": "crc32c",
    "type": "corrupt",
    "count": 10000
  }
}
~~~

Example response:

~~~json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": true
}
~~~

### compressdev_scan_accel_module {#rpc_compressdev_scan_accel_module}

Set config and enable compressdev accel module offload.
+1 −1
Original line number Diff line number Diff line
@@ -105,7 +105,7 @@ DEPDIRS-accel_dsa := log idxd thread $(JSON_LIBS) accel trace
DEPDIRS-accel_iaa := log idxd thread $(JSON_LIBS) accel trace
DEPDIRS-accel_dpdk_cryptodev := log thread $(JSON_LIBS) accel util
DEPDIRS-accel_dpdk_compressdev := log thread $(JSON_LIBS) accel util
DEPDIRS-accel_error := accel thread
DEPDIRS-accel_error := accel $(JSON_LIBS) thread util

ifeq ($(CONFIG_RDMA_PROV),mlx5_dv)
DEPDIRS-accel_mlx5 := accel thread log mlx5 rdma util
+1 −1
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ SO_VER := 1
SO_MINOR := 0

LIBNAME = accel_error
C_SRCS = accel_error.c
C_SRCS = accel_error.c accel_error_rpc.c

SPDK_MAP_FILE = $(SPDK_ROOT_DIR)/mk/spdk_blank.map

+71 −1
Original line number Diff line number Diff line
@@ -2,12 +2,21 @@
 * Copyright (C) 2023 Intel Corporation. All rights reserved.
 */

#include "accel_error.h"
#include "spdk/accel.h"
#include "spdk/accel_module.h"
#include "spdk/thread.h"

struct accel_error_inject_info {
	/* Error injection options */
	struct accel_error_inject_opts	opts;
	/* Number of errors already injected on this channel */
	uint64_t			count;
};

struct accel_error_channel {
	struct spdk_io_channel		*swch;
	struct accel_error_inject_info	injects[SPDK_ACCEL_OPC_LAST];
};

struct accel_error_task {
@@ -16,6 +25,7 @@ struct accel_error_task {
};

static struct spdk_accel_module_if *g_sw_module;
static struct accel_error_inject_opts g_injects[SPDK_ACCEL_OPC_LAST];
static size_t g_task_offset;

static struct accel_error_task *
@@ -49,16 +59,60 @@ accel_error_submit_tasks(struct spdk_io_channel *ch, struct spdk_accel_task *tas
	return g_sw_module->submit_tasks(errch->swch, task);
}

static void
accel_error_inject_channel(struct spdk_io_channel_iter *iter)
{
	struct spdk_io_channel *ch = spdk_io_channel_iter_get_channel(iter);
	struct accel_error_channel *errch = spdk_io_channel_get_ctx(ch);
	struct accel_error_inject_opts *opts = spdk_io_channel_iter_get_ctx(iter);
	struct accel_error_inject_info *info = &errch->injects[opts->opcode];

	info->count = 0;
	memcpy(&info->opts, opts, sizeof(info->opts));

	spdk_for_each_channel_continue(iter, 0);
}

static bool accel_error_supports_opcode(enum spdk_accel_opcode opcode);

int
accel_error_inject_error(struct accel_error_inject_opts *opts)
{
	struct accel_error_inject_opts *curr = &g_injects[opts->opcode];

	if (!accel_error_supports_opcode(opts->opcode)) {
		return -EINVAL;
	}

	memcpy(curr, opts, sizeof(*opts));
	if (curr->type == ACCEL_ERROR_INJECT_DISABLE) {
		curr->count = 0;
	}
	if (curr->count == 0) {
		curr->type = ACCEL_ERROR_INJECT_DISABLE;
	}

	spdk_for_each_channel(&g_sw_module, accel_error_inject_channel, curr, NULL);

	return 0;
}

static int
accel_error_channel_create_cb(void *io_device, void *ctx)
{
	struct accel_error_channel *errch = ctx;
	size_t i;

	errch->swch = g_sw_module->get_io_channel();
	if (errch->swch == NULL) {
		return -ENOMEM;
	}

	for (i = 0; i < SPDK_COUNTOF(errch->injects); ++i) {
		memcpy(&errch->injects[i].opts, &g_injects[i], sizeof(g_injects[i]));
		errch->injects[i].count = 0;
	}

	return 0;
}

@@ -118,6 +172,22 @@ accel_error_get_ctx_size(void)
	return g_task_offset + sizeof(struct accel_error_task);
}

const char *
accel_error_get_type_name(enum accel_error_inject_type type)
{
	const char *typenames[] = {
		[ACCEL_ERROR_INJECT_DISABLE] = "disable",
		[ACCEL_ERROR_INJECT_CORRUPT] = "corrupt",
		[ACCEL_ERROR_INJECT_MAX] = NULL
	};

	if ((int)type >= ACCEL_ERROR_INJECT_MAX) {
		return NULL;
	}

	return typenames[type];
}

static struct spdk_accel_module_if g_accel_error_module = {
	.name			= "error",
	.priority		= INT_MIN,
+25 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: BSD-3-Clause
 * Copyright (C) 2023 Intel Corporation. All rights reserved.
 */

#ifndef SPDK_ACCEL_ERROR_H
#define SPDK_ACCEL_ERROR_H

#include "spdk/accel.h"

enum accel_error_inject_type {
	ACCEL_ERROR_INJECT_DISABLE,
	ACCEL_ERROR_INJECT_CORRUPT,
	ACCEL_ERROR_INJECT_MAX,
};

struct accel_error_inject_opts {
	enum spdk_accel_opcode		opcode;
	enum accel_error_inject_type	type;
	uint64_t			count;
};

int accel_error_inject_error(struct accel_error_inject_opts *opts);
const char *accel_error_get_type_name(enum accel_error_inject_type type);

#endif /* SPDK_ACCEL_ERROR_H */
Loading