LCOV - code coverage report
Current view: top level - spdk/module/fsdev/aio - linux_aio_mgr.c (source / functions) Hit Total Coverage
Test: Combined Lines: 63 95 66.3 %
Date: 2024-11-20 09:06:21 Functions: 10 11 90.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 19 526 3.6 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
       3                 :            :  */
       4                 :            : #include "spdk/stdinc.h"
       5                 :            : #include "spdk/util.h"
       6                 :            : #include "spdk/log.h"
       7                 :            : #include "aio_mgr.h"
       8                 :            : #include <libaio.h>
       9                 :            : 
      10                 :            : #define MAX_EVENTS 1024
      11                 :            : 
      12                 :            : struct spdk_aio_mgr_io {
      13                 :            :         struct spdk_aio_mgr *mgr;
      14                 :            :         TAILQ_ENTRY(spdk_aio_mgr_io) link;
      15                 :            :         struct iocb io;
      16                 :            :         fsdev_aio_done_cb clb;
      17                 :            :         void *ctx;
      18                 :            :         uint32_t data_size;
      19                 :            :         int err;
      20                 :            : };
      21                 :            : 
      22                 :            : struct spdk_aio_mgr {
      23                 :            :         TAILQ_HEAD(, spdk_aio_mgr_io) in_flight;
      24                 :            :         io_context_t io_ctx;
      25                 :            :         struct {
      26                 :            :                 struct spdk_aio_mgr_io *arr;
      27                 :            :                 uint32_t size;
      28                 :            :                 TAILQ_HEAD(, spdk_aio_mgr_io) pool;
      29                 :            :         } aios;
      30                 :            :         uint32_t num_completions;
      31                 :            : };
      32                 :            : 
      33                 :            : static struct spdk_aio_mgr_io *
      34                 :     524288 : aio_mgr_get_aio(struct spdk_aio_mgr *mgr, fsdev_aio_done_cb clb, void *ctx)
      35                 :            : {
      36   [ #  #  #  #  :     524288 :         struct spdk_aio_mgr_io *aio = TAILQ_FIRST(&mgr->aios.pool);
             #  #  #  # ]
      37                 :            : 
      38         [ +  - ]:     524288 :         if (aio) {
      39   [ #  #  #  # ]:     524288 :                 aio->mgr = mgr;
      40   [ #  #  #  # ]:     524288 :                 aio->clb = clb;
      41   [ #  #  #  # ]:     524288 :                 aio->ctx = ctx;
      42   [ #  #  #  # ]:     524288 :                 aio->err = 0;
      43   [ #  #  #  # ]:     524288 :                 aio->data_size = 0;
      44   [ +  -  #  #  :     524288 :                 TAILQ_REMOVE(&mgr->aios.pool, aio, link);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
      45                 :          0 :         }
      46                 :            : 
      47                 :     524288 :         return aio;
      48                 :            : }
      49                 :            : 
      50                 :            : static inline void
      51                 :     524288 : aio_mgr_put_aio(struct spdk_aio_mgr *mgr, struct spdk_aio_mgr_io *aio)
      52                 :            : {
      53   [ #  #  #  #  :     524288 :         TAILQ_INSERT_TAIL(&aio->mgr->aios.pool, aio, link);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
      54                 :     524288 : }
      55                 :            : 
      56                 :            : static void
      57                 :     524288 : spdk_aio_mgr_io_cpl_cb(io_context_t ctx, struct iocb *iocb, long res, long res2)
      58                 :            : {
      59                 :     524288 :         struct spdk_aio_mgr_io *aio = SPDK_CONTAINEROF(iocb, struct spdk_aio_mgr_io, io);
      60                 :            : 
      61   [ +  +  #  #  :     524288 :         TAILQ_REMOVE(&aio->mgr->in_flight, aio, link);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
      62                 :            : 
      63   [ #  #  #  #  :     524288 :         aio->clb(aio->ctx, res, -res2);
          #  #  #  #  #  
             #  #  #  #  
                      # ]
      64                 :            : 
      65   [ #  #  #  #  :     524288 :         aio->mgr->num_completions++;
                   #  # ]
      66                 :            : 
      67   [ #  #  #  # ]:     524288 :         aio_mgr_put_aio(aio->mgr, aio);
      68                 :     524288 : }
      69                 :            : 
      70                 :            : static struct spdk_aio_mgr_io *
      71                 :     524288 : spdk_aio_mgr_submit_io(struct spdk_aio_mgr *mgr, fsdev_aio_done_cb clb, void *ctx, int fd,
      72                 :            :                        uint64_t offs, uint32_t size, struct iovec *iovs, uint32_t iovcnt, bool read)
      73                 :            : {
      74                 :            :         struct spdk_aio_mgr_io *aio;
      75                 :            :         int res;
      76                 :     524288 :         struct iocb *ios[1];
      77                 :            : 
      78   [ -  +  -  +  :     524288 :         SPDK_DEBUGLOG(spdk_aio_mgr_io, "%s: fd=%d offs=%" PRIu64 " size=%" PRIu32 " iovcnt=%" PRIu32 "\n",
             -  -  #  # ]
      79                 :            :                       read ? "read" : "write", fd, offs, size, iovcnt);
      80                 :            : 
      81                 :     524288 :         aio = aio_mgr_get_aio(mgr, clb, ctx);
      82         [ -  + ]:     524288 :         if (!aio) {
      83                 :          0 :                 SPDK_ERRLOG("Cannot get aio\n");
      84   [ #  #  #  # ]:          0 :                 clb(ctx, 0, EFAULT);
      85                 :          0 :                 return NULL;
      86                 :            :         }
      87                 :            : 
      88   [ +  +  #  # ]:     524288 :         if (read) {
      89         [ #  # ]:     131040 :                 io_prep_preadv(&aio->io, fd, iovs, iovcnt, offs);
      90                 :          0 :         } else {
      91         [ #  # ]:     393248 :                 io_prep_pwritev(&aio->io, fd, iovs, iovcnt, offs);
      92                 :            :         }
      93         [ #  # ]:     524288 :         io_set_callback(&aio->io, spdk_aio_mgr_io_cpl_cb);
      94                 :            : 
      95                 :            : 
      96   [ #  #  #  #  :     524288 :         ios[0] = &aio->io;
                   #  # ]
      97   [ #  #  #  # ]:     524288 :         res = io_submit(mgr->io_ctx, 1, ios);
      98   [ -  +  -  +  :     524288 :         SPDK_DEBUGLOG(spdk_aio_mgr_io, "%s: aio=%p submitted with res=%d\n", read ? "read" : "write", aio,
             -  -  #  # ]
      99                 :            :                       res);
     100         [ +  - ]:     524288 :         if (res) {
     101   [ #  #  #  #  :     524288 :                 TAILQ_INSERT_TAIL(&aio->mgr->in_flight, aio, link);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     102                 :     524288 :                 return aio;
     103                 :            :         } else {
     104   [ #  #  #  #  :          0 :                 aio->clb(aio->ctx, 0, aio->err);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     105                 :          0 :                 aio_mgr_put_aio(mgr, aio);
     106                 :          0 :                 return NULL;
     107                 :            :         }
     108                 :            : 
     109                 :          0 : }
     110                 :            : 
     111                 :            : struct spdk_aio_mgr *
     112                 :          1 : spdk_aio_mgr_create(uint32_t max_aios)
     113                 :            : {
     114                 :            :         struct spdk_aio_mgr *mgr;
     115                 :            :         int res;
     116                 :            :         uint32_t i;
     117                 :            : 
     118                 :          1 :         mgr = calloc(1, sizeof(*mgr));
     119         [ -  + ]:          1 :         if (!mgr) {
     120                 :          0 :                 SPDK_ERRLOG("cannot alloc mgr of %zu bytes\n", sizeof(*mgr));
     121                 :          0 :                 return NULL;
     122                 :            :         }
     123                 :            : 
     124         [ #  # ]:          1 :         res = io_queue_init(max_aios, &mgr->io_ctx);
     125         [ -  + ]:          1 :         if (res) {
     126                 :          0 :                 SPDK_ERRLOG("io_setup(%" PRIu32 ") failed with %d\n", max_aios, res);
     127                 :          0 :                 free(mgr);
     128                 :          0 :                 return NULL;
     129                 :            :         }
     130                 :            : 
     131   [ #  #  #  #  :          1 :         mgr->aios.arr = calloc(max_aios, sizeof(mgr->aios.arr[0]));
                   #  # ]
     132   [ -  +  #  #  :          1 :         if (!mgr->aios.arr) {
             #  #  #  # ]
     133                 :          0 :                 SPDK_ERRLOG("cannot alloc aios pool of %" PRIu32 "\n", max_aios);
     134   [ #  #  #  # ]:          0 :                 io_queue_release(mgr->io_ctx);
     135                 :          0 :                 free(mgr);
     136                 :          0 :                 return NULL;
     137                 :            :         }
     138                 :            : 
     139   [ #  #  #  #  :          1 :         TAILQ_INIT(&mgr->in_flight);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     140   [ #  #  #  #  :          1 :         TAILQ_INIT(&mgr->aios.pool);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     141                 :            : 
     142         [ +  + ]:        257 :         for (i = 0; i < max_aios; i++) {
     143   [ #  #  #  #  :        256 :                 TAILQ_INSERT_TAIL(&mgr->aios.pool, &mgr->aios.arr[i], link);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     144                 :          0 :         }
     145                 :            : 
     146                 :          1 :         return mgr;
     147                 :          0 : }
     148                 :            : 
     149                 :            : struct spdk_aio_mgr_io *
     150                 :     131040 : spdk_aio_mgr_read(struct spdk_aio_mgr *mgr, fsdev_aio_done_cb clb, void *ctx,
     151                 :            :                   int fd, uint64_t offs, uint32_t size, struct iovec *iovs, uint32_t iovcnt)
     152                 :            : {
     153                 :     131040 :         return spdk_aio_mgr_submit_io(mgr, clb, ctx, fd, offs, size, iovs, iovcnt, true);
     154                 :            : }
     155                 :            : 
     156                 :            : struct spdk_aio_mgr_io *
     157                 :     393248 : spdk_aio_mgr_write(struct spdk_aio_mgr *mgr, fsdev_aio_done_cb clb, void *ctx,
     158                 :            :                    int fd, uint64_t offs, uint32_t size, const struct iovec *iovs, uint32_t iovcnt)
     159                 :            : {
     160                 :     393248 :         return spdk_aio_mgr_submit_io(mgr, clb, ctx, fd, offs, size, (struct iovec *)iovs, iovcnt, false);
     161                 :            : }
     162                 :            : 
     163                 :            : void
     164                 :          0 : spdk_aio_mgr_cancel(struct spdk_aio_mgr *mgr, struct spdk_aio_mgr_io *aio)
     165                 :            : {
     166                 :            :         int res;
     167                 :          0 :         struct io_event result;
     168                 :            : 
     169   [ #  #  #  #  :          0 :         assert(mgr == aio->mgr);
             #  #  #  # ]
     170                 :            : 
     171   [ #  #  #  #  :          0 :         res = io_cancel(mgr->io_ctx, &aio->io, &result);
                   #  # ]
     172         [ #  # ]:          0 :         if (res) {
     173   [ #  #  #  #  :          0 :                 SPDK_DEBUGLOG(spdk_aio_mgr_io, "aio=%p cancelled\n", aio);
                   #  # ]
     174   [ #  #  #  #  :          0 :                 spdk_aio_mgr_io_cpl_cb(mgr->io_ctx, &aio->io, ECANCELED, 0);
                   #  # ]
     175                 :          0 :         } else {
     176                 :          0 :                 SPDK_WARNLOG("aio=%p cancellation failed with err=%d\n", aio, res);
     177                 :            :         }
     178                 :          0 : }
     179                 :            : 
     180                 :            : bool
     181                 :    1535442 : spdk_aio_mgr_poll(struct spdk_aio_mgr *mgr)
     182                 :            : {
     183                 :            :         int res;
     184                 :            : 
     185   [ #  #  #  # ]:    1535442 :         mgr->num_completions = 0;
     186                 :            : 
     187   [ #  #  #  # ]:    1535442 :         res = io_queue_run(mgr->io_ctx);
     188         [ -  + ]:    1535442 :         if (res) {
     189                 :          0 :                 SPDK_WARNLOG("polling failed with err=%d\n", res);
     190                 :          0 :         }
     191                 :            : 
     192   [ #  #  #  # ]:    1535442 :         return mgr->num_completions ? true : false;
     193                 :            : }
     194                 :            : 
     195                 :            : void
     196                 :          1 : spdk_aio_mgr_delete(struct spdk_aio_mgr *mgr)
     197                 :            : {
     198   [ -  +  #  #  :          1 :         assert(TAILQ_EMPTY(&mgr->in_flight));
          #  #  #  #  #  
                      # ]
     199   [ #  #  #  #  :          1 :         free(mgr->aios.arr);
                   #  # ]
     200   [ #  #  #  # ]:          1 :         io_queue_release(mgr->io_ctx);
     201                 :          1 :         free(mgr);
     202                 :          1 : }
     203                 :            : 
     204                 :       1980 : SPDK_LOG_REGISTER_COMPONENT(spdk_aio_mgr_io)

Generated by: LCOV version 1.15