Commit 7535cdbd authored by Evgeniy Kochetov's avatar Evgeniy Kochetov Committed by Darek Stojaczyk
Browse files

rpc: Add thread_get_stats RPC method



SPDK threads collect busy and idle time statistics. This commit adds
thread_get_stats RPC method to retrieve these values.

Signed-off-by: default avatarEvgeniy Kochetov <evgeniik@mellanox.com>
Change-Id: I8ed8041c6164eb0c0a9336f4e50b5f26a3f20190
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/445285


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarSeth Howell <seth.howell5141@gmail.com>
Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarPaul Luse <paul.e.luse@intel.com>
parent 750a4213
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -95,6 +95,10 @@ sock groups. This API is intended to provide the user with that information.
spdk_sock_group_get_ctx() was added to return the context of the spdk_sock_group.
spdk_sock_group_create() is updated to allow input the user provided ctx.

### rpc

Added thread_get_stats RPC method to retrieve existing statistics.

## v19.04:

### nvme
+41 −0
Original line number Diff line number Diff line
@@ -484,6 +484,47 @@ Example response:
}
~~~

## thread_get_stats {#rpc_thread_get_stats}

Retrieve current statistics of all the threads.

### Parameters

This method has no parameters.

### Response

The response is an array of objects containing threads statistics.

### Example

Example request:
~~~
{
  "jsonrpc": "2.0",
  "method": "thread_get_stats",
  "id": 1
}
~~~

Example response:
~~~
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tick_rate": 2400000000,
    "threads": [
      {
        "name": "reactor_0",
        "busy": 139223208,
        "idle": 8641080608
      }
    ]
  }
}
~~~

# Block Device Abstraction Layer {#jsonrpc_components_bdev}

## set_bdev_options {#rpc_set_bdev_options}
+70 −2
Original line number Diff line number Diff line
/*-
 *   BSD LICENSE
 *
 *   Copyright (c) Intel Corporation.
 *   All rights reserved.
 *   Copyright (c) Intel Corporation. All rights reserved.
 *   Copyright (c) 2019 Mellanox Technologies LTD. All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
@@ -37,6 +37,8 @@
#include "spdk/rpc.h"
#include "spdk/string.h"
#include "spdk/util.h"
#include "spdk/env.h"
#include "spdk/thread.h"

#include "spdk_internal/log.h"

@@ -153,3 +155,69 @@ spdk_rpc_context_switch_monitor(struct spdk_jsonrpc_request *request,
}

SPDK_RPC_REGISTER("context_switch_monitor", spdk_rpc_context_switch_monitor, SPDK_RPC_RUNTIME)

struct rpc_thread_get_stats_ctx {
	struct spdk_jsonrpc_request *request;
	struct spdk_json_write_ctx *w;
};

static void
rpc_thread_get_stats_done(void *arg)
{
	struct rpc_thread_get_stats_ctx *ctx = arg;

	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_thread_get_stats(void *arg)
{
	struct rpc_thread_get_stats_ctx *ctx = arg;
	struct spdk_thread_stats stats;

	if (0 == spdk_thread_get_stats(&stats)) {
		spdk_json_write_object_begin(ctx->w);
		spdk_json_write_named_string(ctx->w, "name", spdk_thread_get_name(spdk_get_thread()));
		spdk_json_write_named_uint64(ctx->w, "busy", stats.busy_tsc);
		spdk_json_write_named_uint64(ctx->w, "idle", stats.idle_tsc);
		spdk_json_write_object_end(ctx->w);
	}
}

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;

	if (params) {
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
						 "'thread_get_stats' 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);
	if (NULL == ctx->w) {
		free(ctx);
		return;
	}
	spdk_json_write_object_begin(ctx->w);
	spdk_json_write_named_uint64(ctx->w, "tick_rate", spdk_get_ticks_hz());
	spdk_json_write_named_array_begin(ctx->w, "threads");

	spdk_for_each_thread(rpc_thread_get_stats, ctx, rpc_thread_get_stats_done);
}

SPDK_RPC_REGISTER("thread_get_stats", spdk_rpc_thread_get_stats, SPDK_RPC_RUNTIME)
+7 −0
Original line number Diff line number Diff line
@@ -1813,6 +1813,13 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
    p.add_argument('-n', '--max', help="""Maximum number of notifications to return in response""", type=int)
    p.set_defaults(func=get_notifications)

    def thread_get_stats(args):
        print_dict(rpc.app.thread_get_stats(args.client))

    p = subparsers.add_parser(
        'thread_get_stats', help='Display current statistics of all the threads')
    p.set_defaults(func=thread_get_stats)

    def check_called_name(name):
        if name in deprecated_aliases:
            print("{} is deprecated, use {} instead.".format(name, deprecated_aliases[name]), file=sys.stderr)
+9 −0
Original line number Diff line number Diff line
@@ -21,3 +21,12 @@ def context_switch_monitor(client, enabled=None):
    if enabled is not None:
        params['enabled'] = enabled
    return client.call('context_switch_monitor', params)


def thread_get_stats(client):
    """Query threads statistics.

    Returns:
        Current threads statistics.
    """
    return client.call('thread_get_stats')