bdev: Clarify bdev_ctx and rpc_ctx for bdev_get_iostat RPC

The bdev_get_iostat RPC uses two types of contexts, one to manage the
progress of the bdev_get_iostat RPC and another to call
spdk_bdev_get_device_stat().

However, this was hard to find from the source code.

To make us easier to find this, rename the former by rpc_ctx and the
latter by bdev_ctx. Then rename related functions and variables accordingly.

Furthermore, relocate request and decoder declaration to improve
readability.

Signed-off-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
Change-Id: I3472c87fe4ec1f5981a49ef79148534fbb1d46c4
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15349
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Shuhei Matsumoto 2022-11-08 10:48:26 +09:00 committed by Tomasz Zawadzki
parent 038fb90350
commit 7c687dfcbd

View File

@ -157,7 +157,7 @@ cleanup:
} }
SPDK_RPC_REGISTER("bdev_examine", rpc_bdev_examine_bdev, SPDK_RPC_RUNTIME) SPDK_RPC_REGISTER("bdev_examine", rpc_bdev_examine_bdev, SPDK_RPC_RUNTIME)
struct rpc_bdev_get_iostat_ctx { struct rpc_get_iostat_ctx {
int bdev_count; int bdev_count;
int rc; int rc;
struct spdk_jsonrpc_request *request; struct spdk_jsonrpc_request *request;
@ -165,59 +165,57 @@ struct rpc_bdev_get_iostat_ctx {
bool per_channel; bool per_channel;
}; };
struct rpc_bdev_iostat { struct bdev_get_iostat_ctx {
struct spdk_bdev_io_stat stat; struct spdk_bdev_io_stat stat;
struct rpc_bdev_get_iostat_ctx *ctx; struct rpc_get_iostat_ctx *rpc_ctx;
struct spdk_bdev_desc *desc; struct spdk_bdev_desc *desc;
}; };
static void static void
rpc_bdev_get_iostat_started(struct rpc_bdev_get_iostat_ctx *ctx, rpc_get_iostat_started(struct rpc_get_iostat_ctx *rpc_ctx, struct spdk_bdev_desc *desc)
struct spdk_bdev_desc *desc)
{ {
struct spdk_bdev *bdev; struct spdk_bdev *bdev;
ctx->w = spdk_jsonrpc_begin_result(ctx->request); rpc_ctx->w = spdk_jsonrpc_begin_result(rpc_ctx->request);
spdk_json_write_object_begin(ctx->w); spdk_json_write_object_begin(rpc_ctx->w);
spdk_json_write_named_uint64(ctx->w, "tick_rate", spdk_get_ticks_hz()); spdk_json_write_named_uint64(rpc_ctx->w, "tick_rate", spdk_get_ticks_hz());
spdk_json_write_named_uint64(ctx->w, "ticks", spdk_get_ticks()); spdk_json_write_named_uint64(rpc_ctx->w, "ticks", spdk_get_ticks());
if (ctx->per_channel == false) { if (rpc_ctx->per_channel == false) {
spdk_json_write_named_array_begin(ctx->w, "bdevs"); spdk_json_write_named_array_begin(rpc_ctx->w, "bdevs");
} else { } else {
bdev = spdk_bdev_desc_get_bdev(desc); bdev = spdk_bdev_desc_get_bdev(desc);
spdk_json_write_named_string(ctx->w, "name", spdk_bdev_get_name(bdev)); spdk_json_write_named_string(rpc_ctx->w, "name", spdk_bdev_get_name(bdev));
spdk_json_write_named_array_begin(ctx->w, "channels"); spdk_json_write_named_array_begin(rpc_ctx->w, "channels");
} }
} }
static void static void
rpc_bdev_get_iostat_done(struct rpc_bdev_get_iostat_ctx *ctx) rpc_get_iostat_done(struct rpc_get_iostat_ctx *rpc_ctx)
{ {
if (--ctx->bdev_count != 0) { if (--rpc_ctx->bdev_count != 0) {
return; return;
} }
if (ctx->rc == 0) { if (rpc_ctx->rc == 0) {
spdk_json_write_array_end(ctx->w); spdk_json_write_array_end(rpc_ctx->w);
spdk_json_write_object_end(ctx->w); spdk_json_write_object_end(rpc_ctx->w);
spdk_jsonrpc_end_result(ctx->request, ctx->w); spdk_jsonrpc_end_result(rpc_ctx->request, rpc_ctx->w);
} else { } else {
/* Return error response after processing all specified bdevs /* Return error response after processing all specified bdevs
* completed or failed. * completed or failed.
*/ */
spdk_jsonrpc_send_error_response(ctx->request, ctx->rc, spdk_jsonrpc_send_error_response(rpc_ctx->request, rpc_ctx->rc,
spdk_strerror(-ctx->rc)); spdk_strerror(-rpc_ctx->rc));
} }
free(ctx); free(rpc_ctx);
} }
static void static void
rpc_bdev_get_iostat_dump(struct spdk_json_write_ctx *w, bdev_get_iostat_dump(struct spdk_json_write_ctx *w, struct spdk_bdev_io_stat *stat)
struct spdk_bdev_io_stat *stat)
{ {
spdk_json_write_named_uint64(w, "bytes_read", stat->bytes_read); spdk_json_write_named_uint64(w, "bytes_read", stat->bytes_read);
spdk_json_write_named_uint64(w, "num_read_ops", stat->num_read_ops); spdk_json_write_named_uint64(w, "num_read_ops", stat->num_read_ops);
@ -234,27 +232,27 @@ rpc_bdev_get_iostat_dump(struct spdk_json_write_ctx *w,
} }
static void static void
rpc_bdev_get_iostat_cb(struct spdk_bdev *bdev, bdev_get_iostat_done(struct spdk_bdev *bdev, struct spdk_bdev_io_stat *stat,
struct spdk_bdev_io_stat *stat, void *cb_arg, int rc) void *cb_arg, int rc)
{ {
struct rpc_bdev_iostat *_stat = cb_arg; struct bdev_get_iostat_ctx *bdev_ctx = cb_arg;
struct rpc_bdev_get_iostat_ctx *ctx = _stat->ctx; struct rpc_get_iostat_ctx *rpc_ctx = bdev_ctx->rpc_ctx;
struct spdk_json_write_ctx *w = ctx->w; struct spdk_json_write_ctx *w = rpc_ctx->w;
if (rc != 0 || ctx->rc != 0) { if (rc != 0 || rpc_ctx->rc != 0) {
if (ctx->rc == 0) { if (rpc_ctx->rc == 0) {
ctx->rc = rc; rpc_ctx->rc = rc;
} }
goto done; goto done;
} }
assert(stat == &_stat->stat); assert(stat == &bdev_ctx->stat);
spdk_json_write_object_begin(w); spdk_json_write_object_begin(w);
spdk_json_write_named_string(w, "name", spdk_bdev_get_name(bdev)); spdk_json_write_named_string(w, "name", spdk_bdev_get_name(bdev));
rpc_bdev_get_iostat_dump(w, stat); bdev_get_iostat_dump(w, stat);
if (spdk_bdev_get_qd_sampling_period(bdev)) { if (spdk_bdev_get_qd_sampling_period(bdev)) {
spdk_json_write_named_uint64(w, "queue_depth_polling_period", spdk_json_write_named_uint64(w, "queue_depth_polling_period",
@ -271,64 +269,65 @@ rpc_bdev_get_iostat_cb(struct spdk_bdev *bdev,
spdk_json_write_object_end(w); spdk_json_write_object_end(w);
done: done:
rpc_bdev_get_iostat_done(ctx); rpc_get_iostat_done(rpc_ctx);
spdk_bdev_close(_stat->desc); spdk_bdev_close(bdev_ctx->desc);
free(_stat); free(bdev_ctx);
} }
static int static int
_bdev_get_device_stat(void *_ctx, struct spdk_bdev *bdev) bdev_get_iostat(void *ctx, struct spdk_bdev *bdev)
{ {
struct rpc_bdev_get_iostat_ctx *ctx = _ctx; struct rpc_get_iostat_ctx *rpc_ctx = ctx;
struct rpc_bdev_iostat *_stat; struct bdev_get_iostat_ctx *bdev_ctx;
int rc; int rc;
_stat = calloc(1, sizeof(struct rpc_bdev_iostat)); bdev_ctx = calloc(1, sizeof(struct bdev_get_iostat_ctx));
if (_stat == NULL) { if (bdev_ctx == NULL) {
SPDK_ERRLOG("Failed to allocate rpc_bdev_iostat struct\n"); SPDK_ERRLOG("Failed to allocate bdev_iostat_ctx struct\n");
return -ENOMEM; return -ENOMEM;
} }
rc = spdk_bdev_open_ext(spdk_bdev_get_name(bdev), false, dummy_bdev_event_cb, NULL, &_stat->desc); rc = spdk_bdev_open_ext(spdk_bdev_get_name(bdev), false, dummy_bdev_event_cb, NULL,
&bdev_ctx->desc);
if (rc != 0) { if (rc != 0) {
free(_stat); free(bdev_ctx);
SPDK_ERRLOG("Failed to open bdev\n"); SPDK_ERRLOG("Failed to open bdev\n");
return rc; return rc;
} }
ctx->bdev_count++; rpc_ctx->bdev_count++;
_stat->ctx = ctx; bdev_ctx->rpc_ctx = rpc_ctx;
spdk_bdev_get_device_stat(bdev, &_stat->stat, rpc_bdev_get_iostat_cb, _stat); spdk_bdev_get_device_stat(bdev, &bdev_ctx->stat, bdev_get_iostat_done, bdev_ctx);
return 0; return 0;
} }
static void static void
rpc_bdev_get_per_channel_stat_done(struct spdk_bdev *bdev, void *ctx, int status) bdev_get_per_channel_stat_done(struct spdk_bdev *bdev, void *ctx, int status)
{ {
struct rpc_bdev_iostat *_stat = ctx; struct bdev_get_iostat_ctx *bdev_ctx = ctx;
rpc_bdev_get_iostat_done(_stat->ctx); rpc_get_iostat_done(bdev_ctx->rpc_ctx);
spdk_bdev_close(_stat->desc); spdk_bdev_close(bdev_ctx->desc);
free(_stat); free(bdev_ctx);
} }
static void static void
rpc_bdev_get_per_channel_stat(struct spdk_bdev_channel_iter *i, struct spdk_bdev *bdev, bdev_get_per_channel_stat(struct spdk_bdev_channel_iter *i, struct spdk_bdev *bdev,
struct spdk_io_channel *ch, void *ctx) struct spdk_io_channel *ch, void *ctx)
{ {
struct rpc_bdev_iostat *_stat = ctx; struct bdev_get_iostat_ctx *bdev_ctx = ctx;
struct spdk_json_write_ctx *w = _stat->ctx->w; struct spdk_json_write_ctx *w = bdev_ctx->rpc_ctx->w;
struct spdk_bdev_io_stat stat; struct spdk_bdev_io_stat stat;
spdk_bdev_get_io_stat(bdev, ch, &stat); spdk_bdev_get_io_stat(bdev, ch, &stat);
spdk_json_write_object_begin(w); spdk_json_write_object_begin(w);
spdk_json_write_named_uint64(w, "thread_id", spdk_thread_get_id(spdk_get_thread())); spdk_json_write_named_uint64(w, "thread_id", spdk_thread_get_id(spdk_get_thread()));
rpc_bdev_get_iostat_dump(w, &stat); bdev_get_iostat_dump(w, &stat);
spdk_json_write_object_end(w); spdk_json_write_object_end(w);
spdk_bdev_for_each_channel_continue(i, 0); spdk_bdev_for_each_channel_continue(i, 0);
@ -356,8 +355,8 @@ rpc_bdev_get_iostat(struct spdk_jsonrpc_request *request,
{ {
struct rpc_bdev_get_iostat req = {}; struct rpc_bdev_get_iostat req = {};
struct spdk_bdev_desc *desc = NULL; struct spdk_bdev_desc *desc = NULL;
struct rpc_bdev_get_iostat_ctx *ctx; struct rpc_get_iostat_ctx *rpc_ctx;
struct rpc_bdev_iostat *_stat; struct bdev_get_iostat_ctx *bdev_ctx;
int rc; int rc;
if (params != NULL) { if (params != NULL) {
@ -391,9 +390,9 @@ rpc_bdev_get_iostat(struct spdk_jsonrpc_request *request,
free_rpc_bdev_get_iostat(&req); free_rpc_bdev_get_iostat(&req);
ctx = calloc(1, sizeof(struct rpc_bdev_get_iostat_ctx)); rpc_ctx = calloc(1, sizeof(struct rpc_get_iostat_ctx));
if (ctx == NULL) { if (rpc_ctx == NULL) {
SPDK_ERRLOG("Failed to allocate rpc_bdev_get_iostat_ctx struct\n"); SPDK_ERRLOG("Failed to allocate rpc_iostat_ctx struct\n");
spdk_jsonrpc_send_error_response(request, -ENOMEM, spdk_strerror(ENOMEM)); spdk_jsonrpc_send_error_response(request, -ENOMEM, spdk_strerror(ENOMEM));
return; return;
} }
@ -402,49 +401,49 @@ rpc_bdev_get_iostat(struct spdk_jsonrpc_request *request,
* Increment initial bdev_count so that it will never reach 0 in the middle * Increment initial bdev_count so that it will never reach 0 in the middle
* of iterating. * of iterating.
*/ */
ctx->bdev_count++; rpc_ctx->bdev_count++;
ctx->request = request; rpc_ctx->request = request;
ctx->per_channel = req.per_channel; rpc_ctx->per_channel = req.per_channel;
if (desc != NULL) { if (desc != NULL) {
_stat = calloc(1, sizeof(struct rpc_bdev_iostat)); bdev_ctx = calloc(1, sizeof(struct bdev_get_iostat_ctx));
if (_stat == NULL) { if (bdev_ctx == NULL) {
SPDK_ERRLOG("Failed to allocate rpc_bdev_iostat struct\n"); SPDK_ERRLOG("Failed to allocate bdev_iostat_ctx struct\n");
ctx->rc = -ENOMEM; rpc_ctx->rc = -ENOMEM;
spdk_bdev_close(desc); spdk_bdev_close(desc);
} else { } else {
_stat->desc = desc; bdev_ctx->desc = desc;
ctx->bdev_count++; rpc_ctx->bdev_count++;
_stat->ctx = ctx; bdev_ctx->rpc_ctx = rpc_ctx;
if (req.per_channel == false) { if (req.per_channel == false) {
spdk_bdev_get_device_stat(spdk_bdev_desc_get_bdev(desc), &_stat->stat, spdk_bdev_get_device_stat(spdk_bdev_desc_get_bdev(desc), &bdev_ctx->stat,
rpc_bdev_get_iostat_cb, _stat); bdev_get_iostat_done, bdev_ctx);
} else { } else {
spdk_bdev_for_each_channel(spdk_bdev_desc_get_bdev(desc), spdk_bdev_for_each_channel(spdk_bdev_desc_get_bdev(desc),
rpc_bdev_get_per_channel_stat, bdev_get_per_channel_stat,
_stat, bdev_ctx,
rpc_bdev_get_per_channel_stat_done); bdev_get_per_channel_stat_done);
} }
} }
} else { } else {
rc = spdk_for_each_bdev(ctx, _bdev_get_device_stat); rc = spdk_for_each_bdev(rpc_ctx, bdev_get_iostat);
if (rc != 0 && ctx->rc == 0) { if (rc != 0 && rpc_ctx->rc == 0) {
ctx->rc = rc; rpc_ctx->rc = rc;
} }
} }
if (ctx->rc == 0) { if (rpc_ctx->rc == 0) {
/* We want to fail the RPC for all failures. The callback function to /* We want to fail the RPC for all failures. The callback function to
* spdk_bdev_for_each_channel() is executed after stack unwinding if * spdk_bdev_for_each_channel() is executed after stack unwinding if
* successful. Hence defer starting RPC response until it is ensured that * successful. Hence defer starting RPC response until it is ensured that
* all spdk_bdev_for_each_channel() calls will succeed or there is no bdev. * all spdk_bdev_for_each_channel() calls will succeed or there is no bdev.
*/ */
rpc_bdev_get_iostat_started(ctx, desc); rpc_get_iostat_started(rpc_ctx, desc);
} }
rpc_bdev_get_iostat_done(ctx); rpc_get_iostat_done(rpc_ctx);
} }
SPDK_RPC_REGISTER("bdev_get_iostat", rpc_bdev_get_iostat, SPDK_RPC_RUNTIME) SPDK_RPC_REGISTER("bdev_get_iostat", rpc_bdev_get_iostat, SPDK_RPC_RUNTIME)