LCOV - code coverage report
Current view: top level - lib/ftl/mngt - ftl_mngt_ioch.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 0 103 0.0 %
Date: 2024-07-15 11:26:12 Functions: 0 10 0.0 %

          Line data    Source code
       1             : /*   SPDX-License-Identifier: BSD-3-Clause
       2             :  *   Copyright (C) 2022 Intel Corporation.
       3             :  *   All rights reserved.
       4             :  */
       5             : 
       6             : #include "spdk/thread.h"
       7             : 
       8             : #include "ftl_core.h"
       9             : #include "ftl_mngt.h"
      10             : #include "ftl_mngt_steps.h"
      11             : #include "ftl_band.h"
      12             : 
      13             : struct ftl_io_channel_ctx {
      14             :         struct ftl_io_channel *ioch;
      15             : };
      16             : 
      17             : struct ftl_io_channel *
      18           0 : ftl_io_channel_get_ctx(struct spdk_io_channel *ioch)
      19             : {
      20           0 :         struct ftl_io_channel_ctx *ctx = spdk_io_channel_get_ctx(ioch);
      21           0 :         return ctx->ioch;
      22             : }
      23             : 
      24             : static void
      25           0 : ftl_dev_register_channel(void *ctx)
      26             : {
      27           0 :         struct ftl_io_channel *ioch = ctx;
      28           0 :         struct spdk_ftl_dev *dev = ioch->dev;
      29             : 
      30             :         /* This only runs on the core thread, so it's safe to do this lockless */
      31           0 :         TAILQ_INSERT_TAIL(&dev->ioch_queue, ioch, entry);
      32           0 : }
      33             : 
      34             : static void
      35           0 : io_channel_unregister(void *ctx)
      36             : {
      37           0 :         struct ftl_io_channel *ioch = ctx;
      38           0 :         struct spdk_ftl_dev *dev = ioch->dev;
      39             : 
      40           0 :         TAILQ_REMOVE(&dev->ioch_queue, ioch, entry);
      41             : 
      42           0 :         spdk_ring_free(ioch->cq);
      43           0 :         spdk_ring_free(ioch->sq);
      44           0 :         ftl_mempool_destroy(ioch->map_pool);
      45           0 :         free(ioch);
      46           0 : }
      47             : 
      48             : static int
      49           0 : io_channel_create_cb(void *io_device, void *ctx)
      50             : {
      51           0 :         struct spdk_ftl_dev *dev = io_device;
      52           0 :         struct ftl_io_channel_ctx *_ioch = ctx;
      53             :         struct ftl_io_channel *ioch;
      54           0 :         char mempool_name[32];
      55             :         int rc;
      56             : 
      57           0 :         FTL_NOTICELOG(dev, "FTL IO channel created on %s\n",
      58             :                       spdk_thread_get_name(spdk_get_thread()));
      59             : 
      60             :         /* This gets unregistered asynchronously with the device -
      61             :          * we can't just use the ctx buffer passed by the thread library
      62             :          */
      63           0 :         ioch = calloc(1, sizeof(*ioch));
      64           0 :         if (ioch == NULL) {
      65           0 :                 FTL_ERRLOG(dev, "Failed to allocate IO channel\n");
      66           0 :                 return -1;
      67             :         }
      68             : 
      69           0 :         rc = snprintf(mempool_name, sizeof(mempool_name), "ftl_io_%p", ioch);
      70           0 :         if (rc < 0 || rc >= (int)sizeof(mempool_name)) {
      71           0 :                 FTL_ERRLOG(dev, "Failed to create IO channel pool name\n");
      72           0 :                 free(ioch);
      73           0 :                 return -1;
      74             :         }
      75             : 
      76           0 :         ioch->dev = dev;
      77             : 
      78           0 :         ioch->map_pool = ftl_mempool_create(
      79             :                                  dev->conf.user_io_pool_size,
      80           0 :                                  sizeof(ftl_addr) * dev->xfer_size,
      81             :                                  64,
      82             :                                  SPDK_ENV_SOCKET_ID_ANY);
      83           0 :         if (!ioch->map_pool) {
      84           0 :                 FTL_ERRLOG(dev, "Failed to create IO channel's  map IO pool\n");
      85           0 :                 goto fail_io_pool;
      86             :         }
      87             : 
      88           0 :         ioch->cq = spdk_ring_create(SPDK_RING_TYPE_SP_SC, spdk_align64pow2(dev->conf.user_io_pool_size + 1),
      89             :                                     SPDK_ENV_SOCKET_ID_ANY);
      90           0 :         if (!ioch->cq) {
      91           0 :                 FTL_ERRLOG(dev, "Failed to create IO channel completion queue\n");
      92           0 :                 goto fail_io_pool;
      93             :         }
      94             : 
      95           0 :         ioch->sq = spdk_ring_create(SPDK_RING_TYPE_SP_SC, spdk_align64pow2(dev->conf.user_io_pool_size + 1),
      96             :                                     SPDK_ENV_SOCKET_ID_ANY);
      97           0 :         if (!ioch->sq) {
      98           0 :                 FTL_ERRLOG(dev, "Failed to create IO channel submission queue\n");
      99           0 :                 goto fail_cq;
     100             :         }
     101             : 
     102           0 :         ioch->poller = SPDK_POLLER_REGISTER(ftl_io_channel_poll, ioch, 0);
     103           0 :         if (!ioch->poller) {
     104           0 :                 FTL_ERRLOG(dev, "Failed to register IO channel poller\n");
     105           0 :                 goto fail_sq;
     106             :         }
     107             : 
     108           0 :         if (spdk_thread_send_msg(dev->core_thread, ftl_dev_register_channel, ioch)) {
     109           0 :                 FTL_ERRLOG(dev, "Failed to register IO channel\n");
     110           0 :                 goto fail_poller;
     111             :         }
     112             : 
     113           0 :         _ioch->ioch = ioch;
     114           0 :         return 0;
     115             : 
     116           0 : fail_poller:
     117           0 :         spdk_poller_unregister(&ioch->poller);
     118           0 : fail_cq:
     119           0 :         spdk_ring_free(ioch->cq);
     120           0 : fail_sq:
     121           0 :         spdk_ring_free(ioch->sq);
     122           0 : fail_io_pool:
     123           0 :         ftl_mempool_destroy(ioch->map_pool);
     124           0 :         free(ioch);
     125             : 
     126           0 :         return -1;
     127             : }
     128             : 
     129             : static void
     130           0 : io_channel_destroy_cb(void *io_device, void *ctx)
     131             : {
     132           0 :         struct ftl_io_channel_ctx *_ioch = ctx;
     133           0 :         struct ftl_io_channel *ioch = _ioch->ioch;
     134           0 :         struct spdk_ftl_dev *dev = ioch->dev;
     135             : 
     136           0 :         FTL_NOTICELOG(dev, "FTL IO channel destroy on %s\n",
     137             :                       spdk_thread_get_name(spdk_get_thread()));
     138             : 
     139           0 :         spdk_poller_unregister(&ioch->poller);
     140           0 :         spdk_thread_send_msg(ftl_get_core_thread(dev),
     141             :                              io_channel_unregister, ioch);
     142           0 : }
     143             : 
     144             : void
     145           0 : ftl_mngt_register_io_device(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     146             : {
     147           0 :         dev->io_device_registered = true;
     148             : 
     149           0 :         spdk_io_device_register(dev, io_channel_create_cb,
     150             :                                 io_channel_destroy_cb,
     151             :                                 sizeof(struct ftl_io_channel_ctx),
     152             :                                 NULL);
     153             : 
     154           0 :         ftl_mngt_next_step(mngt);
     155           0 : }
     156             : 
     157             : static void
     158           0 : unregister_cb(void *io_device)
     159             : {
     160           0 :         struct spdk_ftl_dev *dev = io_device;
     161           0 :         struct ftl_mngt_process *mngt = dev->unregister_process;
     162             : 
     163           0 :         dev->io_device_registered = false;
     164           0 :         dev->unregister_process = NULL;
     165             : 
     166           0 :         ftl_mngt_next_step(mngt);
     167           0 : }
     168             : 
     169             : void
     170           0 : ftl_mngt_unregister_io_device(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     171             : {
     172           0 :         if (dev->io_device_registered) {
     173           0 :                 dev->unregister_process = mngt;
     174           0 :                 spdk_io_device_unregister(dev, unregister_cb);
     175             :         } else {
     176           0 :                 ftl_mngt_skip_step(mngt);
     177             :         }
     178           0 : }
     179             : 
     180             : void
     181           0 : ftl_mngt_init_io_channel(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     182             : {
     183           0 :         dev->ioch = spdk_get_io_channel(dev);
     184           0 :         if (!dev->ioch) {
     185           0 :                 FTL_ERRLOG(dev, "Unable to get IO channel for core thread");
     186           0 :                 ftl_mngt_fail_step(mngt);
     187           0 :                 return;
     188             :         }
     189             : 
     190           0 :         ftl_mngt_next_step(mngt);
     191             : }
     192             : 
     193             : void
     194           0 : ftl_mngt_deinit_io_channel(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     195             : {
     196           0 :         if (dev->ioch) {
     197           0 :                 spdk_put_io_channel(dev->ioch);
     198           0 :                 dev->ioch = NULL;
     199             :         }
     200             : 
     201           0 :         ftl_mngt_next_step(mngt);
     202           0 : }

Generated by: LCOV version 1.15