accel: add accel_get_stats

The RPC allows the user to retrieve accel framework's statistics.

Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com>
Change-Id: I5cd1b45686504c08eda50513ad1dae2f8d65013b
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/17191
Community-CI: Mellanox Build Bot
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Konrad Sztyber 2023-02-28 07:58:27 +01:00 committed by David Ko
parent 319dedcb31
commit 0f81ba102b
6 changed files with 161 additions and 0 deletions

View File

@ -1981,6 +1981,57 @@ Example response:
}
~~~
### accel_get_stats {#rpc_accel_get_stats}
Retrieve accel framework's statistics. Statistics for opcodes that have never been executed (i.e.
all their stats are at 0) aren't included in the `operations` array.
#### Parameters
None.
#### Example
Example request:
~~~json
{
"jsonrpc": "2.0",
"method": "accel_get_stats",
"id": 1
}
~~~
Example response:
~~~json
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"sequence_executed": 256,
"sequence_failed": 0,
"operations": [
{
"opcode": "copy",
"executed": 256,
"failed": 0
},
{
"opcode": "encrypt",
"executed": 128,
"failed": 0
},
{
"opcode": "decrypt",
"executed": 128,
"failed": 0
}
]
}
}
~~~
### compressdev_scan_accel_module {#rpc_compressdev_scan_accel_module}
Set config and enable compressdev accel module offload.

View File

@ -2520,4 +2520,57 @@ spdk_accel_get_opts(struct spdk_accel_opts *opts)
opts->size = size;
}
struct accel_get_stats_ctx {
struct accel_stats stats;
accel_get_stats_cb cb_fn;
void *cb_arg;
};
static void
accel_get_channel_stats_done(struct spdk_io_channel_iter *iter, int status)
{
struct accel_get_stats_ctx *ctx = spdk_io_channel_iter_get_ctx(iter);
ctx->cb_fn(&ctx->stats, ctx->cb_arg);
free(ctx);
}
static void
accel_get_channel_stats(struct spdk_io_channel_iter *iter)
{
struct spdk_io_channel *ch = spdk_io_channel_iter_get_channel(iter);
struct accel_io_channel *accel_ch = spdk_io_channel_get_ctx(ch);
struct accel_get_stats_ctx *ctx = spdk_io_channel_iter_get_ctx(iter);
struct accel_stats *stats = &ctx->stats;
int i;
stats->sequence_executed += accel_ch->stats.sequence_executed;
stats->sequence_failed += accel_ch->stats.sequence_failed;
for (i = 0; i < ACCEL_OPC_LAST; ++i) {
stats->operations[i].executed += accel_ch->stats.operations[i].executed;
stats->operations[i].failed += accel_ch->stats.operations[i].failed;
}
spdk_for_each_channel_continue(iter, 0);
}
int
accel_get_stats(accel_get_stats_cb cb_fn, void *cb_arg)
{
struct accel_get_stats_ctx *ctx;
ctx = calloc(1, sizeof(*ctx));
if (ctx == NULL) {
return -ENOMEM;
}
ctx->cb_fn = cb_fn;
ctx->cb_arg = cb_arg;
spdk_for_each_channel(&spdk_accel_module_list, accel_get_channel_stats, ctx,
accel_get_channel_stats_done);
return 0;
}
SPDK_LOG_REGISTER_COMPONENT(accel)

View File

@ -36,5 +36,7 @@ void _accel_for_each_module(struct module_info *info, _accel_for_each_module_fn
int _accel_get_opc_name(enum accel_opcode opcode, const char **opcode_name);
void _accel_crypto_key_dump_param(struct spdk_json_write_ctx *w, struct spdk_accel_crypto_key *key);
void _accel_crypto_keys_dump_param(struct spdk_json_write_ctx *w);
typedef void (*accel_get_stats_cb)(struct accel_stats *stats, void *cb_arg);
int accel_get_stats(accel_get_stats_cb cb_fn, void *cb_arg);
#endif

View File

@ -397,3 +397,46 @@ rpc_accel_set_options(struct spdk_jsonrpc_request *request, const struct spdk_js
spdk_jsonrpc_send_bool_response(request, true);
}
SPDK_RPC_REGISTER("accel_set_options", rpc_accel_set_options, SPDK_RPC_STARTUP)
static void
rpc_accel_get_stats_done(struct accel_stats *stats, void *cb_arg)
{
struct spdk_jsonrpc_request *request = cb_arg;
struct spdk_json_write_ctx *w;
const char *name;
int i;
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_object_begin(w);
spdk_json_write_named_uint64(w, "sequence_executed", stats->sequence_executed);
spdk_json_write_named_uint64(w, "sequence_failed", stats->sequence_failed);
spdk_json_write_named_array_begin(w, "operations");
for (i = 0; i < ACCEL_OPC_LAST; ++i) {
if (stats->operations[i].executed + stats->operations[i].failed == 0) {
continue;
}
_accel_get_opc_name(i, &name);
spdk_json_write_object_begin(w);
spdk_json_write_named_string(w, "opcode", name);
spdk_json_write_named_uint64(w, "executed", stats->operations[i].executed);
spdk_json_write_named_uint64(w, "failed", stats->operations[i].failed);
spdk_json_write_object_end(w);
}
spdk_json_write_array_end(w);
spdk_json_write_object_end(w);
spdk_jsonrpc_end_result(request, w);
}
static void
rpc_accel_get_stats(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
{
int rc;
rc = accel_get_stats(rpc_accel_get_stats_done, request);
if (rc != 0) {
spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
}
}
SPDK_RPC_REGISTER("accel_get_stats", rpc_accel_get_stats, SPDK_RPC_RUNTIME)

View File

@ -100,3 +100,9 @@ def accel_set_options(client, small_cache_size, large_cache_size):
params['large_cache_size'] = large_cache_size
return client.call('accel_set_options', params)
def accel_get_stats(client):
"""Get accel framework's statistics"""
return client.call('accel_get_stats')

View File

@ -2874,6 +2874,12 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
p.add_argument('--large-cache-size', type=int, help='Size of the large iobuf cache')
p.set_defaults(func=accel_set_options)
def accel_get_stats(args):
print_dict(rpc.accel.accel_get_stats(args.client))
p = subparsers.add_parser('accel_get_stats', help='Display accel framework\'s statistics')
p.set_defaults(func=accel_get_stats)
# ioat
def ioat_scan_accel_module(args):
rpc.ioat.ioat_scan_accel_module(args.client)