LCOV - code coverage report
Current view: top level - module/bdev/ocf - ctx.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 0 204 0.0 %
Date: 2024-11-05 10:06:02 Functions: 0 25 0.0 %

          Line data    Source code
       1             : /*   SPDX-License-Identifier: BSD-3-Clause
       2             :  *   Copyright (C) 2018 Intel Corporation.
       3             :  *   All rights reserved.
       4             :  */
       5             : 
       6             : #include <ocf/ocf.h>
       7             : #ifdef SPDK_HAVE_EXECINFO_H
       8             : #include <execinfo.h>
       9             : #endif
      10             : 
      11             : #include "spdk/env.h"
      12             : #include "spdk/log.h"
      13             : 
      14             : #include "ctx.h"
      15             : #include "data.h"
      16             : 
      17             : ocf_ctx_t vbdev_ocf_ctx;
      18             : 
      19             : static ctx_data_t *
      20           0 : vbdev_ocf_ctx_data_alloc(uint32_t pages)
      21             : {
      22             :         struct bdev_ocf_data *data;
      23             :         void *buf;
      24             :         uint32_t sz;
      25             : 
      26           0 :         data = vbdev_ocf_data_alloc(1);
      27           0 :         if (data == NULL) {
      28           0 :                 return NULL;
      29             :         }
      30             : 
      31           0 :         sz = pages * PAGE_SIZE;
      32           0 :         buf = spdk_malloc(sz, PAGE_SIZE, NULL,
      33             :                           SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
      34           0 :         if (buf == NULL) {
      35           0 :                 vbdev_ocf_data_free(data);
      36           0 :                 return NULL;
      37             :         }
      38             : 
      39           0 :         vbdev_ocf_iovs_add(data, buf, sz);
      40             : 
      41           0 :         data->size = sz;
      42             : 
      43           0 :         return data;
      44             : }
      45             : 
      46             : static void
      47           0 : vbdev_ocf_ctx_data_free(ctx_data_t *ctx_data)
      48             : {
      49           0 :         struct bdev_ocf_data *data = ctx_data;
      50             :         int i;
      51             : 
      52           0 :         if (!data) {
      53           0 :                 return;
      54             :         }
      55             : 
      56           0 :         for (i = 0; i < data->iovcnt; i++) {
      57           0 :                 spdk_free(data->iovs[i].iov_base);
      58             :         }
      59             : 
      60           0 :         vbdev_ocf_data_free(data);
      61             : }
      62             : 
      63             : static int
      64           0 : vbdev_ocf_ctx_data_mlock(ctx_data_t *ctx_data)
      65             : {
      66             :         /* TODO [mlock]: add mlock option */
      67           0 :         return 0;
      68             : }
      69             : 
      70             : static void
      71           0 : vbdev_ocf_ctx_data_munlock(ctx_data_t *ctx_data)
      72             : {
      73             :         /* TODO [mlock]: add mlock option */
      74           0 : }
      75             : 
      76             : static size_t
      77           0 : iovec_flatten(struct iovec *iov, size_t iovcnt, void *buf, size_t size, size_t offset)
      78             : {
      79           0 :         size_t i, len, done = 0;
      80             : 
      81           0 :         for (i = 0; i < iovcnt; i++) {
      82           0 :                 if (offset >= iov[i].iov_len) {
      83           0 :                         offset -= iov[i].iov_len;
      84           0 :                         continue;
      85             :                 }
      86             : 
      87           0 :                 if (iov[i].iov_base == NULL) {
      88           0 :                         continue;
      89             :                 }
      90             : 
      91           0 :                 if (done >= size) {
      92           0 :                         break;
      93             :                 }
      94             : 
      95           0 :                 len = MIN(size - done, iov[i].iov_len - offset);
      96           0 :                 memcpy(buf, iov[i].iov_base + offset, len);
      97           0 :                 buf += len;
      98           0 :                 done += len;
      99           0 :                 offset = 0;
     100             :         }
     101             : 
     102           0 :         return done;
     103             : }
     104             : 
     105             : static uint32_t
     106           0 : vbdev_ocf_ctx_data_rd(void *dst, ctx_data_t *src, uint32_t size)
     107             : {
     108           0 :         struct bdev_ocf_data *s = src;
     109             :         uint32_t size_local;
     110             : 
     111           0 :         size_local = iovec_flatten(s->iovs, s->iovcnt, dst, size, s->seek);
     112           0 :         s->seek += size_local;
     113             : 
     114           0 :         return size_local;
     115             : }
     116             : 
     117             : static size_t
     118           0 : buf_to_iovec(const void *buf, size_t size, struct iovec *iov, size_t iovcnt, size_t offset)
     119             : {
     120           0 :         size_t i, len, done = 0;
     121             : 
     122           0 :         for (i = 0; i < iovcnt; i++) {
     123           0 :                 if (offset >= iov[i].iov_len) {
     124           0 :                         offset -= iov[i].iov_len;
     125           0 :                         continue;
     126             :                 }
     127             : 
     128           0 :                 if (iov[i].iov_base == NULL) {
     129           0 :                         continue;
     130             :                 }
     131             : 
     132           0 :                 if (done >= size) {
     133           0 :                         break;
     134             :                 }
     135             : 
     136           0 :                 len = MIN(size - done, iov[i].iov_len - offset);
     137           0 :                 memcpy(iov[i].iov_base + offset, buf, len);
     138           0 :                 buf += len;
     139           0 :                 done += len;
     140           0 :                 offset = 0;
     141             :         }
     142             : 
     143           0 :         return done;
     144             : }
     145             : 
     146             : static uint32_t
     147           0 : vbdev_ocf_ctx_data_wr(ctx_data_t *dst, const void *src, uint32_t size)
     148             : {
     149           0 :         struct bdev_ocf_data *d = dst;
     150             :         uint32_t size_local;
     151             : 
     152           0 :         size_local = buf_to_iovec(src, size, d->iovs, d->iovcnt, d->seek);
     153           0 :         d->seek += size_local;
     154             : 
     155           0 :         return size_local;
     156             : }
     157             : 
     158             : static size_t
     159           0 : iovset(struct iovec *iov, size_t iovcnt, int byte, size_t size, size_t offset)
     160             : {
     161           0 :         size_t i, len, done = 0;
     162             : 
     163           0 :         for (i = 0; i < iovcnt; i++) {
     164           0 :                 if (offset >= iov[i].iov_len) {
     165           0 :                         offset -= iov[i].iov_len;
     166           0 :                         continue;
     167             :                 }
     168             : 
     169           0 :                 if (iov[i].iov_base == NULL) {
     170           0 :                         continue;
     171             :                 }
     172             : 
     173           0 :                 if (done >= size) {
     174           0 :                         break;
     175             :                 }
     176             : 
     177           0 :                 len = MIN(size - done, iov[i].iov_len - offset);
     178           0 :                 memset(iov[i].iov_base + offset, byte, len);
     179           0 :                 done += len;
     180           0 :                 offset = 0;
     181             :         }
     182             : 
     183           0 :         return done;
     184             : }
     185             : 
     186             : static uint32_t
     187           0 : vbdev_ocf_ctx_data_zero(ctx_data_t *dst, uint32_t size)
     188             : {
     189           0 :         struct bdev_ocf_data *d = dst;
     190             :         uint32_t size_local;
     191             : 
     192           0 :         size_local = iovset(d->iovs, d->iovcnt, 0, size, d->seek);
     193           0 :         d->seek += size_local;
     194             : 
     195           0 :         return size_local;
     196             : }
     197             : 
     198             : static uint32_t
     199           0 : vbdev_ocf_ctx_data_seek(ctx_data_t *dst, ctx_data_seek_t seek, uint32_t offset)
     200             : {
     201           0 :         struct bdev_ocf_data *d = dst;
     202           0 :         uint32_t off = 0;
     203             : 
     204           0 :         switch (seek) {
     205           0 :         case ctx_data_seek_begin:
     206           0 :                 off = MIN(offset, d->size);
     207           0 :                 d->seek = off;
     208           0 :                 break;
     209           0 :         case ctx_data_seek_current:
     210           0 :                 off = MIN(offset, d->size - d->seek);
     211           0 :                 d->seek += off;
     212           0 :                 break;
     213             :         }
     214             : 
     215           0 :         return off;
     216             : }
     217             : 
     218             : static uint64_t
     219           0 : vbdev_ocf_ctx_data_cpy(ctx_data_t *dst, ctx_data_t *src, uint64_t to,
     220             :                        uint64_t from, uint64_t bytes)
     221             : {
     222           0 :         struct bdev_ocf_data *s = src;
     223           0 :         struct bdev_ocf_data *d = dst;
     224           0 :         uint32_t it_iov = 0;
     225           0 :         uint32_t it_off = 0;
     226             :         uint32_t n, sz;
     227             : 
     228           0 :         bytes = MIN(bytes, s->size - from);
     229           0 :         bytes = MIN(bytes, d->size - to);
     230           0 :         sz = bytes;
     231             : 
     232           0 :         while (from || bytes) {
     233           0 :                 if (s->iovs[it_iov].iov_len == it_off) {
     234           0 :                         it_iov++;
     235           0 :                         it_off = 0;
     236           0 :                         continue;
     237             :                 }
     238             : 
     239           0 :                 if (from) {
     240           0 :                         n = MIN(from, s->iovs[it_iov].iov_len);
     241           0 :                         from -= n;
     242             :                 } else {
     243           0 :                         n = MIN(bytes, s->iovs[it_iov].iov_len);
     244           0 :                         buf_to_iovec(s->iovs[it_iov].iov_base + it_off, n, d->iovs, d->iovcnt, to);
     245           0 :                         bytes -= n;
     246           0 :                         to += n;
     247             :                 }
     248             : 
     249           0 :                 it_off += n;
     250             :         }
     251             : 
     252           0 :         return sz;
     253             : }
     254             : 
     255             : static void
     256           0 : vbdev_ocf_ctx_data_secure_erase(ctx_data_t *ctx_data)
     257             : {
     258           0 :         struct bdev_ocf_data *data = ctx_data;
     259           0 :         struct iovec *iovs = data->iovs;
     260             :         int i;
     261             : 
     262           0 :         for (i = 0; i < data->iovcnt; i++) {
     263           0 :                 if (env_memset(iovs[i].iov_base, iovs[i].iov_len, 0)) {
     264           0 :                         assert(false);
     265             :                 }
     266             :         }
     267           0 : }
     268             : 
     269             : int
     270           0 : vbdev_ocf_queue_create(ocf_cache_t cache, ocf_queue_t *queue, const struct ocf_queue_ops *ops)
     271             : {
     272             :         int rc;
     273           0 :         struct vbdev_ocf_cache_ctx *ctx = ocf_cache_get_priv(cache);
     274             : 
     275           0 :         pthread_mutex_lock(&ctx->lock);
     276           0 :         rc = ocf_queue_create(cache, queue, ops);
     277           0 :         pthread_mutex_unlock(&ctx->lock);
     278           0 :         return rc;
     279             : }
     280             : 
     281             : void
     282           0 : vbdev_ocf_queue_put(ocf_queue_t queue)
     283             : {
     284           0 :         ocf_cache_t cache = ocf_queue_get_cache(queue);
     285           0 :         struct vbdev_ocf_cache_ctx *ctx = ocf_cache_get_priv(cache);
     286             : 
     287           0 :         pthread_mutex_lock(&ctx->lock);
     288           0 :         ocf_queue_put(queue);
     289           0 :         pthread_mutex_unlock(&ctx->lock);
     290           0 : }
     291             : 
     292             : void
     293           0 : vbdev_ocf_cache_ctx_put(struct vbdev_ocf_cache_ctx *ctx)
     294             : {
     295           0 :         if (env_atomic_dec_return(&ctx->refcnt) == 0) {
     296           0 :                 pthread_mutex_destroy(&ctx->lock);
     297           0 :                 free(ctx);
     298             :         }
     299           0 : }
     300             : 
     301             : void
     302           0 : vbdev_ocf_cache_ctx_get(struct vbdev_ocf_cache_ctx *ctx)
     303             : {
     304           0 :         env_atomic_inc(&ctx->refcnt);
     305           0 : }
     306             : 
     307             : struct cleaner_priv {
     308             :         struct spdk_poller *poller;
     309             :         ocf_queue_t         mngt_queue;
     310             :         uint64_t            next_run;
     311             : };
     312             : 
     313             : static int
     314           0 : cleaner_poll(void *arg)
     315             : {
     316           0 :         ocf_cleaner_t cleaner = arg;
     317           0 :         struct cleaner_priv *priv = ocf_cleaner_get_priv(cleaner);
     318             : 
     319           0 :         if (spdk_get_ticks() >= priv->next_run) {
     320           0 :                 ocf_cleaner_run(cleaner, priv->mngt_queue);
     321           0 :                 return SPDK_POLLER_BUSY;
     322             :         }
     323             : 
     324           0 :         return SPDK_POLLER_IDLE;
     325             : }
     326             : 
     327             : static void
     328           0 : cleaner_cmpl(ocf_cleaner_t c, uint32_t interval)
     329             : {
     330           0 :         struct cleaner_priv *priv = ocf_cleaner_get_priv(c);
     331             : 
     332           0 :         priv->next_run = spdk_get_ticks() + ((interval * spdk_get_ticks_hz()) / 1000);
     333           0 : }
     334             : 
     335             : static int
     336           0 : vbdev_ocf_ctx_cleaner_init(ocf_cleaner_t c)
     337             : {
     338           0 :         struct cleaner_priv        *priv  = calloc(1, sizeof(*priv));
     339           0 :         ocf_cache_t                 cache = ocf_cleaner_get_cache(c);
     340           0 :         struct vbdev_ocf_cache_ctx *cctx  = ocf_cache_get_priv(cache);
     341             : 
     342           0 :         if (priv == NULL) {
     343           0 :                 return -ENOMEM;
     344             :         }
     345             : 
     346           0 :         priv->mngt_queue = cctx->mngt_queue;
     347             : 
     348           0 :         ocf_cleaner_set_cmpl(c, cleaner_cmpl);
     349           0 :         ocf_cleaner_set_priv(c, priv);
     350             : 
     351           0 :         return 0;
     352             : }
     353             : 
     354             : static void
     355           0 : vbdev_ocf_ctx_cleaner_stop(ocf_cleaner_t c)
     356             : {
     357           0 :         struct cleaner_priv *priv = ocf_cleaner_get_priv(c);
     358             : 
     359           0 :         if (priv) {
     360           0 :                 spdk_poller_unregister(&priv->poller);
     361           0 :                 free(priv);
     362             :         }
     363           0 : }
     364             : 
     365             : static void
     366           0 : vbdev_ocf_ctx_cleaner_kick(ocf_cleaner_t cleaner)
     367             : {
     368           0 :         struct cleaner_priv *priv  = ocf_cleaner_get_priv(cleaner);
     369             : 
     370           0 :         if (priv->poller) {
     371           0 :                 return;
     372             :         }
     373             : 
     374             :         /* We start cleaner poller at the same thread where cache was created
     375             :          * TODO: allow user to specify core at which cleaner should run */
     376           0 :         priv->poller = SPDK_POLLER_REGISTER(cleaner_poll, cleaner, 0);
     377             : }
     378             : 
     379             : /* This function is main way by which OCF communicates with user
     380             :  * We don't want to use SPDK_LOG here because debugging information that is
     381             :  * associated with every print message is not helpful in callback that only prints info
     382             :  * while the real source is somewhere in OCF code */
     383             : static int
     384           0 : vbdev_ocf_ctx_log_printf(ocf_logger_t logger, ocf_logger_lvl_t lvl,
     385             :                          const char *fmt, va_list args)
     386             : {
     387             :         int spdk_lvl;
     388             : 
     389           0 :         switch (lvl) {
     390           0 :         case log_emerg:
     391             :         case log_alert:
     392             :         case log_crit:
     393             :         case log_err:
     394           0 :                 spdk_lvl = SPDK_LOG_ERROR;
     395           0 :                 break;
     396             : 
     397           0 :         case log_warn:
     398           0 :                 spdk_lvl = SPDK_LOG_WARN;
     399           0 :                 break;
     400             : 
     401           0 :         case log_notice:
     402           0 :                 spdk_lvl = SPDK_LOG_NOTICE;
     403           0 :                 break;
     404             : 
     405           0 :         case log_info:
     406             :         case log_debug:
     407             :         default:
     408           0 :                 spdk_lvl = SPDK_LOG_INFO;
     409             :         }
     410             : 
     411           0 :         spdk_vlog(spdk_lvl, NULL, -1, NULL, fmt, args);
     412           0 :         return 0;
     413             : }
     414             : 
     415             : static const struct ocf_ctx_config vbdev_ocf_ctx_cfg = {
     416             :         .name = "OCF SPDK",
     417             : 
     418             :         .ops = {
     419             :                 .data = {
     420             :                         .alloc = vbdev_ocf_ctx_data_alloc,
     421             :                         .free = vbdev_ocf_ctx_data_free,
     422             :                         .mlock = vbdev_ocf_ctx_data_mlock,
     423             :                         .munlock = vbdev_ocf_ctx_data_munlock,
     424             :                         .read = vbdev_ocf_ctx_data_rd,
     425             :                         .write = vbdev_ocf_ctx_data_wr,
     426             :                         .zero = vbdev_ocf_ctx_data_zero,
     427             :                         .seek = vbdev_ocf_ctx_data_seek,
     428             :                         .copy = vbdev_ocf_ctx_data_cpy,
     429             :                         .secure_erase = vbdev_ocf_ctx_data_secure_erase,
     430             :                 },
     431             : 
     432             :                 .cleaner = {
     433             :                         .init = vbdev_ocf_ctx_cleaner_init,
     434             :                         .stop = vbdev_ocf_ctx_cleaner_stop,
     435             :                         .kick = vbdev_ocf_ctx_cleaner_kick,
     436             :                 },
     437             : 
     438             :                 .logger = {
     439             :                         .print = vbdev_ocf_ctx_log_printf,
     440             :                         .dump_stack = NULL,
     441             :                 },
     442             : 
     443             :         },
     444             : };
     445             : 
     446             : int
     447           0 : vbdev_ocf_ctx_init(void)
     448             : {
     449             :         int ret;
     450             : 
     451           0 :         ret = ocf_ctx_create(&vbdev_ocf_ctx, &vbdev_ocf_ctx_cfg);
     452           0 :         if (ret < 0) {
     453           0 :                 return ret;
     454             :         }
     455             : 
     456           0 :         return 0;
     457             : }
     458             : 
     459             : void
     460           0 : vbdev_ocf_ctx_cleanup(void)
     461             : {
     462           0 :         ocf_ctx_put(vbdev_ocf_ctx);
     463           0 :         vbdev_ocf_ctx = NULL;
     464           0 : }

Generated by: LCOV version 1.15