From 20894340f23529b2b40894864b375580bafbe0b7 Mon Sep 17 00:00:00 2001 From: Marcin Dziegielewski Date: Mon, 21 Oct 2019 14:58:26 +0200 Subject: [PATCH] lib/bdev/ocf: update of ocf library to version 19.06 This path updates ocf library to version 19.06 and also introduces all necessary changes required to integrate ocf bdev adapter with new version of ocf. Summary of changes introduces with new OCF in ocf bdev: - ocf_env.h increased limit for memory operations, changed behaviour of strncpy to less restrictive, both changes are required to run new OCF - ctx.c changed functions to new from new OCF - added new cache mode "write only" - added missed cache modes wa and wi to RPC scripts - rewritten spdk_rpc_bdev_ocf_get_stats function to use asynhronus ocf_mngt_cache_read_lock - used new asynhronus ocf_mngt_cache_flush instead of waiting for request - removed no longer valid filed - cfg->device.min_free_ram - changed expected result in metadata_probe_cb Signed-off-by: Marcin Dziegielewski Change-Id: I83e4335e16600e4d22e6bb517931102de42d39e9 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/468132 Reviewed-by: Tomasz Zawadzki Reviewed-by: Jim Harris Tested-by: SPDK CI Jenkins --- CHANGELOG.md | 10 ++++++ lib/env_ocf/ocf_env.h | 8 +++-- module/bdev/ocf/ctx.c | 4 +-- module/bdev/ocf/stats.c | 18 +--------- module/bdev/ocf/utils.c | 3 +- module/bdev/ocf/vbdev_ocf.c | 25 ++----------- module/bdev/ocf/vbdev_ocf_rpc.c | 64 +++++++++++++++++++++++++-------- ocf | 2 +- scripts/rpc.py | 2 +- scripts/rpc/bdev.py | 2 +- 10 files changed, 75 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f83d13c2..b084339ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -163,6 +163,16 @@ Added `blobfs_mount` RPC method to mount blobfs on given bdev to a host path by Then on the host path, user can directly do some file operations which will be mapped to blobfs. +### ocf + +Updated OCF submodule to OCF v19.06 + +Along with update, new cache mode 'write only' was added. + +New cache modes added to use via RPC, wi - write invalidate and wa - write around. + +New version of OCF provides fully asynchronous management API. + ## v19.07: ### ftl diff --git a/lib/env_ocf/ocf_env.h b/lib/env_ocf/ocf_env.h index 86dd9ce0d..b8185f6eb 100644 --- a/lib/env_ocf/ocf_env.h +++ b/lib/env_ocf/ocf_env.h @@ -660,8 +660,8 @@ static inline uint64_t env_secs_to_ticks(uint64_t j) /* *** STRING OPERATIONS *** */ -/* 256 KB is sufficient amount of memory for OCF operations */ -#define ENV_MAX_MEM (256 * 1024) +/* 512 KB is sufficient amount of memory for OCF operations */ +#define ENV_MAX_MEM (512 * 1024) static inline int env_memset(void *dest, size_t len, uint8_t value) { @@ -722,9 +722,11 @@ static inline int env_strncpy(char *dest, size_t dmax, const char *src, size_t l if (dmax == 0 || dmax > ENV_MAX_STR) { return 1; } - if (len == 0 || len > dmax) { + if (len == 0) { return 1; } + /* Just copy as many characters as we can instead of return failure */ + len = min(len, dmax); strncpy(dest, src, len); return 0; diff --git a/module/bdev/ocf/ctx.c b/module/bdev/ocf/ctx.c index 3b1ea5af5..a85250d72 100644 --- a/module/bdev/ocf/ctx.c +++ b/module/bdev/ocf/ctx.c @@ -532,7 +532,7 @@ vbdev_ocf_ctx_init(void) { int ret; - ret = ocf_ctx_init(&vbdev_ocf_ctx, &vbdev_ocf_ctx_cfg); + ret = ocf_ctx_create(&vbdev_ocf_ctx, &vbdev_ocf_ctx_cfg); if (ret < 0) { return ret; } @@ -543,7 +543,7 @@ vbdev_ocf_ctx_init(void) void vbdev_ocf_ctx_cleanup(void) { - ocf_ctx_exit(vbdev_ocf_ctx); + ocf_ctx_put(vbdev_ocf_ctx); vbdev_ocf_ctx = NULL; } diff --git a/module/bdev/ocf/stats.c b/module/bdev/ocf/stats.c index 955df7ced..ac8d3f9fe 100644 --- a/module/bdev/ocf/stats.c +++ b/module/bdev/ocf/stats.c @@ -40,28 +40,12 @@ vbdev_ocf_stats_get(ocf_cache_t cache, ocf_core_id_t core_id, struct vbdev_ocf_s int status; ocf_core_t core; - if (cache == NULL) { - assert(false); - return -EFAULT; - } - - status = ocf_mngt_cache_read_lock(cache); - if (status) { - return status; - } - status = ocf_core_get(cache, core_id, &core); if (status) { return status; } - status = ocf_stats_collect_core(core, &stats->usage, &stats->reqs, &stats->blocks, &stats->errors); - ocf_mngt_cache_read_unlock(cache); - if (status) { - return status; - } - - return 0; + return ocf_stats_collect_core(core, &stats->usage, &stats->reqs, &stats->blocks, &stats->errors); } #define WJSON_STAT(w, stats, group, field, units) \ diff --git a/module/bdev/ocf/utils.c b/module/bdev/ocf/utils.c index 581f3b498..fadb82116 100644 --- a/module/bdev/ocf/utils.c +++ b/module/bdev/ocf/utils.c @@ -41,7 +41,8 @@ static char *cache_modes[ocf_cache_mode_max] = { [ocf_cache_mode_wb] = "wb", [ocf_cache_mode_wa] = "wa", [ocf_cache_mode_pt] = "pt", - [ocf_cache_mode_wi] = "wi" + [ocf_cache_mode_wi] = "wi", + [ocf_cache_mode_wo] = "wo", }; ocf_cache_mode_t diff --git a/module/bdev/ocf/vbdev_ocf.c b/module/bdev/ocf/vbdev_ocf.c index cbb84d10c..0e7bce96a 100644 --- a/module/bdev/ocf/vbdev_ocf.c +++ b/module/bdev/ocf/vbdev_ocf.c @@ -289,24 +289,6 @@ stop_vbdev(struct vbdev_ocf *vbdev) vbdev_ocf_mngt_poll(vbdev, stop_vbdev_poll); } -/* Wait for all OCF requests to finish */ -static void -wait_for_requests_poll(struct vbdev_ocf *vbdev) -{ - if (ocf_cache_has_pending_requests(vbdev->ocf_cache)) { - return; - } - - vbdev_ocf_mngt_continue(vbdev, 0); -} - -/* Start waiting for OCF requests to finish */ -static void -wait_for_requests(struct vbdev_ocf *vbdev) -{ - vbdev_ocf_mngt_poll(vbdev, wait_for_requests_poll); -} - static void flush_vbdev_cmpl(ocf_cache_t cache, void *priv, int error) { @@ -329,7 +311,7 @@ flush_vbdev_poll(struct vbdev_ocf *vbdev) } vbdev_ocf_mngt_poll(vbdev, NULL); - ocf_mngt_cache_flush(vbdev->ocf_cache, false, flush_vbdev_cmpl, vbdev); + ocf_mngt_cache_flush(vbdev->ocf_cache, flush_vbdev_cmpl, vbdev); } static void @@ -341,7 +323,6 @@ flush_vbdev(struct vbdev_ocf *vbdev) /* Procedures called during dirty unregister */ vbdev_ocf_mngt_fn unregister_path_dirty[] = { flush_vbdev, - wait_for_requests, stop_vbdev, detach_cache, close_cache_bdev, @@ -354,7 +335,6 @@ vbdev_ocf_mngt_fn unregister_path_dirty[] = { /* Procedures called during clean unregister */ vbdev_ocf_mngt_fn unregister_path_clean[] = { flush_vbdev, - wait_for_requests, detach_core, close_core_bdev, stop_vbdev, @@ -1113,7 +1093,6 @@ init_vbdev_config(struct vbdev_ocf *vbdev) /* TODO [cache line size] */ cfg->device.cache_line_size = ocf_cache_line_size_4; cfg->device.force = true; - cfg->device.min_free_ram = 0; cfg->device.perform_test = false; cfg->device.discard_on_start = false; @@ -1592,7 +1571,7 @@ metadata_probe_cb(void *priv, int rc, if (rc) { /* -ENODATA means device does not have cache metadata on it */ - if (rc != -ENODATA) { + if (rc != -OCF_ERR_NO_METADATA) { ctx->result = rc; } examine_ctx_put(ctx); diff --git a/module/bdev/ocf/vbdev_ocf_rpc.c b/module/bdev/ocf/vbdev_ocf_rpc.c index 5a1325062..1b9746045 100644 --- a/module/bdev/ocf/vbdev_ocf_rpc.c +++ b/module/bdev/ocf/vbdev_ocf_rpc.c @@ -190,21 +190,64 @@ static const struct spdk_json_object_decoder rpc_bdev_ocf_get_stats_decoders[] = {"name", offsetof(struct rpc_bdev_ocf_get_stats, name), spdk_json_decode_string}, }; +struct get_ocf_stats_ctx { + struct spdk_jsonrpc_request *request; + int core_id; +}; + +static void +spdk_rpc_bdev_ocf_get_stats_cmpl(ocf_cache_t cache, void *priv, int error) +{ + struct get_ocf_stats_ctx *ctx = (struct get_ocf_stats_ctx *) priv; + struct spdk_json_write_ctx *w; + struct vbdev_ocf_stats stats; + + if (error) { + goto end; + } + + error = vbdev_ocf_stats_get(cache, ctx->core_id, &stats); + + ocf_mngt_cache_read_unlock(cache); + + if (error) { + goto end; + } + + w = spdk_jsonrpc_begin_result(ctx->request); + vbdev_ocf_stats_write_json(w, &stats); + spdk_jsonrpc_end_result(ctx->request, w); + +end: + if (error) { + spdk_jsonrpc_send_error_response_fmt(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, + "Could not get stats: %s", + spdk_strerror(-error)); + } + free(ctx); +} + static void spdk_rpc_bdev_ocf_get_stats(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params) { struct rpc_bdev_ocf_get_stats req = {NULL}; - struct spdk_json_write_ctx *w; struct vbdev_ocf *vbdev; - struct vbdev_ocf_stats stats; - int status; + struct get_ocf_stats_ctx *ctx; + + ctx = calloc(1, sizeof(*ctx)); + if (!ctx) { + spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, + "Not enough memory to process request"); + goto end; + } if (spdk_json_decode_object(params, rpc_bdev_ocf_get_stats_decoders, SPDK_COUNTOF(rpc_bdev_ocf_get_stats_decoders), &req)) { spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters"); + free(ctx); goto end; } @@ -212,20 +255,13 @@ spdk_rpc_bdev_ocf_get_stats(struct spdk_jsonrpc_request *request, if (vbdev == NULL) { spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, spdk_strerror(ENODEV)); + free(ctx); goto end; } - status = vbdev_ocf_stats_get(vbdev->ocf_cache, vbdev->core.id, &stats); - if (status) { - spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, - "Could not get stats: %s", - spdk_strerror(-status)); - goto end; - } - - w = spdk_jsonrpc_begin_result(request); - vbdev_ocf_stats_write_json(w, &stats); - spdk_jsonrpc_end_result(request, w); + ctx->core_id = vbdev->core.id; + ctx->request = request; + ocf_mngt_cache_read_lock(vbdev->ocf_cache, spdk_rpc_bdev_ocf_get_stats_cmpl, ctx); end: free_rpc_bdev_ocf_get_stats(&req); diff --git a/ocf b/ocf index 515137f25..6fb1a697a 160000 --- a/ocf +++ b/ocf @@ -1 +1 @@ -Subproject commit 515137f25ec71dca0c268fbd1437dd7d177e4f8d +Subproject commit 6fb1a697a43b54a0d13854a7a3ee07b520a51d87 diff --git a/scripts/rpc.py b/scripts/rpc.py index 812d89e8e..3bcf2fc8d 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -214,7 +214,7 @@ if __name__ == "__main__": p = subparsers.add_parser('bdev_ocf_create', aliases=['construct_ocf_bdev'], help='Add an OCF block device') p.add_argument('name', help='Name of resulting OCF bdev') - p.add_argument('mode', help='OCF cache mode', choices=['wb', 'wt', 'pt']) + p.add_argument('mode', help='OCF cache mode', choices=['wb', 'wt', 'pt', 'wa', 'wi', 'wo']) p.add_argument('cache_bdev_name', help='Name of underlying cache bdev') p.add_argument('core_bdev_name', help='Name of unerlying core bdev') p.set_defaults(func=bdev_ocf_create) diff --git a/scripts/rpc/bdev.py b/scripts/rpc/bdev.py index 0fa270da7..a60d3dead 100644 --- a/scripts/rpc/bdev.py +++ b/scripts/rpc/bdev.py @@ -107,7 +107,7 @@ def bdev_ocf_create(client, name, mode, cache_bdev_name, core_bdev_name): Args: name: name of constructed OCF bdev - mode: OCF cache mode: {'wb', 'wt', 'pt'} + mode: OCF cache mode: {'wb', 'wt', 'pt', 'wa', 'wi', 'wo'} cache_bdev_name: name of underlying cache bdev core_bdev_name: name of underlying core bdev