LCOV - code coverage report
Current view: top level - spdk/lib/ftl/mngt - ftl_mngt.c (source / functions) Hit Total Coverage
Test: Combined Lines: 223 285 78.2 %
Date: 2024-12-17 04:35:18 Functions: 31 31 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 108 1466 7.4 %

           Branch data     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/queue.h"
       7                 :            : #include "spdk/assert.h"
       8                 :            : #include "spdk/env.h"
       9                 :            : 
      10                 :            : #include "ftl_mngt.h"
      11                 :            : #include "ftl_core.h"
      12                 :            : 
      13                 :            : struct ftl_mngt_step_status {
      14                 :            :         uint64_t start;
      15                 :            :         uint64_t stop;
      16                 :            :         int status;
      17                 :            :         int silent;
      18                 :            :         TAILQ_ENTRY(ftl_mngt_step) entry;
      19                 :            : };
      20                 :            : 
      21                 :            : struct ftl_mngt_step {
      22                 :            :         void *ctx;
      23                 :            :         const struct ftl_mngt_step_desc *desc;
      24                 :            :         struct ftl_mngt_step_status action;
      25                 :            :         struct ftl_mngt_step_status rollback;
      26                 :            : };
      27                 :            : 
      28                 :            : struct ftl_mngt_process {
      29                 :            :         struct spdk_ftl_dev *dev;
      30                 :            :         int status;
      31                 :            :         bool silent;
      32                 :            :         bool rollback;
      33                 :            :         bool continuing;
      34                 :            :         struct  {
      35                 :            :                 ftl_mngt_completion cb;
      36                 :            :                 void *cb_ctx;
      37                 :            :                 struct spdk_thread *thread;
      38                 :            :         } caller;
      39                 :            :         void *ctx;
      40                 :            :         uint64_t tsc_start;
      41                 :            :         uint64_t tsc_stop;
      42                 :            :         const struct ftl_mngt_process_desc *desc;
      43                 :            :         TAILQ_HEAD(, ftl_mngt_step) action_queue_todo;
      44                 :            :         TAILQ_HEAD(, ftl_mngt_step) action_queue_done;
      45                 :            :         TAILQ_HEAD(, ftl_mngt_step) rollback_queue_todo;
      46                 :            :         TAILQ_HEAD(, ftl_mngt_step) rollback_queue_done;
      47                 :            :         struct {
      48                 :            :                 struct ftl_mngt_step step;
      49                 :            :                 struct ftl_mngt_step_desc desc;
      50                 :            :         } cleanup;
      51                 :            :         struct ftl_mng_tracer *tracer;
      52                 :            : };
      53                 :            : 
      54                 :            : static void action_next(struct ftl_mngt_process *mngt);
      55                 :            : static void action_msg(void *ctx);
      56                 :            : static void action_execute(struct ftl_mngt_process *mngt);
      57                 :            : static void action_done(struct ftl_mngt_process *mngt, int status);
      58                 :            : static void rollback_next(struct ftl_mngt_process *mngt);
      59                 :            : static void rollback_msg(void *ctx);
      60                 :            : static void rollback_execute(struct ftl_mngt_process *mngt);
      61                 :            : static void rollback_done(struct ftl_mngt_process *mngt, int status);
      62                 :            : 
      63                 :            : static inline struct ftl_mngt_step *
      64                 :       1910 : get_current_step(struct ftl_mngt_process *mngt)
      65                 :            : {
      66   [ +  +  +  +  :       1910 :         if (!mngt->rollback) {
             #  #  #  # ]
      67   [ #  #  #  #  :       1858 :                 return TAILQ_FIRST(&mngt->action_queue_todo);
                   #  # ]
      68                 :            :         } else {
      69   [ #  #  #  #  :         52 :                 return TAILQ_FIRST(&mngt->rollback_queue_todo);
                   #  # ]
      70                 :            :         }
      71                 :          0 : }
      72                 :            : 
      73                 :            : static int
      74                 :       1629 : init_step(struct ftl_mngt_process *mngt,
      75                 :            :           const struct ftl_mngt_step_desc *desc)
      76                 :            : {
      77                 :            :         struct ftl_mngt_step *step;
      78                 :            : 
      79                 :       1629 :         step = calloc(1, sizeof(*step));
      80         [ -  + ]:       1629 :         if (!step) {
      81                 :          0 :                 return -ENOMEM;
      82                 :            :         }
      83                 :            : 
      84                 :            :         /* Initialize the step's argument */
      85   [ +  +  #  #  :       1629 :         if (desc->ctx_size) {
                   #  # ]
      86   [ #  #  #  #  :         28 :                 step->ctx = calloc(1, desc->ctx_size);
             #  #  #  # ]
      87   [ -  +  #  #  :         28 :                 if (!step->ctx) {
                   #  # ]
      88                 :          0 :                         free(step);
      89                 :          0 :                         return -ENOMEM;
      90                 :            :                 }
      91                 :          0 :         }
      92   [ #  #  #  # ]:       1629 :         step->desc = desc;
      93   [ #  #  #  #  :       1629 :         TAILQ_INSERT_TAIL(&mngt->action_queue_todo, step, action.entry);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
      94                 :            : 
      95                 :       1629 :         return 0;
      96                 :          0 : }
      97                 :            : 
      98                 :            : static void
      99                 :        240 : free_mngt(struct ftl_mngt_process *mngt)
     100                 :            : {
     101                 :        240 :         TAILQ_HEAD(, ftl_mngt_step) steps;
     102                 :            : 
     103         [ -  + ]:        240 :         if (!mngt) {
     104                 :          0 :                 return;
     105                 :            :         }
     106                 :            : 
     107         [ #  # ]:        240 :         TAILQ_INIT(&steps);
     108   [ +  +  #  #  :        240 :         TAILQ_CONCAT(&steps, &mngt->action_queue_todo, action.entry);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     109   [ +  +  #  #  :        240 :         TAILQ_CONCAT(&steps, &mngt->action_queue_done, action.entry);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     110                 :            : 
     111         [ +  + ]:       1869 :         while (!TAILQ_EMPTY(&steps)) {
     112                 :       1629 :                 struct ftl_mngt_step *step = TAILQ_FIRST(&steps);
     113   [ +  +  #  #  :       1629 :                 TAILQ_REMOVE(&steps, step, action.entry);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     114                 :            : 
     115   [ #  #  #  # ]:       1629 :                 free(step->ctx);
     116                 :       1629 :                 free(step);
     117                 :            :         }
     118                 :            : 
     119   [ #  #  #  # ]:        240 :         free(mngt->ctx);
     120                 :        240 :         free(mngt);
     121                 :          0 : }
     122                 :            : 
     123                 :            : static struct ftl_mngt_process *
     124                 :        240 : allocate_mngt(struct spdk_ftl_dev *dev, const struct ftl_mngt_process_desc *pdesc,
     125                 :            :               ftl_mngt_completion cb, void *cb_ctx, bool silent)
     126                 :            : {
     127                 :            :         struct ftl_mngt_process *mngt;
     128                 :            : 
     129                 :            :         /* Initialize management process */
     130                 :        240 :         mngt = calloc(1, sizeof(*mngt));
     131         [ -  + ]:        240 :         if (!mngt) {
     132                 :          0 :                 goto error;
     133                 :            :         }
     134   [ #  #  #  # ]:        240 :         mngt->dev = dev;
     135   [ #  #  #  #  :        240 :         mngt->silent = silent;
                   #  # ]
     136   [ #  #  #  #  :        240 :         mngt->caller.cb = cb;
                   #  # ]
     137   [ #  #  #  #  :        240 :         mngt->caller.cb_ctx = cb_ctx;
                   #  # ]
     138   [ #  #  #  #  :        240 :         mngt->caller.thread = spdk_get_thread();
                   #  # ]
     139                 :            : 
     140                 :            :         /* Initialize process context */
     141   [ +  +  #  #  :        240 :         if (pdesc->ctx_size) {
                   #  # ]
     142   [ #  #  #  #  :         37 :                 mngt->ctx = calloc(1, pdesc->ctx_size);
             #  #  #  # ]
     143   [ -  +  #  #  :         37 :                 if (!mngt->ctx) {
                   #  # ]
     144                 :          0 :                         goto error;
     145                 :            :                 }
     146                 :          0 :         }
     147   [ #  #  #  # ]:        240 :         mngt->tsc_start = spdk_get_ticks();
     148   [ #  #  #  # ]:        240 :         mngt->desc = pdesc;
     149   [ #  #  #  #  :        240 :         TAILQ_INIT(&mngt->action_queue_todo);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     150   [ #  #  #  #  :        240 :         TAILQ_INIT(&mngt->action_queue_done);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     151   [ #  #  #  #  :        240 :         TAILQ_INIT(&mngt->rollback_queue_todo);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     152   [ #  #  #  #  :        240 :         TAILQ_INIT(&mngt->rollback_queue_done);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     153                 :            : 
     154                 :        240 :         return mngt;
     155                 :          0 : error:
     156                 :          0 :         free_mngt(mngt);
     157                 :          0 :         return NULL;
     158                 :          0 : }
     159                 :            : 
     160                 :            : static int
     161                 :        200 : _ftl_mngt_process_execute(struct spdk_ftl_dev *dev, const struct ftl_mngt_process_desc *pdesc,
     162                 :            :                           ftl_mngt_completion cb, void *cb_ctx, bool silent)
     163                 :            : {
     164                 :            :         const struct ftl_mngt_step_desc *sdesc;
     165                 :            :         struct ftl_mngt_process *mngt;
     166                 :        200 :         int rc = 0;
     167                 :            : 
     168         [ #  # ]:        200 :         mngt = allocate_mngt(dev, pdesc, cb, cb_ctx, silent);
     169         [ -  + ]:        200 :         if (!mngt) {
     170                 :          0 :                 rc = -ENOMEM;
     171                 :          0 :                 goto error;
     172                 :            :         }
     173                 :            : 
     174   [ +  +  #  #  :        200 :         if (pdesc->error_handler) {
                   #  # ]
     175                 :            :                 /* Initialize a step for error handler */
     176   [ #  #  #  #  :         22 :                 mngt->cleanup.step.desc = &mngt->cleanup.desc;
          #  #  #  #  #  
                #  #  # ]
     177   [ #  #  #  #  :         22 :                 mngt->cleanup.desc.name = "Handle ERROR";
             #  #  #  # ]
     178   [ #  #  #  #  :         22 :                 mngt->cleanup.desc.cleanup = pdesc->error_handler;
          #  #  #  #  #  
                #  #  # ]
     179                 :            : 
     180                 :            :                 /* Queue error handler to the rollback queue, it will be executed at the end */
     181   [ -  +  #  #  :         22 :                 TAILQ_INSERT_HEAD(&mngt->rollback_queue_todo, &mngt->cleanup.step,
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     182                 :            :                                   rollback.entry);
     183                 :          0 :         }
     184                 :            : 
     185                 :            :         /* Initialize steps */
     186   [ #  #  #  #  :        200 :         sdesc = mngt->desc->steps;
                   #  # ]
     187   [ +  +  #  #  :       1504 :         while (sdesc->action) {
                   #  # ]
     188                 :       1304 :                 rc = init_step(mngt, sdesc);
     189         [ -  + ]:       1304 :                 if (rc) {
     190                 :          0 :                         goto error;
     191                 :            :                 }
     192         [ #  # ]:       1304 :                 sdesc++;
     193                 :            :         }
     194                 :            : 
     195                 :        200 :         action_execute(mngt);
     196                 :        200 :         return 0;
     197                 :          0 : error:
     198                 :          0 :         free_mngt(mngt);
     199                 :          0 :         return rc;
     200                 :          0 : }
     201                 :            : 
     202                 :            : int
     203                 :         69 : ftl_mngt_process_execute(struct spdk_ftl_dev *dev, const struct ftl_mngt_process_desc *pdesc,
     204                 :            :                          ftl_mngt_completion cb, void *cb_ctx)
     205                 :            : {
     206                 :         69 :         return _ftl_mngt_process_execute(dev, pdesc, cb, cb_ctx, false);
     207                 :            : }
     208                 :            : 
     209                 :            : int
     210                 :         40 : ftl_mngt_process_rollback(struct spdk_ftl_dev *dev, const struct ftl_mngt_process_desc *pdesc,
     211                 :            :                           ftl_mngt_completion cb, void *cb_ctx)
     212                 :            : {
     213                 :            :         const struct ftl_mngt_step_desc *sdesc;
     214                 :            :         struct ftl_mngt_process *mngt;
     215                 :         40 :         int rc = 0;
     216                 :            : 
     217                 :         40 :         mngt = allocate_mngt(dev, pdesc, cb, cb_ctx, true);
     218         [ -  + ]:         40 :         if (!mngt) {
     219                 :          0 :                 rc = -ENOMEM;
     220                 :          0 :                 goto error;
     221                 :            :         }
     222                 :            : 
     223                 :            :         /* Initialize steps for rollback */
     224   [ #  #  #  #  :         40 :         sdesc = mngt->desc->steps;
                   #  # ]
     225   [ +  +  #  #  :        522 :         while (sdesc->action) {
                   #  # ]
     226   [ +  +  #  #  :        482 :                 if (!sdesc->cleanup) {
                   #  # ]
     227         [ #  # ]:        157 :                         sdesc++;
     228                 :        157 :                         continue;
     229                 :            :                 }
     230                 :        325 :                 rc = init_step(mngt, sdesc);
     231         [ -  + ]:        325 :                 if (rc) {
     232                 :          0 :                         goto error;
     233                 :            :                 }
     234         [ #  # ]:        325 :                 sdesc++;
     235                 :            :         }
     236                 :            : 
     237                 :            :         /* Build rollback list */
     238                 :            :         struct ftl_mngt_step *step;
     239   [ +  +  #  #  :        365 :         TAILQ_FOREACH(step, &mngt->action_queue_todo, action.entry) {
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     240   [ #  #  #  #  :        325 :                 step->action.silent = true;
                   #  # ]
     241   [ +  +  #  #  :        325 :                 TAILQ_INSERT_HEAD(&mngt->rollback_queue_todo, step,
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     242                 :            :                                   rollback.entry);
     243                 :          0 :         }
     244                 :            : 
     245   [ #  #  #  # ]:         40 :         mngt->rollback = true;
     246                 :         40 :         rollback_execute(mngt);
     247                 :         40 :         return 0;
     248                 :          0 : error:
     249                 :          0 :         free_mngt(mngt);
     250                 :          0 :         return rc;
     251                 :          0 : }
     252                 :            : 
     253                 :            : struct spdk_ftl_dev *
     254                 :        114 : ftl_mngt_get_dev(struct ftl_mngt_process *mngt)
     255                 :            : {
     256   [ #  #  #  # ]:        114 :         return mngt->dev;
     257                 :            : }
     258                 :            : 
     259                 :            : int
     260                 :         35 : ftl_mngt_alloc_step_ctx(struct ftl_mngt_process *mngt, size_t size)
     261                 :            : {
     262                 :         35 :         struct ftl_mngt_step *step = get_current_step(mngt);
     263                 :         35 :         void *arg = calloc(1, size);
     264                 :            : 
     265         [ -  + ]:         35 :         if (!arg) {
     266                 :          0 :                 return -ENOMEM;
     267                 :            :         }
     268                 :            : 
     269   [ #  #  #  # ]:         35 :         free(step->ctx);
     270   [ #  #  #  # ]:         35 :         step->ctx = arg;
     271                 :            : 
     272                 :         35 :         return 0;
     273                 :          0 : }
     274                 :            : 
     275                 :            : void *
     276                 :       1693 : ftl_mngt_get_step_ctx(struct ftl_mngt_process *mngt)
     277                 :            : {
     278   [ #  #  #  # ]:       1693 :         return get_current_step(mngt)->ctx;
     279                 :            : }
     280                 :            : 
     281                 :            : void *
     282                 :         53 : ftl_mngt_get_process_ctx(struct ftl_mngt_process *mngt)
     283                 :            : {
     284   [ #  #  #  # ]:         53 :         return mngt->ctx;
     285                 :            : }
     286                 :            : 
     287                 :            : void *
     288                 :         22 : ftl_mngt_get_caller_ctx(struct ftl_mngt_process *mngt)
     289                 :            : {
     290   [ #  #  #  #  :         22 :         return mngt->caller.cb_ctx;
                   #  # ]
     291                 :            : }
     292                 :            : 
     293                 :            : void
     294                 :       1626 : ftl_mngt_next_step(struct ftl_mngt_process *mngt)
     295                 :            : {
     296   [ +  +  +  +  :       1626 :         if (false == mngt->rollback) {
             #  #  #  # ]
     297                 :       1286 :                 action_next(mngt);
     298                 :          0 :         } else {
     299                 :        340 :                 rollback_next(mngt);
     300                 :            :         }
     301                 :       1626 : }
     302                 :            : 
     303                 :            : void
     304                 :         23 : ftl_mngt_skip_step(struct ftl_mngt_process *mngt)
     305                 :            : {
     306   [ -  +  +  +  :         23 :         if (mngt->rollback) {
             #  #  #  # ]
     307   [ #  #  #  #  :         22 :                 get_current_step(mngt)->rollback.silent = true;
                   #  # ]
     308                 :          0 :         } else {
     309   [ #  #  #  #  :          1 :                 get_current_step(mngt)->action.silent = true;
                   #  # ]
     310                 :            :         }
     311                 :         23 :         ftl_mngt_next_step(mngt);
     312                 :         23 : }
     313                 :            : 
     314                 :            : void
     315                 :     208141 : ftl_mngt_continue_step(struct ftl_mngt_process *mngt)
     316                 :            : {
     317                 :            : 
     318   [ +  +  +  -  :     208141 :         if (!mngt->continuing) {
             #  #  #  # ]
     319   [ +  +  +  +  :     208141 :                 if (false == mngt->rollback) {
             #  #  #  # ]
     320                 :     208129 :                         action_execute(mngt);
     321                 :          0 :                 } else {
     322                 :         12 :                         rollback_execute(mngt);
     323                 :            :                 }
     324                 :          0 :         }
     325                 :            : 
     326   [ #  #  #  # ]:     208141 :         mngt->continuing = true;
     327                 :     208141 : }
     328                 :            : 
     329                 :            : static void
     330                 :        159 : child_cb(struct spdk_ftl_dev *dev, void *ctx, int status)
     331                 :            : {
     332                 :        159 :         struct ftl_mngt_process *parent = ctx;
     333                 :            : 
     334         [ +  + ]:        159 :         if (status) {
     335                 :          3 :                 ftl_mngt_fail_step(parent);
     336                 :          0 :         } else {
     337                 :        156 :                 ftl_mngt_next_step(parent);
     338                 :            :         }
     339                 :        159 : }
     340                 :            : 
     341                 :            : void
     342                 :        131 : ftl_mngt_call_process(struct ftl_mngt_process *mngt,
     343                 :            :                       const struct ftl_mngt_process_desc *pdesc)
     344                 :            : {
     345   [ -  +  #  #  :        131 :         if (_ftl_mngt_process_execute(mngt->dev, pdesc, child_cb, mngt, true)) {
                   #  # ]
     346                 :          0 :                 ftl_mngt_fail_step(mngt);
     347                 :          0 :         } else {
     348   [ +  +  +  +  :        131 :                 if (mngt->rollback) {
             #  #  #  # ]
     349   [ #  #  #  #  :          3 :                         get_current_step(mngt)->rollback.silent = true;
                   #  # ]
     350                 :          0 :                 } else {
     351   [ #  #  #  #  :        128 :                         get_current_step(mngt)->action.silent = true;
                   #  # ]
     352                 :            :                 }
     353                 :            :         }
     354                 :        131 : }
     355                 :            : 
     356                 :            : void
     357                 :         28 : ftl_mngt_call_process_rollback(struct ftl_mngt_process *mngt,
     358                 :            :                                const struct ftl_mngt_process_desc *pdesc)
     359                 :            : {
     360   [ -  +  #  #  :         28 :         if (ftl_mngt_process_rollback(mngt->dev, pdesc, child_cb, mngt)) {
                   #  # ]
     361                 :          0 :                 ftl_mngt_fail_step(mngt);
     362                 :          0 :         } else {
     363   [ +  +  +  +  :         28 :                 if (mngt->rollback) {
             #  #  #  # ]
     364   [ #  #  #  #  :          3 :                         get_current_step(mngt)->rollback.silent = true;
                   #  # ]
     365                 :          0 :                 } else {
     366   [ #  #  #  #  :         25 :                         get_current_step(mngt)->action.silent = true;
                   #  # ]
     367                 :            :                 }
     368                 :            :         }
     369                 :         28 : }
     370                 :            : 
     371                 :            : void
     372                 :          9 : ftl_mngt_fail_step(struct ftl_mngt_process *mngt)
     373                 :            : {
     374   [ #  #  #  # ]:          9 :         mngt->status = -1;
     375                 :            : 
     376   [ +  +  +  -  :          9 :         if (false == mngt->rollback) {
             #  #  #  # ]
     377                 :          9 :                 action_done(mngt, -1);
     378                 :          0 :         } else {
     379                 :          0 :                 rollback_done(mngt, -1);
     380                 :            :         }
     381                 :            : 
     382   [ #  #  #  # ]:          9 :         mngt->rollback = true;
     383                 :          9 :         rollback_execute(mngt);
     384                 :          9 : }
     385                 :            : 
     386                 :            : static inline float
     387                 :       1522 : tsc_to_ms(uint64_t tsc)
     388                 :            : {
     389                 :       1522 :         float ms = tsc;
     390                 :       1522 :         ms /= (float)spdk_get_ticks_hz();
     391                 :       1522 :         ms *= 1000.0;
     392                 :       1522 :         return ms;
     393                 :            : }
     394                 :            : 
     395                 :            : static void
     396                 :       1635 : trace_step(struct spdk_ftl_dev *dev, struct ftl_mngt_step *step, bool rollback)
     397                 :            : {
     398                 :            :         uint64_t duration;
     399         [ +  + ]:       1635 :         const char *what = rollback ? "Rollback" : "Action";
     400   [ +  +  #  #  :       1635 :         int silent = rollback ? step->rollback.silent : step->action.silent;
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     401                 :            : 
     402         [ +  + ]:       1635 :         if (silent) {
     403                 :        182 :                 return;
     404                 :            :         }
     405                 :            : 
     406   [ +  -  #  #  :       1453 :         FTL_NOTICELOG(dev, "%s\n", what);
             #  #  #  # ]
     407   [ +  -  #  #  :       1453 :         FTL_NOTICELOG(dev, "\t name:     %s\n", step->desc->name);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     408   [ #  #  #  #  :       1453 :         duration = step->action.stop - step->action.start;
          #  #  #  #  #  
                #  #  # ]
     409   [ +  -  #  #  :       1453 :         FTL_NOTICELOG(dev, "\t duration: %.3f ms\n", tsc_to_ms(duration));
             #  #  #  # ]
     410   [ +  -  #  #  :       1453 :         FTL_NOTICELOG(dev, "\t status:   %d\n", step->action.status);
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     411                 :          0 : }
     412                 :            : 
     413                 :            : static void
     414                 :        240 : finish_msg(void *ctx)
     415                 :            : {
     416                 :        240 :         struct ftl_mngt_process *mngt = ctx;
     417                 :        240 :         char *devname = NULL;
     418                 :            : 
     419   [ +  +  +  +  :        240 :         if (!mngt->silent && mngt->dev->conf.name) {
          +  +  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     420                 :            :                 /* the callback below can free the device so make a temp copy of the name */
     421   [ -  +  #  #  :         51 :                 devname = strdup(mngt->dev->conf.name);
          #  #  #  #  #  
                #  #  # ]
     422                 :          0 :         }
     423                 :            : 
     424   [ #  #  #  #  :        240 :         mngt->caller.cb(mngt->dev, mngt->caller.cb_ctx, mngt->status);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     425                 :            : 
     426   [ +  +  +  +  :        240 :         if (!mngt->silent) {
             #  #  #  # ]
     427                 :            :                 /* TODO: refactor the logging macros to pass just the name instead of device */
     428                 :         69 :                 struct spdk_ftl_dev tmpdev = {
     429                 :          0 :                         .conf = {
     430                 :          0 :                                 .name = devname
     431                 :            :                         }
     432                 :            :                 };
     433                 :            : 
     434   [ #  #  #  #  :         69 :                 FTL_NOTICELOG(&tmpdev, "Management process finished, name '%s', duration = %.3f ms, result %d\n",
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     435                 :            :                               mngt->desc->name,
     436                 :            :                               tsc_to_ms(mngt->tsc_stop - mngt->tsc_start),
     437                 :            :                               mngt->status);
     438                 :          0 :         }
     439                 :        240 :         free_mngt(mngt);
     440                 :        240 :         free(devname);
     441                 :        240 : }
     442                 :            : 
     443                 :            : void
     444                 :        240 : ftl_mngt_finish(struct ftl_mngt_process *mngt)
     445                 :            : {
     446   [ #  #  #  # ]:        240 :         mngt->tsc_stop = spdk_get_ticks();
     447   [ #  #  #  #  :        240 :         spdk_thread_send_msg(mngt->caller.thread, finish_msg, mngt);
                   #  # ]
     448                 :        240 : }
     449                 :            : 
     450                 :            : /*
     451                 :            :  * Actions
     452                 :            :  */
     453                 :            : static void
     454                 :       1286 : action_next(struct ftl_mngt_process *mngt)
     455                 :            : {
     456   [ -  +  #  #  :       1286 :         if (TAILQ_EMPTY(&mngt->action_queue_todo)) {
             #  #  #  # ]
     457                 :            :                 /* Nothing to do, finish the management process */
     458                 :          0 :                 ftl_mngt_finish(mngt);
     459                 :          0 :                 return;
     460                 :            :         } else {
     461                 :       1286 :                 action_done(mngt, 0);
     462                 :       1286 :                 action_execute(mngt);
     463                 :            :         }
     464                 :          0 : }
     465                 :            : 
     466                 :            : static void
     467                 :     209615 : action_msg(void *ctx)
     468                 :            : {
     469                 :     209615 :         struct ftl_mngt_process *mngt = ctx;
     470                 :            :         struct ftl_mngt_step *step;
     471                 :            : 
     472   [ #  #  #  # ]:     209615 :         mngt->continuing = false;
     473                 :            : 
     474   [ +  +  #  #  :     209615 :         if (TAILQ_EMPTY(&mngt->action_queue_todo)) {
             #  #  #  # ]
     475                 :        191 :                 ftl_mngt_finish(mngt);
     476                 :        191 :                 return;
     477                 :            :         }
     478                 :            : 
     479   [ #  #  #  #  :     209424 :         step = TAILQ_FIRST(&mngt->action_queue_todo);
                   #  # ]
     480   [ +  +  #  #  :     209424 :         if (!step->action.start) {
             #  #  #  # ]
     481   [ #  #  #  #  :       1307 :                 step->action.start = spdk_get_ticks();
                   #  # ]
     482                 :          0 :         }
     483   [ #  #  #  #  :     209424 :         step->desc->action(mngt->dev, mngt);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     484                 :          0 : }
     485                 :            : 
     486                 :            : static void
     487                 :     209615 : action_execute(struct ftl_mngt_process *mngt)
     488                 :            : {
     489   [ #  #  #  #  :     209615 :         spdk_thread_send_msg(mngt->dev->core_thread, action_msg, mngt);
             #  #  #  # ]
     490                 :     209615 : }
     491                 :            : 
     492                 :            : static void
     493                 :       1295 : action_done(struct ftl_mngt_process *mngt, int status)
     494                 :            : {
     495                 :            :         struct ftl_mngt_step *step;
     496                 :            : 
     497   [ -  +  #  #  :       1295 :         assert(!TAILQ_EMPTY(&mngt->action_queue_todo));
          #  #  #  #  #  
                      # ]
     498   [ #  #  #  #  :       1295 :         step = TAILQ_FIRST(&mngt->action_queue_todo);
                   #  # ]
     499   [ +  +  #  #  :       1295 :         TAILQ_REMOVE(&mngt->action_queue_todo, step, action.entry);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     500                 :            : 
     501   [ #  #  #  #  :       1295 :         TAILQ_INSERT_TAIL(&mngt->action_queue_done, step, action.entry);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     502   [ +  +  #  #  :       1295 :         if (step->desc->cleanup) {
          #  #  #  #  #  
                      # ]
     503   [ +  +  #  #  :        413 :                 TAILQ_INSERT_HEAD(&mngt->rollback_queue_todo, step,
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     504                 :            :                                   rollback.entry);
     505                 :          0 :         }
     506                 :            : 
     507   [ #  #  #  #  :       1295 :         step->action.stop = spdk_get_ticks();
                   #  # ]
     508   [ #  #  #  #  :       1295 :         step->action.status = status;
                   #  # ]
     509                 :            : 
     510   [ #  #  #  # ]:       1295 :         trace_step(mngt->dev, step, false);
     511                 :       1295 : }
     512                 :            : 
     513                 :            : /*
     514                 :            :  * Rollback
     515                 :            :  */
     516                 :            : static void
     517                 :        340 : rollback_next(struct ftl_mngt_process *mngt)
     518                 :            : {
     519   [ -  +  #  #  :        340 :         if (TAILQ_EMPTY(&mngt->rollback_queue_todo)) {
             #  #  #  # ]
     520                 :            :                 /* Nothing to do, finish the management process */
     521                 :          0 :                 ftl_mngt_finish(mngt);
     522                 :          0 :                 return;
     523                 :            :         } else {
     524                 :        340 :                 rollback_done(mngt, 0);
     525                 :        340 :                 rollback_execute(mngt);
     526                 :            :         }
     527                 :          0 : }
     528                 :            : 
     529                 :            : static void
     530                 :        401 : rollback_msg(void *ctx)
     531                 :            : {
     532                 :        401 :         struct ftl_mngt_process *mngt = ctx;
     533                 :            :         struct ftl_mngt_step *step;
     534                 :            : 
     535   [ #  #  #  # ]:        401 :         mngt->continuing = false;
     536                 :            : 
     537   [ +  +  #  #  :        401 :         if (TAILQ_EMPTY(&mngt->rollback_queue_todo)) {
             #  #  #  # ]
     538                 :         49 :                 ftl_mngt_finish(mngt);
     539                 :         49 :                 return;
     540                 :            :         }
     541                 :            : 
     542   [ #  #  #  #  :        352 :         step = TAILQ_FIRST(&mngt->rollback_queue_todo);
                   #  # ]
     543   [ +  -  #  #  :        352 :         if (!step->rollback.start) {
             #  #  #  # ]
     544   [ #  #  #  #  :        352 :                 step->rollback.start = spdk_get_ticks();
                   #  # ]
     545                 :          0 :         }
     546   [ #  #  #  #  :        352 :         step->desc->cleanup(mngt->dev, mngt);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     547                 :          0 : }
     548                 :            : 
     549                 :            : static void
     550                 :        401 : rollback_execute(struct ftl_mngt_process *mngt)
     551                 :            : {
     552   [ #  #  #  #  :        401 :         spdk_thread_send_msg(mngt->dev->core_thread, rollback_msg, mngt);
             #  #  #  # ]
     553                 :        401 : }
     554                 :            : 
     555                 :            : void
     556                 :        340 : rollback_done(struct ftl_mngt_process *mngt, int status)
     557                 :            : {
     558                 :            :         struct ftl_mngt_step *step;
     559                 :            : 
     560   [ -  +  #  #  :        340 :         assert(!TAILQ_EMPTY(&mngt->rollback_queue_todo));
          #  #  #  #  #  
                      # ]
     561   [ #  #  #  #  :        340 :         step = TAILQ_FIRST(&mngt->rollback_queue_todo);
                   #  # ]
     562   [ +  +  #  #  :        340 :         TAILQ_REMOVE(&mngt->rollback_queue_todo, step, rollback.entry);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     563   [ #  #  #  #  :        340 :         TAILQ_INSERT_TAIL(&mngt->rollback_queue_done, step, rollback.entry);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     564                 :            : 
     565   [ #  #  #  #  :        340 :         step->rollback.stop = spdk_get_ticks();
                   #  # ]
     566   [ #  #  #  #  :        340 :         step->rollback.status = status;
                   #  # ]
     567                 :            : 
     568   [ #  #  #  # ]:        340 :         trace_step(mngt->dev, step,  true);
     569                 :        340 : }

Generated by: LCOV version 1.15