LCOV - code coverage report
Current view: top level - spdk/test/nvme/sgl - sgl.c (source / functions) Hit Total Coverage
Test: Combined Lines: 206 250 82.4 %
Date: 2024-07-12 17:35:58 Functions: 19 20 95.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 81 168 48.2 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2015 Intel Corporation.
       3                 :            :  *   All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "spdk/stdinc.h"
       7                 :            : 
       8                 :            : #include "spdk/nvme.h"
       9                 :            : #include "spdk/env.h"
      10                 :            : #include "spdk/util.h"
      11                 :            : 
      12                 :            : #define MAX_DEVS 64
      13                 :            : 
      14                 :            : #define MAX_IOVS 128
      15                 :            : 
      16                 :            : #define DATA_PATTERN 0x5A
      17                 :            : 
      18                 :            : #define BASE_LBA_START 0x100000
      19                 :            : 
      20                 :            : struct dev {
      21                 :            :         struct spdk_nvme_ctrlr                  *ctrlr;
      22                 :            :         char                                    name[SPDK_NVMF_TRADDR_MAX_LEN + 1];
      23                 :            : };
      24                 :            : 
      25                 :            : static struct dev devs[MAX_DEVS];
      26                 :            : static int num_devs = 0;
      27                 :            : 
      28                 :            : #define foreach_dev(iter) \
      29                 :            :         for (iter = devs; iter - devs < num_devs; iter++)
      30                 :            : 
      31                 :            : static int io_complete_flag = 0;
      32                 :            : 
      33                 :            : struct sgl_element {
      34                 :            :         void *base;
      35                 :            :         size_t offset;
      36                 :            :         size_t len;
      37                 :            : };
      38                 :            : 
      39                 :            : struct io_request {
      40                 :            :         uint32_t current_iov_index;
      41                 :            :         uint32_t current_iov_bytes_left;
      42                 :            :         struct sgl_element iovs[MAX_IOVS];
      43                 :            :         uint32_t nseg;
      44                 :            :         uint32_t misalign;
      45                 :            : };
      46                 :            : 
      47                 :            : static void
      48                 :        234 : nvme_request_reset_sgl(void *cb_arg, uint32_t sgl_offset)
      49                 :            : {
      50                 :            :         uint32_t i;
      51                 :        234 :         uint32_t offset = 0;
      52                 :            :         struct sgl_element *iov;
      53                 :        234 :         struct io_request *req = (struct io_request *)cb_arg;
      54                 :            : 
      55         [ +  - ]:        326 :         for (i = 0; i < req->nseg; i++) {
      56                 :        326 :                 iov = &req->iovs[i];
      57                 :        326 :                 offset += iov->len;
      58         [ +  + ]:        326 :                 if (offset > sgl_offset) {
      59                 :        234 :                         break;
      60                 :            :                 }
      61                 :            :         }
      62                 :        234 :         req->current_iov_index = i;
      63                 :        234 :         req->current_iov_bytes_left = offset - sgl_offset;
      64                 :        234 :         return;
      65                 :            : }
      66                 :            : 
      67                 :            : static int
      68                 :       1348 : nvme_request_next_sge(void *cb_arg, void **address, uint32_t *length)
      69                 :            : {
      70                 :       1348 :         struct io_request *req = (struct io_request *)cb_arg;
      71                 :            :         struct sgl_element *iov;
      72                 :            : 
      73         [ -  + ]:       1348 :         if (req->current_iov_index >= req->nseg) {
      74                 :          0 :                 *length = 0;
      75                 :          0 :                 *address = NULL;
      76                 :          0 :                 return 0;
      77                 :            :         }
      78                 :            : 
      79                 :       1348 :         iov = &req->iovs[req->current_iov_index];
      80                 :            : 
      81         [ +  + ]:       1348 :         if (req->current_iov_bytes_left) {
      82                 :        234 :                 *address = iov->base + iov->offset + iov->len - req->current_iov_bytes_left;
      83                 :        234 :                 *length = req->current_iov_bytes_left;
      84                 :        234 :                 req->current_iov_bytes_left = 0;
      85                 :            :         } else {
      86                 :       1114 :                 *address = iov->base + iov->offset;
      87                 :       1114 :                 *length = iov->len;
      88                 :            :         }
      89                 :            : 
      90                 :       1348 :         req->current_iov_index++;
      91                 :            : 
      92                 :       1348 :         return 0;
      93                 :            : }
      94                 :            : 
      95                 :            : static void
      96                 :        108 : io_complete(void *ctx, const struct spdk_nvme_cpl *cpl)
      97                 :            : {
      98   [ +  -  -  + ]:        108 :         if (spdk_nvme_cpl_is_error(cpl)) {
      99                 :          0 :                 io_complete_flag = 2;
     100                 :            :         } else {
     101                 :        108 :                 io_complete_flag = 1;
     102                 :            :         }
     103                 :        108 : }
     104                 :            : 
     105                 :            : static void
     106                 :         10 : build_io_request_0(struct io_request *req)
     107                 :            : {
     108                 :         10 :         req->nseg = 1;
     109                 :            : 
     110                 :         10 :         req->iovs[0].base = spdk_zmalloc(0x800, 4, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     111                 :         10 :         req->iovs[0].len = 0x800;
     112                 :         10 : }
     113                 :            : 
     114                 :            : static void
     115                 :         10 : build_io_request_1(struct io_request *req)
     116                 :            : {
     117                 :         10 :         req->nseg = 1;
     118                 :            : 
     119                 :            :         /* 512B for 1st sge */
     120                 :         10 :         req->iovs[0].base = spdk_zmalloc(0x200, 0x200, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     121                 :         10 :         req->iovs[0].len = 0x200;
     122                 :         10 : }
     123                 :            : 
     124                 :            : static void
     125                 :         10 : build_io_request_2(struct io_request *req)
     126                 :            : {
     127                 :         10 :         req->nseg = 1;
     128                 :            : 
     129                 :            :         /* 256KB for 1st sge */
     130                 :         10 :         req->iovs[0].base = spdk_zmalloc(0x40000, 0x1000, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     131                 :         10 :         req->iovs[0].len = 0x40000;
     132                 :         10 : }
     133                 :            : 
     134                 :            : static void
     135                 :         10 : build_io_request_3(struct io_request *req)
     136                 :            : {
     137                 :         10 :         req->nseg = 3;
     138                 :            : 
     139                 :            :         /* 2KB for 1st sge, make sure the iov address start at 0x800 boundary,
     140                 :            :          *  and end with 0x1000 boundary */
     141                 :         10 :         req->iovs[0].base = spdk_zmalloc(0x1000, 0x1000, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     142                 :         10 :         req->iovs[0].offset = 0x800;
     143                 :         10 :         req->iovs[0].len = 0x800;
     144                 :            : 
     145                 :            :         /* 4KB for 2th sge */
     146                 :         10 :         req->iovs[1].base = spdk_zmalloc(0x1000, 0x1000, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     147                 :         10 :         req->iovs[1].len = 0x1000;
     148                 :            : 
     149                 :            :         /* 12KB for 3th sge */
     150                 :         10 :         req->iovs[2].base = spdk_zmalloc(0x3000, 0x1000, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     151                 :         10 :         req->iovs[2].len = 0x3000;
     152                 :         10 : }
     153                 :            : 
     154                 :            : static void
     155                 :         10 : build_io_request_4(struct io_request *req)
     156                 :            : {
     157                 :            :         uint32_t i;
     158                 :            : 
     159                 :         10 :         req->nseg = 32;
     160                 :            : 
     161                 :            :         /* 4KB for 1st sge */
     162                 :         10 :         req->iovs[0].base = spdk_zmalloc(0x1000, 0x1000, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     163                 :         10 :         req->iovs[0].len = 0x1000;
     164                 :            : 
     165                 :            :         /* 8KB for the rest 31 sge */
     166         [ +  + ]:        320 :         for (i = 1; i < req->nseg; i++) {
     167                 :        310 :                 req->iovs[i].base = spdk_zmalloc(0x2000, 0x1000, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     168                 :        310 :                 req->iovs[i].len = 0x2000;
     169                 :            :         }
     170                 :         10 : }
     171                 :            : 
     172                 :            : static void
     173                 :         10 : build_io_request_5(struct io_request *req)
     174                 :            : {
     175                 :         10 :         req->nseg = 1;
     176                 :            : 
     177                 :            :         /* 8KB for 1st sge */
     178                 :         10 :         req->iovs[0].base = spdk_zmalloc(0x2000, 0x1000, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     179                 :         10 :         req->iovs[0].len = 0x2000;
     180                 :         10 : }
     181                 :            : 
     182                 :            : static void
     183                 :         10 : build_io_request_6(struct io_request *req)
     184                 :            : {
     185                 :         10 :         req->nseg = 2;
     186                 :            : 
     187                 :            :         /* 4KB for 1st sge */
     188                 :         10 :         req->iovs[0].base = spdk_zmalloc(0x1000, 0x1000, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     189                 :         10 :         req->iovs[0].len = 0x1000;
     190                 :            : 
     191                 :            :         /* 4KB for 2st sge */
     192                 :         10 :         req->iovs[1].base = spdk_zmalloc(0x1000, 0x1000, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     193                 :         10 :         req->iovs[1].len = 0x1000;
     194                 :         10 : }
     195                 :            : 
     196                 :            : static void
     197                 :         10 : build_io_request_7(struct io_request *req)
     198                 :            : {
     199                 :            :         uint8_t *base;
     200                 :            : 
     201                 :         10 :         req->nseg = 1;
     202                 :            : 
     203                 :            :         /*
     204                 :            :          * Create a 64KB sge, but ensure it is *not* aligned on a 4KB
     205                 :            :          *  boundary.  This is valid for single element buffers with PRP.
     206                 :            :          */
     207                 :         10 :         base = spdk_zmalloc(0x11000, 0x1000, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     208                 :         10 :         req->misalign = 64;
     209                 :         10 :         req->iovs[0].base = base + req->misalign;
     210                 :         10 :         req->iovs[0].len = 0x10000;
     211                 :         10 : }
     212                 :            : 
     213                 :            : static void
     214                 :         10 : build_io_request_8(struct io_request *req)
     215                 :            : {
     216                 :         10 :         req->nseg = 2;
     217                 :            : 
     218                 :            :         /*
     219                 :            :          * 1KB for 1st sge, make sure the iov address does not start and end
     220                 :            :          * at 0x1000 boundary
     221                 :            :          */
     222                 :         10 :         req->iovs[0].base = spdk_zmalloc(0x1000, 0x1000, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     223                 :         10 :         req->iovs[0].offset = 0x400;
     224                 :         10 :         req->iovs[0].len = 0x400;
     225                 :            : 
     226                 :            :         /*
     227                 :            :          * 1KB for 1st sge, make sure the iov address does not start and end
     228                 :            :          * at 0x1000 boundary
     229                 :            :          */
     230                 :         10 :         req->iovs[1].base = spdk_zmalloc(0x1000, 0x1000, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     231                 :         10 :         req->iovs[1].offset = 0x400;
     232                 :         10 :         req->iovs[1].len = 0x400;
     233                 :         10 : }
     234                 :            : 
     235                 :            : static void
     236                 :         10 : build_io_request_9(struct io_request *req)
     237                 :            : {
     238                 :            :         /*
     239                 :            :          * Check if mixed PRP complaint and not complaint requests are handled
     240                 :            :          * properly by splitting them into subrequests.
     241                 :            :          * Construct buffers with following theme:
     242                 :            :          */
     243                 :         10 :         const size_t req_len[] = {  2048, 4096, 2048,  4096,  2048,  1024 };
     244                 :         10 :         const size_t req_off[] = { 0x800,  0x0,  0x0, 0x100, 0x800, 0x800 };
     245                 :         10 :         struct sgl_element *iovs = req->iovs;
     246                 :            :         uint32_t i;
     247                 :         10 :         req->nseg = SPDK_COUNTOF(req_len);
     248                 :            :         assert(SPDK_COUNTOF(req_len) == SPDK_COUNTOF(req_off));
     249                 :            : 
     250         [ +  + ]:         70 :         for (i = 0; i < req->nseg; i++) {
     251                 :         60 :                 iovs[i].base = spdk_zmalloc(req_off[i] + req_len[i], 0x4000, NULL, SPDK_ENV_LCORE_ID_ANY,
     252                 :            :                                             SPDK_MALLOC_DMA);
     253                 :         60 :                 iovs[i].offset = req_off[i];
     254                 :         60 :                 iovs[i].len = req_len[i];
     255                 :            :         }
     256                 :         10 : }
     257                 :            : 
     258                 :            : static void
     259                 :         10 : build_io_request_10(struct io_request *req)
     260                 :            : {
     261                 :            :         /*
     262                 :            :          * Test the case where we have a valid PRP list, but the first and last
     263                 :            :          * elements are not exact multiples of the logical block size.
     264                 :            :          */
     265                 :         10 :         const size_t req_len[] = {  4004, 4096,  92 };
     266                 :         10 :         const size_t req_off[] = {  0x5c,  0x0, 0x0 };
     267                 :         10 :         struct sgl_element *iovs = req->iovs;
     268                 :            :         uint32_t i;
     269                 :         10 :         req->nseg = SPDK_COUNTOF(req_len);
     270                 :            :         assert(SPDK_COUNTOF(req_len) == SPDK_COUNTOF(req_off));
     271                 :            : 
     272         [ +  + ]:         40 :         for (i = 0; i < req->nseg; i++) {
     273                 :         30 :                 iovs[i].base = spdk_zmalloc(req_off[i] + req_len[i], 0x4000, NULL, SPDK_ENV_LCORE_ID_ANY,
     274                 :            :                                             SPDK_MALLOC_DMA);
     275                 :         30 :                 iovs[i].offset = req_off[i];
     276                 :         30 :                 iovs[i].len = req_len[i];
     277                 :            :         }
     278                 :         10 : }
     279                 :            : 
     280                 :            : static void
     281                 :         10 : build_io_request_11(struct io_request *req)
     282                 :            : {
     283                 :            :         /* This test case focuses on the last element not starting on a page boundary. */
     284                 :         10 :         const size_t req_len[] = { 512, 512 };
     285                 :         10 :         const size_t req_off[] = { 0xe00, 0x800 };
     286                 :         10 :         struct sgl_element *iovs = req->iovs;
     287                 :            :         uint32_t i;
     288                 :         10 :         req->nseg = SPDK_COUNTOF(req_len);
     289                 :            :         assert(SPDK_COUNTOF(req_len) == SPDK_COUNTOF(req_off));
     290                 :            : 
     291         [ +  + ]:         30 :         for (i = 0; i < req->nseg; i++) {
     292                 :         20 :                 iovs[i].base = spdk_zmalloc(req_off[i] + req_len[i], 0x4000, NULL, SPDK_ENV_LCORE_ID_ANY,
     293                 :            :                                             SPDK_MALLOC_DMA);
     294                 :         20 :                 iovs[i].offset = req_off[i];
     295                 :         20 :                 iovs[i].len = req_len[i];
     296                 :            :         }
     297                 :         10 : }
     298                 :            : 
     299                 :            : typedef void (*nvme_build_io_req_fn_t)(struct io_request *req);
     300                 :            : 
     301                 :            : static void
     302                 :        120 : free_req(struct io_request *req)
     303                 :            : {
     304                 :            :         uint32_t i;
     305                 :            : 
     306         [ -  + ]:        120 :         if (req == NULL) {
     307                 :          0 :                 return;
     308                 :            :         }
     309                 :            : 
     310         [ +  + ]:        670 :         for (i = 0; i < req->nseg; i++) {
     311                 :        550 :                 spdk_free(req->iovs[i].base - req->misalign);
     312                 :            :         }
     313                 :            : 
     314                 :        120 :         spdk_free(req);
     315                 :            : }
     316                 :            : 
     317                 :            : static int
     318                 :        120 : writev_readv_tests(struct dev *dev, nvme_build_io_req_fn_t build_io_fn, const char *test_name)
     319                 :            : {
     320                 :        120 :         int rc = 0;
     321                 :            :         uint32_t len, lba_count;
     322                 :            :         uint32_t i, j, nseg, remainder;
     323                 :            :         char *buf;
     324                 :            : 
     325                 :            :         struct io_request *req;
     326                 :            :         struct spdk_nvme_ns *ns;
     327                 :            :         struct spdk_nvme_qpair *qpair;
     328                 :            :         const struct spdk_nvme_ns_data *nsdata;
     329                 :            : 
     330                 :        120 :         ns = spdk_nvme_ctrlr_get_ns(dev->ctrlr, 1);
     331         [ -  + ]:        120 :         if (!ns) {
     332   [ #  #  #  # ]:          0 :                 fprintf(stderr, "Null namespace\n");
     333                 :          0 :                 return 0;
     334                 :            :         }
     335                 :        120 :         nsdata = spdk_nvme_ns_get_data(ns);
     336   [ +  -  -  + ]:        120 :         if (!nsdata || !spdk_nvme_ns_get_sector_size(ns)) {
     337   [ #  #  #  # ]:          0 :                 fprintf(stderr, "Empty nsdata or wrong sector size\n");
     338                 :          0 :                 return 0;
     339                 :            :         }
     340                 :            : 
     341         [ -  + ]:        120 :         if (spdk_nvme_ns_get_flags(ns) & SPDK_NVME_NS_DPS_PI_SUPPORTED) {
     342                 :          0 :                 return 0;
     343                 :            :         }
     344                 :            : 
     345                 :        120 :         req = spdk_zmalloc(sizeof(*req), 0, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
     346         [ -  + ]:        120 :         if (!req) {
     347   [ #  #  #  # ]:          0 :                 fprintf(stderr, "Allocate request failed\n");
     348                 :          0 :                 return 0;
     349                 :            :         }
     350                 :            : 
     351                 :            :         /* IO parameters setting */
     352                 :        120 :         build_io_fn(req);
     353                 :            : 
     354                 :        120 :         len = 0;
     355         [ +  + ]:        670 :         for (i = 0; i < req->nseg; i++) {
     356                 :        550 :                 struct sgl_element *sge = &req->iovs[i];
     357                 :            : 
     358                 :        550 :                 len += sge->len;
     359                 :            :         }
     360                 :            : 
     361         [ -  + ]:        120 :         lba_count = len / spdk_nvme_ns_get_sector_size(ns);
     362         [ -  + ]:        120 :         remainder = len % spdk_nvme_ns_get_sector_size(ns);
     363   [ +  +  +  +  :        120 :         if (!lba_count || remainder || (BASE_LBA_START + lba_count > (uint32_t)nsdata->nsze)) {
                   +  + ]
     364   [ -  +  -  + ]:         66 :                 fprintf(stderr, "%s: %s Invalid IO length parameter\n", dev->name, test_name);
     365                 :         66 :                 free_req(req);
     366                 :         66 :                 return 0;
     367                 :            :         }
     368                 :            : 
     369                 :         54 :         qpair = spdk_nvme_ctrlr_alloc_io_qpair(dev->ctrlr, NULL, 0);
     370         [ -  + ]:         54 :         if (!qpair) {
     371                 :          0 :                 free_req(req);
     372                 :          0 :                 return -1;
     373                 :            :         }
     374                 :            : 
     375                 :         54 :         nseg = req->nseg;
     376         [ +  + ]:        389 :         for (i = 0; i < nseg; i++) {
     377         [ -  + ]:        335 :                 memset(req->iovs[i].base + req->iovs[i].offset, DATA_PATTERN, req->iovs[i].len);
     378                 :            :         }
     379                 :            : 
     380                 :         54 :         rc = spdk_nvme_ns_cmd_writev(ns, qpair, BASE_LBA_START, lba_count,
     381                 :            :                                      io_complete, req, 0,
     382                 :            :                                      nvme_request_reset_sgl,
     383                 :            :                                      nvme_request_next_sge);
     384                 :            : 
     385         [ -  + ]:         54 :         if (rc != 0) {
     386   [ #  #  #  # ]:          0 :                 fprintf(stderr, "%s: %s writev failed\n", dev->name, test_name);
     387                 :          0 :                 spdk_nvme_ctrlr_free_io_qpair(qpair);
     388                 :          0 :                 free_req(req);
     389                 :          0 :                 return -1;
     390                 :            :         }
     391                 :            : 
     392                 :         54 :         io_complete_flag = 0;
     393                 :            : 
     394         [ +  + ]:      15570 :         while (!io_complete_flag) {
     395                 :      15516 :                 spdk_nvme_qpair_process_completions(qpair, 1);
     396                 :            :         }
     397                 :            : 
     398         [ -  + ]:         54 :         if (io_complete_flag != 1) {
     399   [ #  #  #  # ]:          0 :                 fprintf(stderr, "%s: %s writev failed\n", dev->name, test_name);
     400                 :          0 :                 spdk_nvme_ctrlr_free_io_qpair(qpair);
     401                 :          0 :                 free_req(req);
     402                 :          0 :                 return -1;
     403                 :            :         }
     404                 :            : 
     405                 :            :         /* reset completion flag */
     406                 :         54 :         io_complete_flag = 0;
     407                 :            : 
     408         [ +  + ]:        389 :         for (i = 0; i < nseg; i++) {
     409         [ -  + ]:        335 :                 memset(req->iovs[i].base + req->iovs[i].offset, 0, req->iovs[i].len);
     410                 :            :         }
     411                 :            : 
     412                 :         54 :         rc = spdk_nvme_ns_cmd_readv(ns, qpair, BASE_LBA_START, lba_count,
     413                 :            :                                     io_complete, req, 0,
     414                 :            :                                     nvme_request_reset_sgl,
     415                 :            :                                     nvme_request_next_sge);
     416                 :            : 
     417         [ -  + ]:         54 :         if (rc != 0) {
     418   [ #  #  #  # ]:          0 :                 fprintf(stderr, "%s: %s readv failed\n", dev->name, test_name);
     419                 :          0 :                 spdk_nvme_ctrlr_free_io_qpair(qpair);
     420                 :          0 :                 free_req(req);
     421                 :          0 :                 return -1;
     422                 :            :         }
     423                 :            : 
     424         [ +  + ]:      45715 :         while (!io_complete_flag) {
     425                 :      45661 :                 spdk_nvme_qpair_process_completions(qpair, 1);
     426                 :            :         }
     427                 :            : 
     428         [ -  + ]:         54 :         if (io_complete_flag != 1) {
     429   [ #  #  #  # ]:          0 :                 fprintf(stderr, "%s: %s readv failed\n", dev->name, test_name);
     430                 :          0 :                 spdk_nvme_ctrlr_free_io_qpair(qpair);
     431                 :          0 :                 free_req(req);
     432                 :          0 :                 return -1;
     433                 :            :         }
     434                 :            : 
     435         [ +  + ]:        389 :         for (i = 0; i < nseg; i++) {
     436                 :        335 :                 buf = (char *)req->iovs[i].base + req->iovs[i].offset;
     437         [ +  + ]:    4922191 :                 for (j = 0; j < req->iovs[i].len; j++) {
     438         [ -  + ]:    4921856 :                         if (buf[j] != DATA_PATTERN) {
     439   [ #  #  #  # ]:          0 :                                 fprintf(stderr, "%s: %s write/read success, but memcmp Failed\n", dev->name, test_name);
     440                 :          0 :                                 spdk_nvme_ctrlr_free_io_qpair(qpair);
     441                 :          0 :                                 free_req(req);
     442                 :          0 :                                 return -1;
     443                 :            :                         }
     444                 :            :                 }
     445                 :            :         }
     446                 :            : 
     447   [ -  +  -  + ]:         54 :         fprintf(stdout, "%s: %s test passed\n", dev->name, test_name);
     448                 :         54 :         spdk_nvme_ctrlr_free_io_qpair(qpair);
     449                 :         54 :         free_req(req);
     450                 :         54 :         return rc;
     451                 :            : }
     452                 :            : 
     453                 :            : static bool
     454                 :          0 : probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
     455                 :            :          struct spdk_nvme_ctrlr_opts *opts)
     456                 :            : {
     457         [ #  # ]:          0 :         printf("Attaching to %s\n", trid->traddr);
     458                 :            : 
     459                 :          0 :         return true;
     460                 :            : }
     461                 :            : 
     462                 :            : static void
     463                 :         10 : attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
     464                 :            :           struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts)
     465                 :            : {
     466                 :            :         struct dev *dev;
     467                 :            : 
     468                 :            :         /* add to dev list */
     469                 :         10 :         dev = &devs[num_devs++];
     470                 :            : 
     471                 :         10 :         dev->ctrlr = ctrlr;
     472                 :            : 
     473         [ -  + ]:         10 :         snprintf(dev->name, sizeof(dev->name), "%s",
     474                 :         10 :                  trid->traddr);
     475                 :            : 
     476         [ -  + ]:         10 :         printf("Attached to %s\n", dev->name);
     477                 :         10 : }
     478                 :            : 
     479                 :            : int
     480                 :          6 : main(int argc, char **argv)
     481                 :            : {
     482                 :            :         struct dev              *iter;
     483                 :            :         int                     rc;
     484                 :          3 :         struct spdk_env_opts    opts;
     485                 :          6 :         struct spdk_nvme_detach_ctx *detach_ctx = NULL;
     486                 :            : 
     487                 :          6 :         spdk_env_opts_init_ext(&opts, sizeof(opts));
     488                 :          6 :         opts.name = "nvme_sgl";
     489                 :          6 :         opts.core_mask = "0x1";
     490                 :          6 :         opts.shm_id = 0;
     491         [ -  + ]:          6 :         if (spdk_env_init_ext(&opts) < 0) {
     492   [ #  #  #  # ]:          0 :                 fprintf(stderr, "Unable to initialize SPDK env\n");
     493                 :          0 :                 return 1;
     494                 :            :         }
     495                 :            : 
     496         [ -  + ]:          6 :         printf("NVMe Readv/Writev Request test\n");
     497                 :            : 
     498         [ -  + ]:          6 :         if (spdk_nvme_probe(NULL, NULL, probe_cb, attach_cb, NULL) != 0) {
     499   [ #  #  #  # ]:          0 :                 fprintf(stderr, "nvme_probe() failed\n");
     500                 :          0 :                 exit(1);
     501                 :            :         }
     502                 :            : 
     503                 :          6 :         rc = 0;
     504         [ +  + ]:         16 :         foreach_dev(iter) {
     505                 :            : #define TEST(x) writev_readv_tests(iter, x, #x)
     506         [ +  - ]:         10 :                 if (TEST(build_io_request_0)
     507         [ +  - ]:         10 :                     || TEST(build_io_request_1)
     508         [ +  - ]:         10 :                     || TEST(build_io_request_2)
     509         [ +  - ]:         10 :                     || TEST(build_io_request_3)
     510         [ +  - ]:         10 :                     || TEST(build_io_request_4)
     511         [ +  - ]:         10 :                     || TEST(build_io_request_5)
     512         [ +  - ]:         10 :                     || TEST(build_io_request_6)
     513         [ +  - ]:         10 :                     || TEST(build_io_request_7)
     514         [ +  - ]:         10 :                     || TEST(build_io_request_8)
     515         [ +  - ]:         10 :                     || TEST(build_io_request_9)
     516         [ +  - ]:         10 :                     || TEST(build_io_request_10)
     517         [ -  + ]:         10 :                     || TEST(build_io_request_11)) {
     518                 :            : #undef TEST
     519                 :          0 :                         rc = 1;
     520         [ #  # ]:          0 :                         printf("%s: failed sgl tests\n", iter->name);
     521                 :            :                 }
     522                 :            :         }
     523                 :            : 
     524         [ -  + ]:          6 :         printf("Cleaning up...\n");
     525                 :            : 
     526         [ +  + ]:         16 :         foreach_dev(iter) {
     527                 :         10 :                 spdk_nvme_detach_async(iter->ctrlr, &detach_ctx);
     528                 :            :         }
     529                 :            : 
     530         [ -  + ]:          6 :         if (detach_ctx) {
     531                 :          0 :                 spdk_nvme_detach_poll(detach_ctx);
     532                 :            :         }
     533                 :            : 
     534                 :          6 :         return rc;
     535                 :            : }

Generated by: LCOV version 1.14