event/rpc: Add framework_get_reactors RPC

Add an new RPC `framework_get_reactors` to retrieve list of all
reactors.  Running threads on each reactor are included
in the output.  Update jsonrpc.md and CHANGELOG accordingly.

Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I985d087dd41afe3033b7678af141ec8e5a2a822e
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/478027
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Alexey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
Shuhei Matsumoto 2019-12-17 17:32:51 -05:00 committed by Tomasz Zawadzki
parent abbd6ed864
commit 876fdf2a59
5 changed files with 140 additions and 4 deletions

View File

@ -45,6 +45,8 @@ processing function. Batching is controlled by 'delay_cmd_submit' qpair option.
Added optional 'delay_cmd_submit' parameter to 'bdev_nvme_set_options' RPC method.
An new RPC `framework_get_reactors` has been added to retrieve list of all reactors.
### dpdk
Updated DPDK submodule to DPDK 19.11.

View File

@ -485,6 +485,50 @@ Example response:
}
~~~
## framework_get_reactors {#rpc_framework_get_reactors}
Retrieve an array of all reactors.
### Parameters
This method has no parameters.
### Response
The response is an array of all reactors.
### Example
Example request:
~~~
{
"jsonrpc": "2.0",
"method": "framework_get_reactors",
"id": 1
}
~~~
Example response:
~~~
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"reactors": [
{
"lcore": 0,
"lw_threads": [
{
"name": "app_thread",
"cpumask": "1"
}
]
}
]
}
}
~~~
## thread_get_stats {#rpc_thread_get_stats}
Retrieve current statistics of all the threads.

View File

@ -41,6 +41,7 @@
#include "spdk/thread.h"
#include "spdk_internal/log.h"
#include "spdk_internal/event.h"
struct rpc_spdk_kill_instance {
char *sig_name;
@ -152,7 +153,7 @@ SPDK_RPC_REGISTER("framework_monitor_context_switch", spdk_rpc_framework_monitor
SPDK_RPC_RUNTIME)
SPDK_RPC_REGISTER_ALIAS_DEPRECATED(framework_monitor_context_switch, context_switch_monitor)
struct rpc_thread_get_stats_ctx {
struct rpc_get_stats_ctx {
struct spdk_jsonrpc_request *request;
struct spdk_json_write_ctx *w;
};
@ -160,7 +161,7 @@ struct rpc_thread_get_stats_ctx {
static void
rpc_thread_get_stats_done(void *arg)
{
struct rpc_thread_get_stats_ctx *ctx = arg;
struct rpc_get_stats_ctx *ctx = arg;
spdk_json_write_array_end(ctx->w);
spdk_json_write_object_end(ctx->w);
@ -172,7 +173,7 @@ rpc_thread_get_stats_done(void *arg)
static void
rpc_thread_get_stats(void *arg)
{
struct rpc_thread_get_stats_ctx *ctx = arg;
struct rpc_get_stats_ctx *ctx = arg;
struct spdk_thread *thread = spdk_get_thread();
struct spdk_thread_stats stats;
@ -191,7 +192,7 @@ static void
spdk_rpc_thread_get_stats(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_thread_get_stats_ctx *ctx;
struct rpc_get_stats_ctx *ctx;
if (params) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
@ -216,3 +217,76 @@ spdk_rpc_thread_get_stats(struct spdk_jsonrpc_request *request,
}
SPDK_RPC_REGISTER("thread_get_stats", spdk_rpc_thread_get_stats, SPDK_RPC_RUNTIME)
static void
rpc_framework_get_reactors_done(void *arg1, void *arg2)
{
struct rpc_get_stats_ctx *ctx = arg1;
spdk_json_write_array_end(ctx->w);
spdk_json_write_object_end(ctx->w);
spdk_jsonrpc_end_result(ctx->request, ctx->w);
free(ctx);
}
static void
rpc_framework_get_reactors(void *arg1, void *arg2)
{
struct rpc_get_stats_ctx *ctx = arg1;
uint32_t current_core;
struct spdk_reactor *reactor;
struct spdk_lw_thread *lw_thread;
struct spdk_thread *thread;
current_core = spdk_env_get_current_core();
reactor = spdk_reactor_get(current_core);
spdk_json_write_object_begin(ctx->w);
spdk_json_write_named_uint32(ctx->w, "lcore", current_core);
spdk_json_write_named_array_begin(ctx->w, "lw_threads");
TAILQ_FOREACH(lw_thread, &reactor->threads, link) {
thread = spdk_thread_get_from_ctx(lw_thread);
spdk_json_write_object_begin(ctx->w);
spdk_json_write_named_string(ctx->w, "name", spdk_thread_get_name(thread));
spdk_json_write_named_string(ctx->w, "cpumask",
spdk_cpuset_fmt(spdk_thread_get_cpumask(thread)));
spdk_json_write_object_end(ctx->w);
}
spdk_json_write_array_end(ctx->w);
spdk_json_write_object_end(ctx->w);
}
static void
spdk_rpc_framework_get_reactors(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_get_stats_ctx *ctx;
if (params) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"`framework_get_reactors` requires no arguments");
return;
}
ctx = calloc(1, sizeof(*ctx));
if (!ctx) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
"Memory allocation error");
return;
}
ctx->request = request;
ctx->w = spdk_jsonrpc_begin_result(ctx->request);
spdk_json_write_object_begin(ctx->w);
spdk_json_write_named_array_begin(ctx->w, "reactors");
spdk_for_each_reactor(rpc_framework_get_reactors, ctx, NULL,
rpc_framework_get_reactors_done);
}
SPDK_RPC_REGISTER("framework_get_reactors", spdk_rpc_framework_get_reactors, SPDK_RPC_RUNTIME)

View File

@ -135,6 +135,13 @@ if __name__ == "__main__":
p.add_argument('-d', '--disable', action='store_true', help='Disable context switch monitoring')
p.set_defaults(func=framework_monitor_context_switch)
def framework_get_reactors(args):
print_dict(rpc.app.framework_get_reactors(args.client))
p = subparsers.add_parser(
'framework_get_reactors', help='Display list of all reactors')
p.set_defaults(func=framework_get_reactors)
# bdev
def bdev_set_options(args):
rpc.bdev.bdev_set_options(args.client,

View File

@ -28,6 +28,15 @@ def framework_monitor_context_switch(client, enabled=None):
return client.call('framework_monitor_context_switch', params)
def framework_get_reactors(client):
"""Query list of all reactors.
Returns:
List of all reactors.
"""
return client.call('framework_get_reactors')
def thread_get_stats(client):
"""Query threads statistics.