LCOV - code coverage report
Current view: top level - lib/dma - dma.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 116 135 85.9 %
Date: 2024-07-12 14:55:14 Functions: 17 19 89.5 %

          Line data    Source code
       1             : /*   SPDX-License-Identifier: BSD-3-Clause
       2             :  *   Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
       3             :  */
       4             : 
       5             : #include "spdk/dma.h"
       6             : #include "spdk/log.h"
       7             : #include "spdk/util.h"
       8             : #include "spdk/likely.h"
       9             : 
      10             : pthread_mutex_t g_dma_mutex = PTHREAD_MUTEX_INITIALIZER;
      11             : TAILQ_HEAD(, spdk_memory_domain) g_dma_memory_domains = TAILQ_HEAD_INITIALIZER(
      12             :                         g_dma_memory_domains);
      13             : 
      14             : struct spdk_memory_domain {
      15             :         enum spdk_dma_device_type type;
      16             :         spdk_memory_domain_pull_data_cb pull_cb;
      17             :         spdk_memory_domain_push_data_cb push_cb;
      18             :         spdk_memory_domain_translate_memory_cb translate_cb;
      19             :         spdk_memory_domain_invalidate_data_cb invalidate_cb;
      20             :         spdk_memory_domain_memzero_cb memzero_cb;
      21             :         TAILQ_ENTRY(spdk_memory_domain) link;
      22             :         struct spdk_memory_domain_ctx *ctx;
      23             :         char *id;
      24             : };
      25             : 
      26             : static struct spdk_memory_domain g_system_domain = {
      27             :         .type = SPDK_DMA_DEVICE_TYPE_DMA,
      28             :         .id = "system",
      29             : };
      30             : 
      31             : static void
      32             : __attribute__((constructor))
      33           1 : _memory_domain_register(void)
      34             : {
      35           1 :         TAILQ_INSERT_TAIL(&g_dma_memory_domains, &g_system_domain, link);
      36           1 : }
      37             : 
      38             : struct spdk_memory_domain *
      39           1 : spdk_memory_domain_get_system_domain(void)
      40             : {
      41           1 :         return &g_system_domain;
      42             : }
      43             : 
      44             : int
      45           5 : spdk_memory_domain_create(struct spdk_memory_domain **_domain, enum spdk_dma_device_type type,
      46             :                           struct spdk_memory_domain_ctx *ctx, const char *id)
      47             : {
      48             :         struct spdk_memory_domain *domain;
      49             :         size_t ctx_size;
      50             : 
      51           5 :         if (!_domain) {
      52           1 :                 return -EINVAL;
      53             :         }
      54             : 
      55           4 :         if (ctx && ctx->size == 0) {
      56           1 :                 SPDK_ERRLOG("Context size can't be 0\n");
      57           1 :                 return -EINVAL;
      58             :         }
      59             : 
      60           3 :         domain = calloc(1, sizeof(*domain));
      61           3 :         if (!domain) {
      62           0 :                 SPDK_ERRLOG("Failed to allocate memory");
      63           0 :                 return -ENOMEM;
      64             :         }
      65             : 
      66           3 :         if (id) {
      67           3 :                 domain->id = strdup(id);
      68           3 :                 if (!domain->id) {
      69           0 :                         SPDK_ERRLOG("Failed to allocate memory");
      70           0 :                         free(domain);
      71           0 :                         return -ENOMEM;
      72             :                 }
      73             :         }
      74             : 
      75           3 :         if (ctx) {
      76           3 :                 domain->ctx = calloc(1, sizeof(*domain->ctx));
      77           3 :                 if (!domain->ctx) {
      78           0 :                         SPDK_ERRLOG("Failed to allocate memory");
      79           0 :                         free(domain->id);
      80           0 :                         free(domain);
      81           0 :                         return -ENOMEM;
      82             :                 }
      83             : 
      84           3 :                 ctx_size = spdk_min(sizeof(*domain->ctx), ctx->size);
      85           3 :                 memcpy(domain->ctx, ctx, ctx_size);
      86           3 :                 domain->ctx->size = ctx_size;
      87             :         }
      88             : 
      89           3 :         domain->type = type;
      90             : 
      91           3 :         pthread_mutex_lock(&g_dma_mutex);
      92           3 :         TAILQ_INSERT_TAIL(&g_dma_memory_domains, domain, link);
      93           3 :         pthread_mutex_unlock(&g_dma_mutex);
      94             : 
      95           3 :         *_domain = domain;
      96             : 
      97           3 :         return 0;
      98             : }
      99             : 
     100             : void
     101           3 : spdk_memory_domain_set_translation(struct spdk_memory_domain *domain,
     102             :                                    spdk_memory_domain_translate_memory_cb translate_cb)
     103             : {
     104           3 :         assert(domain);
     105             : 
     106           3 :         domain->translate_cb = translate_cb;
     107           3 : }
     108             : 
     109             : void
     110           0 : spdk_memory_domain_set_invalidate(struct spdk_memory_domain *domain,
     111             :                                   spdk_memory_domain_invalidate_data_cb invalidate_cb)
     112             : {
     113           0 :         assert(domain);
     114             : 
     115           0 :         domain->invalidate_cb = invalidate_cb;
     116           0 : }
     117             : 
     118             : void
     119           3 : spdk_memory_domain_set_pull(struct spdk_memory_domain *domain,
     120             :                             spdk_memory_domain_pull_data_cb pull_cb)
     121             : {
     122           3 :         assert(domain);
     123             : 
     124           3 :         domain->pull_cb = pull_cb;
     125           3 : }
     126             : 
     127             : void
     128           1 : spdk_memory_domain_set_push(struct spdk_memory_domain *domain,
     129             :                             spdk_memory_domain_push_data_cb push_cb)
     130             : {
     131           1 :         assert(domain);
     132             : 
     133           1 :         domain->push_cb = push_cb;
     134           1 : }
     135             : 
     136             : void
     137           3 : spdk_memory_domain_set_memzero(struct spdk_memory_domain *domain,
     138             :                                spdk_memory_domain_memzero_cb memzero_cb)
     139             : {
     140           3 :         assert(domain);
     141             : 
     142           3 :         domain->memzero_cb = memzero_cb;
     143           3 : }
     144             : 
     145             : struct spdk_memory_domain_ctx *
     146           1 : spdk_memory_domain_get_context(struct spdk_memory_domain *domain)
     147             : {
     148           1 :         assert(domain);
     149             : 
     150           1 :         return domain->ctx;
     151             : }
     152             : 
     153             : /* We have to use the typedef in the function declaration to appease astyle. */
     154             : typedef enum spdk_dma_device_type spdk_dma_device_type_t;
     155             : 
     156             : spdk_dma_device_type_t
     157           1 : spdk_memory_domain_get_dma_device_type(struct spdk_memory_domain *domain)
     158             : {
     159           1 :         assert(domain);
     160             : 
     161           1 :         return domain->type;
     162             : }
     163             : 
     164             : const char *
     165           1 : spdk_memory_domain_get_dma_device_id(struct spdk_memory_domain *domain)
     166             : {
     167           1 :         assert(domain);
     168             : 
     169           1 :         return domain->id;
     170             : }
     171             : 
     172             : void
     173           4 : spdk_memory_domain_destroy(struct spdk_memory_domain *domain)
     174             : {
     175           4 :         if (!domain) {
     176           1 :                 return;
     177             :         }
     178             : 
     179           3 :         assert(domain != &g_system_domain);
     180             : 
     181           3 :         pthread_mutex_lock(&g_dma_mutex);
     182           3 :         TAILQ_REMOVE(&g_dma_memory_domains, domain, link);
     183           3 :         pthread_mutex_unlock(&g_dma_mutex);
     184             : 
     185           3 :         free(domain->ctx);
     186           3 :         free(domain->id);
     187           3 :         free(domain);
     188             : }
     189             : 
     190             : int
     191           2 : spdk_memory_domain_pull_data(struct spdk_memory_domain *src_domain, void *src_domain_ctx,
     192             :                              struct iovec *src_iov, uint32_t src_iov_cnt, struct iovec *dst_iov, uint32_t dst_iov_cnt,
     193             :                              spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg)
     194             : {
     195           2 :         assert(src_domain);
     196           2 :         assert(src_iov);
     197           2 :         assert(dst_iov);
     198             : 
     199           2 :         if (spdk_unlikely(!src_domain->pull_cb)) {
     200           1 :                 return -ENOTSUP;
     201             :         }
     202             : 
     203           1 :         return src_domain->pull_cb(src_domain, src_domain_ctx, src_iov, src_iov_cnt, dst_iov, dst_iov_cnt,
     204             :                                    cpl_cb, cpl_cb_arg);
     205             : }
     206             : 
     207             : int
     208           2 : spdk_memory_domain_push_data(struct spdk_memory_domain *dst_domain, void *dst_domain_ctx,
     209             :                              struct iovec *dst_iov, uint32_t dst_iovcnt, struct iovec *src_iov, uint32_t src_iovcnt,
     210             :                              spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg)
     211             : {
     212           2 :         assert(dst_domain);
     213           2 :         assert(dst_iov);
     214           2 :         assert(src_iov);
     215             : 
     216           2 :         if (spdk_unlikely(!dst_domain->push_cb)) {
     217           1 :                 return -ENOTSUP;
     218             :         }
     219             : 
     220           1 :         return dst_domain->push_cb(dst_domain, dst_domain_ctx, dst_iov, dst_iovcnt, src_iov, src_iovcnt,
     221             :                                    cpl_cb, cpl_cb_arg);
     222             : }
     223             : 
     224             : int
     225           2 : spdk_memory_domain_translate_data(struct spdk_memory_domain *src_domain, void *src_domain_ctx,
     226             :                                   struct spdk_memory_domain *dst_domain, struct spdk_memory_domain_translation_ctx *dst_domain_ctx,
     227             :                                   void *addr, size_t len, struct spdk_memory_domain_translation_result *result)
     228             : {
     229           2 :         assert(src_domain);
     230           2 :         assert(dst_domain);
     231           2 :         assert(result);
     232             : 
     233           2 :         if (spdk_unlikely(!src_domain->translate_cb)) {
     234           1 :                 return -ENOTSUP;
     235             :         }
     236             : 
     237           1 :         return src_domain->translate_cb(src_domain, src_domain_ctx, dst_domain, dst_domain_ctx, addr, len,
     238             :                                         result);
     239             : }
     240             : 
     241             : void
     242           0 : spdk_memory_domain_invalidate_data(struct spdk_memory_domain *domain, void *domain_ctx,
     243             :                                    struct iovec *iov, uint32_t iovcnt)
     244             : {
     245           0 :         assert(domain);
     246             : 
     247           0 :         if (spdk_unlikely(!domain->invalidate_cb)) {
     248           0 :                 return;
     249             :         }
     250             : 
     251           0 :         domain->invalidate_cb(domain, domain_ctx, iov, iovcnt);
     252             : }
     253             : 
     254             : int
     255           2 : spdk_memory_domain_memzero(struct spdk_memory_domain *domain, void *domain_ctx, struct iovec *iov,
     256             :                            uint32_t iovcnt, spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg)
     257             : {
     258           2 :         assert(domain);
     259           2 :         assert(iov);
     260           2 :         assert(iovcnt);
     261             : 
     262           2 :         if (spdk_unlikely(!domain->memzero_cb)) {
     263           1 :                 return -ENOTSUP;
     264             :         }
     265             : 
     266           1 :         return domain->memzero_cb(domain, domain_ctx, iov, iovcnt, cpl_cb, cpl_cb_arg);
     267             : }
     268             : 
     269             : struct spdk_memory_domain *
     270           8 : spdk_memory_domain_get_first(const char *id)
     271             : {
     272             :         struct spdk_memory_domain *domain;
     273             : 
     274           8 :         if (!id) {
     275           5 :                 pthread_mutex_lock(&g_dma_mutex);
     276           5 :                 domain = TAILQ_FIRST(&g_dma_memory_domains);
     277           5 :                 pthread_mutex_unlock(&g_dma_mutex);
     278             : 
     279           5 :                 return domain;
     280             :         }
     281             : 
     282           3 :         pthread_mutex_lock(&g_dma_mutex);
     283           8 :         TAILQ_FOREACH(domain, &g_dma_memory_domains, link) {
     284           7 :                 if (!strcmp(domain->id, id)) {
     285           2 :                         break;
     286             :                 }
     287             :         }
     288           3 :         pthread_mutex_unlock(&g_dma_mutex);
     289             : 
     290           3 :         return domain;
     291             : }
     292             : 
     293             : struct spdk_memory_domain *
     294          12 : spdk_memory_domain_get_next(struct spdk_memory_domain *prev, const char *id)
     295             : {
     296             :         struct spdk_memory_domain *domain;
     297             : 
     298          12 :         if (!prev) {
     299           0 :                 return NULL;
     300             :         }
     301             : 
     302          12 :         pthread_mutex_lock(&g_dma_mutex);
     303          12 :         domain = TAILQ_NEXT(prev, link);
     304          12 :         pthread_mutex_unlock(&g_dma_mutex);
     305             : 
     306          12 :         if (!id || !domain) {
     307          10 :                 return domain;
     308             :         }
     309             : 
     310           2 :         pthread_mutex_lock(&g_dma_mutex);
     311           4 :         TAILQ_FOREACH_FROM(domain, &g_dma_memory_domains, link) {
     312           3 :                 if (!strcmp(domain->id, id)) {
     313           1 :                         break;
     314             :                 }
     315             :         }
     316           2 :         pthread_mutex_unlock(&g_dma_mutex);
     317             : 
     318           2 :         return domain;
     319             : }

Generated by: LCOV version 1.15