diff --git a/CHANGELOG.md b/CHANGELOG.md index 90c3daa04..c3997e508 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## v20.04: (Upcoming Release) +### ocf + +Update OCF submodule to OCF v20.03 + +New version of OCF comes with API changes and bug fixes + ### nvme Export internal nvme_ctrlr_cmd_security_receive/send() APIs as public APIs with "spdk_" diff --git a/lib/env_ocf/ocf_env.c b/lib/env_ocf/ocf_env.c index 0eaed98ba..ab5445203 100644 --- a/lib/env_ocf/ocf_env.c +++ b/lib/env_ocf/ocf_env.c @@ -115,3 +115,62 @@ env_crc32(uint32_t crc, uint8_t const *message, size_t len) { return spdk_crc32_ieee_update(message, len, crc); } + +/* EXECUTION CONTEXTS */ +pthread_mutex_t *exec_context_mutex; + +static void __attribute__((constructor)) init_execution_context(void) +{ + unsigned count = env_get_execution_context_count(); + unsigned i; + + ENV_BUG_ON(count == 0); + exec_context_mutex = malloc(count * sizeof(exec_context_mutex[0])); + ENV_BUG_ON(exec_context_mutex == NULL); + for (i = 0; i < count; i++) { + ENV_BUG_ON(pthread_mutex_init(&exec_context_mutex[i], NULL)); + } +} + +static void __attribute__((destructor)) deinit_execution_context(void) +{ + unsigned count = env_get_execution_context_count(); + unsigned i; + + ENV_BUG_ON(count == 0); + ENV_BUG_ON(exec_context_mutex == NULL); + + for (i = 0; i < count; i++) { + ENV_BUG_ON(pthread_mutex_destroy(&exec_context_mutex[i])); + } + free(exec_context_mutex); +} + +/* get_execuction_context must assure that after the call finishes, the caller + * will not get preempted from current execution context. For userspace env + * we simulate this behavior by acquiring per execution context mutex. As a + * result the caller might actually get preempted, but no other thread will + * execute in this context by the time the caller puts current execution ctx. */ +unsigned env_get_execution_context(void) +{ + unsigned cpu; + + cpu = sched_getcpu(); + cpu = (cpu == -1) ? 0 : cpu; + + ENV_BUG_ON(pthread_mutex_lock(&exec_context_mutex[cpu])); + + return cpu; +} + +void env_put_execution_context(unsigned ctx) +{ + pthread_mutex_unlock(&exec_context_mutex[ctx]); +} + +unsigned env_get_execution_context_count(void) +{ + int num = sysconf(_SC_NPROCESSORS_ONLN); + + return (num == -1) ? 0 : num; +} diff --git a/lib/env_ocf/ocf_env.h b/lib/env_ocf/ocf_env.h index 1ba76ea93..0b6ecb7a0 100644 --- a/lib/env_ocf/ocf_env.h +++ b/lib/env_ocf/ocf_env.h @@ -112,6 +112,9 @@ typedef uint64_t sector_t; } \ }) +#define ENV_BUILD_BUG_ON(cond) _Static_assert(!(cond), "static "\ + "assertion failure") + #define container_of(ptr, type, member) SPDK_CONTAINEROF(ptr, type, member) static inline void *env_malloc(size_t size, int flags) @@ -145,6 +148,11 @@ static inline void *env_vzalloc(size_t size) SPDK_MALLOC_DMA); } +static inline void *env_vzalloc_flags(size_t size, int flags) +{ + return env_vzalloc(size); +} + static inline void *env_secure_alloc(size_t size) { return spdk_zmalloc(size, 0, NULL, SPDK_ENV_LCORE_ID_ANY, @@ -228,6 +236,15 @@ static inline int env_mutex_is_locked(env_mutex *mutex) return 1; } +static inline int env_mutex_destroy(env_mutex *mutex) +{ + if (pthread_mutex_destroy(&mutex->m)) { + return 1; + } + + return 0; +} + /* *** RECURSIVE MUTEX *** */ typedef env_mutex env_rmutex; @@ -268,6 +285,11 @@ static inline int env_rmutex_is_locked(env_rmutex *rmutex) return env_mutex_is_locked(rmutex); } +static inline int env_rmutex_destroy(env_rmutex *rmutex) +{ + return env_mutex_destroy(rmutex); +} + /* *** RW SEMAPHORE *** */ typedef struct { pthread_rwlock_t lock; @@ -327,6 +349,11 @@ static inline int env_rwsem_down_write_interruptible(env_rwsem *s) return pthread_rwlock_wrlock(&s->lock); } +static inline int env_rwsem_destroy(env_rwsem *s) +{ + return pthread_rwlock_destroy(&s->lock); +} + /* *** ATOMIC VARIABLES *** */ typedef int env_atomic; @@ -510,6 +537,11 @@ static inline void env_completion_complete(env_completion *completion) sem_post(&completion->sem); } +static inline void env_completion_destroy(env_completion *completion) +{ + sem_destroy(&completion->sem); +} + /* *** SPIN LOCKS *** */ typedef struct { @@ -752,7 +784,7 @@ static inline int env_strncpy(char *dest, size_t dmax, const char *src, size_t l return 0; } -#define env_strncmp strncmp +#define env_strncmp(s1, slen1, s2, slen2) strncmp(s1, s2, min(slen1, slen2)) static inline char *env_strdup(const char *src, int flags) { @@ -795,4 +827,9 @@ static inline void env_touch_softlockup_wd(void) uint32_t env_crc32(uint32_t crc, uint8_t const *data, size_t len); +/* EXECUTION CONTEXTS */ +unsigned env_get_execution_context(void); +void env_put_execution_context(unsigned ctx); +unsigned env_get_execution_context_count(void); + #endif /* __OCF_ENV_H__ */ diff --git a/lib/env_ocf/ocf_env_headers.h b/lib/env_ocf/ocf_env_headers.h index 7fd40256a..742479374 100644 --- a/lib/env_ocf/ocf_env_headers.h +++ b/lib/env_ocf/ocf_env_headers.h @@ -36,8 +36,8 @@ #include "spdk/stdinc.h" -#define OCF_VERSION_MAIN 3 -#define OCF_VERSION_MAJOR 8 +#define OCF_VERSION_MAIN 20 +#define OCF_VERSION_MAJOR 3 #define OCF_VERSION_MINOR 0 #endif /* __OCF_ENV_HEADERS_H__ */ diff --git a/module/bdev/ocf/stats.c b/module/bdev/ocf/stats.c index ac8d3f9fe..164da7d2e 100644 --- a/module/bdev/ocf/stats.c +++ b/module/bdev/ocf/stats.c @@ -35,12 +35,12 @@ #include "stats.h" int -vbdev_ocf_stats_get(ocf_cache_t cache, ocf_core_id_t core_id, struct vbdev_ocf_stats *stats) +vbdev_ocf_stats_get(ocf_cache_t cache, char *core_name, struct vbdev_ocf_stats *stats) { int status; ocf_core_t core; - status = ocf_core_get(cache, core_id, &core); + status = ocf_core_get_by_name(cache, core_name, strlen(core_name), &core); if (status) { return status; } @@ -52,7 +52,7 @@ vbdev_ocf_stats_get(ocf_cache_t cache, ocf_core_id_t core_id, struct vbdev_ocf_s spdk_json_write_named_object_begin(w, #field); \ spdk_json_write_named_uint64(w, "count", stats->group.field.value); \ spdk_json_write_named_string_fmt(w, "percentage", "%lu.%lu", \ - stats->group.field.percent / 10, stats->group.field.percent % 10); \ + stats->group.field.fraction / 100, stats->group.field.fraction % 100); \ spdk_json_write_named_string(w, "units", units); \ spdk_json_write_object_end(w); diff --git a/module/bdev/ocf/stats.h b/module/bdev/ocf/stats.h index f7bf8c448..b377c67f5 100644 --- a/module/bdev/ocf/stats.h +++ b/module/bdev/ocf/stats.h @@ -44,7 +44,7 @@ struct vbdev_ocf_stats { struct ocf_stats_errors errors; }; -int vbdev_ocf_stats_get(ocf_cache_t cache, ocf_core_id_t core_id, struct vbdev_ocf_stats *stats); +int vbdev_ocf_stats_get(ocf_cache_t cache, char *core_name, struct vbdev_ocf_stats *stats); void vbdev_ocf_stats_write_json(struct spdk_json_write_ctx *w, struct vbdev_ocf_stats *stats); diff --git a/module/bdev/ocf/vbdev_ocf.c b/module/bdev/ocf/vbdev_ocf.c index c347fac20..cecad0274 100644 --- a/module/bdev/ocf/vbdev_ocf.c +++ b/module/bdev/ocf/vbdev_ocf.c @@ -563,26 +563,15 @@ vbdev_ocf_io_submit_cb(struct ocf_io *io, int error) static int io_submit_to_ocf(struct spdk_bdev_io *bdev_io, struct ocf_io *io) { - int dir; - uint64_t len = bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen; - uint64_t offset = bdev_io->u.bdev.offset_blocks * bdev_io->bdev->blocklen; - switch (bdev_io->type) { case SPDK_BDEV_IO_TYPE_WRITE: case SPDK_BDEV_IO_TYPE_READ: - dir = OCF_READ; - if (bdev_io->type == SPDK_BDEV_IO_TYPE_WRITE) { - dir = OCF_WRITE; - } - ocf_io_configure(io, offset, len, dir, 0, 0); ocf_core_submit_io(io); return 0; case SPDK_BDEV_IO_TYPE_FLUSH: - ocf_io_configure(io, offset, len, OCF_WRITE, 0, OCF_WRITE_FLUSH); ocf_core_submit_flush(io); return 0; case SPDK_BDEV_IO_TYPE_UNMAP: - ocf_io_configure(io, offset, len, 0, 0, 0); ocf_core_submit_discard(io); return 0; case SPDK_BDEV_IO_TYPE_RESET: @@ -601,16 +590,39 @@ io_handle(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io) struct ocf_io *io = NULL; struct bdev_ocf_data *data = NULL; struct vbdev_ocf_qcxt *qctx = spdk_io_channel_get_ctx(ch); + uint64_t len = bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen; + uint64_t offset = bdev_io->u.bdev.offset_blocks * bdev_io->bdev->blocklen; + int dir, flags = 0; int err; - io = ocf_core_new_io(vbdev->ocf_core); + switch (bdev_io->type) { + case SPDK_BDEV_IO_TYPE_READ: + dir = OCF_READ; + break; + case SPDK_BDEV_IO_TYPE_WRITE: + dir = OCF_WRITE; + break; + case SPDK_BDEV_IO_TYPE_FLUSH: + dir = OCF_WRITE; + break; + case SPDK_BDEV_IO_TYPE_UNMAP: + dir = OCF_WRITE; + break; + default: + err = -EINVAL; + goto fail; + } + + if (bdev_io->type == SPDK_BDEV_IO_TYPE_FLUSH) { + flags = OCF_WRITE_FLUSH; + } + + io = ocf_core_new_io(vbdev->ocf_core, qctx->queue, offset, len, dir, 0, flags); if (!io) { err = -ENOMEM; goto fail; } - ocf_io_set_queue(io, qctx->queue); - data = vbdev_ocf_data_from_spdk_io(bdev_io); if (!data) { err = -ENOMEM; @@ -955,7 +967,6 @@ add_core_cmpl(ocf_cache_t cache, ocf_core_t core, void *priv, int error) return; } else { vbdev->ocf_core = core; - vbdev->core.id = ocf_core_get_id(core); } vbdev_ocf_mngt_continue(vbdev, error); @@ -1042,7 +1053,6 @@ start_cache(struct vbdev_ocf *vbdev) SPDK_NOTICELOG("OCF bdev %s connects to existing cache device %s\n", vbdev->name, vbdev->cache.name); vbdev->ocf_cache = existing; - vbdev->cache.id = ocf_cache_get_id(existing); vbdev->cache_ctx = ocf_cache_get_priv(existing); vbdev_ocf_cache_ctx_get(vbdev->cache_ctx); vbdev_ocf_mngt_continue(vbdev, 0); @@ -1066,7 +1076,6 @@ start_cache(struct vbdev_ocf *vbdev) return; } - vbdev->cache.id = ocf_cache_get_id(vbdev->ocf_cache); ocf_cache_set_priv(vbdev->ocf_cache, vbdev->cache_ctx); rc = create_management_queue(vbdev); @@ -1117,9 +1126,8 @@ init_vbdev_config(struct vbdev_ocf *vbdev) { struct vbdev_ocf_config *cfg = &vbdev->cfg; - /* Id 0 means OCF decides the id */ - cfg->cache.id = 0; - cfg->cache.name = vbdev->name; + snprintf(cfg->cache.name, sizeof(cfg->cache.name), "%s", vbdev->name); + snprintf(cfg->core.name, sizeof(cfg->core.name), "%s", vbdev->core.name); /* TODO [metadata]: make configurable with persistent * metadata support */ @@ -1144,7 +1152,6 @@ init_vbdev_config(struct vbdev_ocf *vbdev) cfg->core.volume_type = SPDK_OBJECT; cfg->device.volume_type = SPDK_OBJECT; - cfg->core.core_id = OCF_CORE_MAX; if (vbdev->cfg.loadq) { /* When doing cache_load(), we need to set try_add to true, diff --git a/module/bdev/ocf/vbdev_ocf.h b/module/bdev/ocf/vbdev_ocf.h index c7f60b8a2..ffa1a0e63 100644 --- a/module/bdev/ocf/vbdev_ocf.h +++ b/module/bdev/ocf/vbdev_ocf.h @@ -122,9 +122,6 @@ struct vbdev_ocf_mngt_ctx { /* Base device info */ struct vbdev_ocf_base { - /* OCF unique internal id */ - int id; - /* OCF internal name */ char *name; diff --git a/module/bdev/ocf/vbdev_ocf_rpc.c b/module/bdev/ocf/vbdev_ocf_rpc.c index 1b9746045..6756d026f 100644 --- a/module/bdev/ocf/vbdev_ocf_rpc.c +++ b/module/bdev/ocf/vbdev_ocf_rpc.c @@ -192,7 +192,7 @@ static const struct spdk_json_object_decoder rpc_bdev_ocf_get_stats_decoders[] = struct get_ocf_stats_ctx { struct spdk_jsonrpc_request *request; - int core_id; + char *core_name; }; static void @@ -206,7 +206,7 @@ spdk_rpc_bdev_ocf_get_stats_cmpl(ocf_cache_t cache, void *priv, int error) goto end; } - error = vbdev_ocf_stats_get(cache, ctx->core_id, &stats); + error = vbdev_ocf_stats_get(cache, ctx->core_name, &stats); ocf_mngt_cache_read_unlock(cache); @@ -259,7 +259,7 @@ spdk_rpc_bdev_ocf_get_stats(struct spdk_jsonrpc_request *request, goto end; } - ctx->core_id = vbdev->core.id; + ctx->core_name = vbdev->core.name; ctx->request = request; ocf_mngt_cache_read_lock(vbdev->ocf_cache, spdk_rpc_bdev_ocf_get_stats_cmpl, ctx); diff --git a/module/bdev/ocf/volume.c b/module/bdev/ocf/volume.c index 326c7fd74..dcf9cf541 100644 --- a/module/bdev/ocf/volume.c +++ b/module/bdev/ocf/volume.c @@ -217,7 +217,7 @@ prepare_submit(struct ocf_io *io) } vbdev_ocf_volume_io_get(io); - base = *((struct vbdev_ocf_base **)ocf_volume_get_priv(io->volume)); + base = *((struct vbdev_ocf_base **)ocf_volume_get_priv(ocf_io_get_volume(io))); if (io->io_queue == NULL) { /* In case IO is initiated by OCF, queue is unknown @@ -254,7 +254,9 @@ prepare_submit(struct ocf_io *io) static void vbdev_ocf_volume_submit_flush(struct ocf_io *io) { - struct vbdev_ocf_base *base = *((struct vbdev_ocf_base **)ocf_volume_get_priv(io->volume)); + struct vbdev_ocf_base *base = + *((struct vbdev_ocf_base **) + ocf_volume_get_priv(ocf_io_get_volume(io))); struct ocf_io_ctx *io_ctx = ocf_get_io_ctx(io); int status; @@ -279,7 +281,9 @@ vbdev_ocf_volume_submit_flush(struct ocf_io *io) static void vbdev_ocf_volume_submit_io(struct ocf_io *io) { - struct vbdev_ocf_base *base = *((struct vbdev_ocf_base **)ocf_volume_get_priv(io->volume)); + struct vbdev_ocf_base *base = + *((struct vbdev_ocf_base **) + ocf_volume_get_priv(ocf_io_get_volume(io))); struct ocf_io_ctx *io_ctx = ocf_get_io_ctx(io); struct iovec *iovs; int iovcnt, status = 0, i, offset; @@ -363,7 +367,9 @@ end: static void vbdev_ocf_volume_submit_discard(struct ocf_io *io) { - struct vbdev_ocf_base *base = *((struct vbdev_ocf_base **)ocf_volume_get_priv(io->volume)); + struct vbdev_ocf_base *base = + *((struct vbdev_ocf_base **) + ocf_volume_get_priv(ocf_io_get_volume(io))); struct ocf_io_ctx *io_ctx = ocf_get_io_ctx(io); int status = 0; diff --git a/ocf b/ocf index 6fb1a697a..9d0795564 160000 --- a/ocf +++ b/ocf @@ -1 +1 @@ -Subproject commit 6fb1a697a43b54a0d13854a7a3ee07b520a51d87 +Subproject commit 9d0795564082b5dfb489ab3fc2fa22cb1538ab85