LCOV - code coverage report
Current view: top level - spdk/lib/ftl/mngt - ftl_mngt.c (source / functions) Hit Total Coverage
Test: Combined Lines: 223 252 88.5 %
Date: 2024-07-12 00:10:58 Functions: 31 31 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 108 134 80.6 %

           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                 :       2060 : get_current_step(struct ftl_mngt_process *mngt)
      65                 :            : {
      66   [ +  +  +  + ]:       2060 :         if (!mngt->rollback) {
      67                 :       1978 :                 return TAILQ_FIRST(&mngt->action_queue_todo);
      68                 :            :         } else {
      69                 :         82 :                 return TAILQ_FIRST(&mngt->rollback_queue_todo);
      70                 :            :         }
      71                 :            : }
      72                 :            : 
      73                 :            : static int
      74                 :       1740 : init_step(struct ftl_mngt_process *mngt,
      75                 :            :           const struct ftl_mngt_step_desc *desc)
      76                 :            : {
      77                 :            :         struct ftl_mngt_step *step;
      78                 :            : 
      79                 :       1740 :         step = calloc(1, sizeof(*step));
      80         [ -  + ]:       1740 :         if (!step) {
      81                 :          0 :                 return -ENOMEM;
      82                 :            :         }
      83                 :            : 
      84                 :            :         /* Initialize the step's argument */
      85         [ +  + ]:       1740 :         if (desc->ctx_size) {
      86                 :         34 :                 step->ctx = calloc(1, desc->ctx_size);
      87         [ -  + ]:         34 :                 if (!step->ctx) {
      88                 :          0 :                         free(step);
      89                 :          0 :                         return -ENOMEM;
      90                 :            :                 }
      91                 :            :         }
      92                 :       1740 :         step->desc = desc;
      93                 :       1740 :         TAILQ_INSERT_TAIL(&mngt->action_queue_todo, step, action.entry);
      94                 :            : 
      95                 :       1740 :         return 0;
      96                 :            : }
      97                 :            : 
      98                 :            : static void
      99                 :        285 : free_mngt(struct ftl_mngt_process *mngt)
     100                 :            : {
     101                 :        270 :         TAILQ_HEAD(, ftl_mngt_step) steps;
     102                 :            : 
     103         [ -  + ]:        285 :         if (!mngt) {
     104                 :          0 :                 return;
     105                 :            :         }
     106                 :            : 
     107                 :        285 :         TAILQ_INIT(&steps);
     108         [ +  + ]:        285 :         TAILQ_CONCAT(&steps, &mngt->action_queue_todo, action.entry);
     109         [ +  + ]:        285 :         TAILQ_CONCAT(&steps, &mngt->action_queue_done, action.entry);
     110                 :            : 
     111         [ +  + ]:       2025 :         while (!TAILQ_EMPTY(&steps)) {
     112                 :       1740 :                 struct ftl_mngt_step *step = TAILQ_FIRST(&steps);
     113         [ +  + ]:       1740 :                 TAILQ_REMOVE(&steps, step, action.entry);
     114                 :            : 
     115                 :       1740 :                 free(step->ctx);
     116                 :       1740 :                 free(step);
     117                 :            :         }
     118                 :            : 
     119                 :        285 :         free(mngt->ctx);
     120                 :        285 :         free(mngt);
     121                 :            : }
     122                 :            : 
     123                 :            : static struct ftl_mngt_process *
     124                 :        285 : 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                 :        285 :         mngt = calloc(1, sizeof(*mngt));
     131         [ -  + ]:        285 :         if (!mngt) {
     132                 :          0 :                 goto error;
     133                 :            :         }
     134                 :        285 :         mngt->dev = dev;
     135                 :        285 :         mngt->silent = silent;
     136                 :        285 :         mngt->caller.cb = cb;
     137                 :        285 :         mngt->caller.cb_ctx = cb_ctx;
     138                 :        285 :         mngt->caller.thread = spdk_get_thread();
     139                 :            : 
     140                 :            :         /* Initialize process context */
     141         [ +  + ]:        285 :         if (pdesc->ctx_size) {
     142                 :         43 :                 mngt->ctx = calloc(1, pdesc->ctx_size);
     143         [ -  + ]:         43 :                 if (!mngt->ctx) {
     144                 :          0 :                         goto error;
     145                 :            :                 }
     146                 :            :         }
     147                 :        285 :         mngt->tsc_start = spdk_get_ticks();
     148                 :        285 :         mngt->desc = pdesc;
     149                 :        285 :         TAILQ_INIT(&mngt->action_queue_todo);
     150                 :        285 :         TAILQ_INIT(&mngt->action_queue_done);
     151                 :        285 :         TAILQ_INIT(&mngt->rollback_queue_todo);
     152                 :        285 :         TAILQ_INIT(&mngt->rollback_queue_done);
     153                 :            : 
     154                 :        285 :         return mngt;
     155                 :          0 : error:
     156                 :          0 :         free_mngt(mngt);
     157                 :          0 :         return NULL;
     158                 :            : }
     159                 :            : 
     160                 :            : static int
     161                 :        227 : _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                 :        227 :         int rc = 0;
     167                 :            : 
     168                 :        227 :         mngt = allocate_mngt(dev, pdesc, cb, cb_ctx, silent);
     169         [ -  + ]:        227 :         if (!mngt) {
     170                 :          0 :                 rc = -ENOMEM;
     171                 :          0 :                 goto error;
     172                 :            :         }
     173                 :            : 
     174         [ +  + ]:        227 :         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                 :            :         }
     184                 :            : 
     185                 :            :         /* Initialize steps */
     186                 :        227 :         sdesc = mngt->desc->steps;
     187         [ +  + ]:       1603 :         while (sdesc->action) {
     188                 :       1376 :                 rc = init_step(mngt, sdesc);
     189         [ -  + ]:       1376 :                 if (rc) {
     190                 :          0 :                         goto error;
     191                 :            :                 }
     192                 :       1376 :                 sdesc++;
     193                 :            :         }
     194                 :            : 
     195                 :        227 :         action_execute(mngt);
     196                 :        227 :         return 0;
     197                 :          0 : error:
     198                 :          0 :         free_mngt(mngt);
     199                 :          0 :         return rc;
     200                 :            : }
     201                 :            : 
     202                 :            : int
     203                 :         87 : 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                 :         87 :         return _ftl_mngt_process_execute(dev, pdesc, cb, cb_ctx, false);
     207                 :            : }
     208                 :            : 
     209                 :            : int
     210                 :         58 : 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                 :         58 :         int rc = 0;
     216                 :            : 
     217                 :         58 :         mngt = allocate_mngt(dev, pdesc, cb, cb_ctx, true);
     218         [ -  + ]:         58 :         if (!mngt) {
     219                 :          0 :                 rc = -ENOMEM;
     220                 :          0 :                 goto error;
     221                 :            :         }
     222                 :            : 
     223                 :            :         /* Initialize steps for rollback */
     224                 :         58 :         sdesc = mngt->desc->steps;
     225         [ +  + ]:        582 :         while (sdesc->action) {
     226         [ +  + ]:        524 :                 if (!sdesc->cleanup) {
     227                 :        160 :                         sdesc++;
     228                 :        160 :                         continue;
     229                 :            :                 }
     230                 :        364 :                 rc = init_step(mngt, sdesc);
     231         [ -  + ]:        364 :                 if (rc) {
     232                 :          0 :                         goto error;
     233                 :            :                 }
     234                 :        364 :                 sdesc++;
     235                 :            :         }
     236                 :            : 
     237                 :            :         /* Build rollback list */
     238                 :            :         struct ftl_mngt_step *step;
     239         [ +  + ]:        422 :         TAILQ_FOREACH(step, &mngt->action_queue_todo, action.entry) {
     240                 :        364 :                 step->action.silent = true;
     241         [ +  + ]:        364 :                 TAILQ_INSERT_HEAD(&mngt->rollback_queue_todo, step,
     242                 :            :                                   rollback.entry);
     243                 :            :         }
     244                 :            : 
     245                 :         58 :         mngt->rollback = true;
     246                 :         58 :         rollback_execute(mngt);
     247                 :         58 :         return 0;
     248                 :          0 : error:
     249                 :          0 :         free_mngt(mngt);
     250                 :          0 :         return rc;
     251                 :            : }
     252                 :            : 
     253                 :            : struct spdk_ftl_dev *
     254                 :        138 : ftl_mngt_get_dev(struct ftl_mngt_process *mngt)
     255                 :            : {
     256                 :        138 :         return mngt->dev;
     257                 :            : }
     258                 :            : 
     259                 :            : int
     260                 :         47 : ftl_mngt_alloc_step_ctx(struct ftl_mngt_process *mngt, size_t size)
     261                 :            : {
     262                 :         47 :         struct ftl_mngt_step *step = get_current_step(mngt);
     263                 :         47 :         void *arg = calloc(1, size);
     264                 :            : 
     265         [ -  + ]:         47 :         if (!arg) {
     266                 :          0 :                 return -ENOMEM;
     267                 :            :         }
     268                 :            : 
     269                 :         47 :         free(step->ctx);
     270                 :         47 :         step->ctx = arg;
     271                 :            : 
     272                 :         47 :         return 0;
     273                 :            : }
     274                 :            : 
     275                 :            : void *
     276                 :       1816 : ftl_mngt_get_step_ctx(struct ftl_mngt_process *mngt)
     277                 :            : {
     278                 :       1816 :         return get_current_step(mngt)->ctx;
     279                 :            : }
     280                 :            : 
     281                 :            : void *
     282                 :         65 : ftl_mngt_get_process_ctx(struct ftl_mngt_process *mngt)
     283                 :            : {
     284                 :         65 :         return mngt->ctx;
     285                 :            : }
     286                 :            : 
     287                 :            : void *
     288                 :         34 : ftl_mngt_get_caller_ctx(struct ftl_mngt_process *mngt)
     289                 :            : {
     290                 :         34 :         return mngt->caller.cb_ctx;
     291                 :            : }
     292                 :            : 
     293                 :            : void
     294                 :       1734 : ftl_mngt_next_step(struct ftl_mngt_process *mngt)
     295                 :            : {
     296   [ +  +  +  + ]:       1734 :         if (false == mngt->rollback) {
     297                 :       1340 :                 action_next(mngt);
     298                 :            :         } else {
     299                 :        394 :                 rollback_next(mngt);
     300                 :            :         }
     301                 :       1734 : }
     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                 :            :         } else {
     309                 :          1 :                 get_current_step(mngt)->action.silent = true;
     310                 :            :         }
     311                 :         23 :         ftl_mngt_next_step(mngt);
     312                 :         23 : }
     313                 :            : 
     314                 :            : void
     315                 :     203656 : ftl_mngt_continue_step(struct ftl_mngt_process *mngt)
     316                 :            : {
     317                 :            : 
     318   [ +  +  +  - ]:     203656 :         if (!mngt->continuing) {
     319   [ +  +  +  + ]:     203656 :                 if (false == mngt->rollback) {
     320                 :     203632 :                         action_execute(mngt);
     321                 :            :                 } else {
     322                 :         24 :                         rollback_execute(mngt);
     323                 :            :                 }
     324                 :            :         }
     325                 :            : 
     326                 :     203656 :         mngt->continuing = true;
     327                 :     203656 : }
     328                 :            : 
     329                 :            : static void
     330                 :        174 : child_cb(struct spdk_ftl_dev *dev, void *ctx, int status)
     331                 :            : {
     332                 :        174 :         struct ftl_mngt_process *parent = ctx;
     333                 :            : 
     334         [ +  + ]:        174 :         if (status) {
     335                 :          6 :                 ftl_mngt_fail_step(parent);
     336                 :            :         } else {
     337                 :        168 :                 ftl_mngt_next_step(parent);
     338                 :            :         }
     339                 :        174 : }
     340                 :            : 
     341                 :            : void
     342                 :        140 : ftl_mngt_call_process(struct ftl_mngt_process *mngt,
     343                 :            :                       const struct ftl_mngt_process_desc *pdesc)
     344                 :            : {
     345         [ -  + ]:        140 :         if (_ftl_mngt_process_execute(mngt->dev, pdesc, child_cb, mngt, true)) {
     346                 :          0 :                 ftl_mngt_fail_step(mngt);
     347                 :            :         } else {
     348   [ +  +  +  + ]:        140 :                 if (mngt->rollback) {
     349                 :          6 :                         get_current_step(mngt)->rollback.silent = true;
     350                 :            :                 } else {
     351                 :        134 :                         get_current_step(mngt)->action.silent = true;
     352                 :            :                 }
     353                 :            :         }
     354                 :        140 : }
     355                 :            : 
     356                 :            : void
     357                 :         34 : ftl_mngt_call_process_rollback(struct ftl_mngt_process *mngt,
     358                 :            :                                const struct ftl_mngt_process_desc *pdesc)
     359                 :            : {
     360         [ -  + ]:         34 :         if (ftl_mngt_process_rollback(mngt->dev, pdesc, child_cb, mngt)) {
     361                 :          0 :                 ftl_mngt_fail_step(mngt);
     362                 :            :         } else {
     363   [ +  +  +  + ]:         34 :                 if (mngt->rollback) {
     364                 :          6 :                         get_current_step(mngt)->rollback.silent = true;
     365                 :            :                 } else {
     366                 :         28 :                         get_current_step(mngt)->action.silent = true;
     367                 :            :                 }
     368                 :            :         }
     369                 :         34 : }
     370                 :            : 
     371                 :            : void
     372                 :         18 : ftl_mngt_fail_step(struct ftl_mngt_process *mngt)
     373                 :            : {
     374                 :         18 :         mngt->status = -1;
     375                 :            : 
     376   [ +  +  +  - ]:         18 :         if (false == mngt->rollback) {
     377                 :         18 :                 action_done(mngt, -1);
     378                 :            :         } else {
     379                 :          0 :                 rollback_done(mngt, -1);
     380                 :            :         }
     381                 :            : 
     382                 :         18 :         mngt->rollback = true;
     383                 :         18 :         rollback_execute(mngt);
     384                 :         18 : }
     385                 :            : 
     386                 :            : static inline float
     387                 :       1642 : tsc_to_ms(uint64_t tsc)
     388                 :            : {
     389                 :       1642 :         float ms = tsc;
     390                 :       1642 :         ms /= (float)spdk_get_ticks_hz();
     391                 :       1642 :         ms *= 1000.0;
     392                 :       1642 :         return ms;
     393                 :            : }
     394                 :            : 
     395                 :            : static void
     396                 :       1752 : trace_step(struct spdk_ftl_dev *dev, struct ftl_mngt_step *step, bool rollback)
     397                 :            : {
     398                 :            :         uint64_t duration;
     399         [ +  + ]:       1752 :         const char *what = rollback ? "Rollback" : "Action";
     400         [ +  + ]:       1752 :         int silent = rollback ? step->rollback.silent : step->action.silent;
     401                 :            : 
     402         [ +  + ]:       1752 :         if (silent) {
     403                 :        197 :                 return;
     404                 :            :         }
     405                 :            : 
     406         [ +  - ]:       1555 :         FTL_NOTICELOG(dev, "%s\n", what);
     407         [ +  - ]:       1555 :         FTL_NOTICELOG(dev, "\t name:     %s\n", step->desc->name);
     408                 :       1555 :         duration = step->action.stop - step->action.start;
     409         [ +  - ]:       1555 :         FTL_NOTICELOG(dev, "\t duration: %.3f ms\n", tsc_to_ms(duration));
     410         [ +  - ]:       1555 :         FTL_NOTICELOG(dev, "\t status:   %d\n", step->action.status);
     411                 :            : }
     412                 :            : 
     413                 :            : static void
     414                 :        285 : finish_msg(void *ctx)
     415                 :            : {
     416                 :        285 :         struct ftl_mngt_process *mngt = ctx;
     417                 :        285 :         char *devname = NULL;
     418                 :            : 
     419   [ +  +  +  +  :        285 :         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                 :            :         }
     423                 :            : 
     424                 :        285 :         mngt->caller.cb(mngt->dev, mngt->caller.cb_ctx, mngt->status);
     425                 :            : 
     426   [ +  +  +  + ]:        285 :         if (!mngt->silent) {
     427                 :            :                 /* TODO: refactor the logging macros to pass just the name instead of device */
     428                 :         87 :                 struct spdk_ftl_dev tmpdev = {
     429                 :            :                         .conf = {
     430                 :            :                                 .name = devname
     431                 :            :                         }
     432                 :            :                 };
     433                 :            : 
     434                 :         87 :                 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                 :            :         }
     439                 :        285 :         free_mngt(mngt);
     440                 :        285 :         free(devname);
     441                 :        285 : }
     442                 :            : 
     443                 :            : void
     444                 :        285 : ftl_mngt_finish(struct ftl_mngt_process *mngt)
     445                 :            : {
     446                 :        285 :         mngt->tsc_stop = spdk_get_ticks();
     447                 :        285 :         spdk_thread_send_msg(mngt->caller.thread, finish_msg, mngt);
     448                 :        285 : }
     449                 :            : 
     450                 :            : /*
     451                 :            :  * Actions
     452                 :            :  */
     453                 :            : static void
     454                 :       1340 : action_next(struct ftl_mngt_process *mngt)
     455                 :            : {
     456         [ -  + ]:       1340 :         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                 :       1340 :                 action_done(mngt, 0);
     462                 :       1340 :                 action_execute(mngt);
     463                 :            :         }
     464                 :            : }
     465                 :            : 
     466                 :            : static void
     467                 :     205199 : action_msg(void *ctx)
     468                 :            : {
     469                 :     205199 :         struct ftl_mngt_process *mngt = ctx;
     470                 :            :         struct ftl_mngt_step *step;
     471                 :            : 
     472                 :     205199 :         mngt->continuing = false;
     473                 :            : 
     474         [ +  + ]:     205199 :         if (TAILQ_EMPTY(&mngt->action_queue_todo)) {
     475                 :        209 :                 ftl_mngt_finish(mngt);
     476                 :        209 :                 return;
     477                 :            :         }
     478                 :            : 
     479                 :     204990 :         step = TAILQ_FIRST(&mngt->action_queue_todo);
     480         [ +  + ]:     204990 :         if (!step->action.start) {
     481                 :       1382 :                 step->action.start = spdk_get_ticks();
     482                 :            :         }
     483                 :     204990 :         step->desc->action(mngt->dev, mngt);
     484                 :            : }
     485                 :            : 
     486                 :            : static void
     487                 :     205199 : action_execute(struct ftl_mngt_process *mngt)
     488                 :            : {
     489                 :     205199 :         spdk_thread_send_msg(mngt->dev->core_thread, action_msg, mngt);
     490                 :     205199 : }
     491                 :            : 
     492                 :            : static void
     493                 :       1358 : action_done(struct ftl_mngt_process *mngt, int status)
     494                 :            : {
     495                 :            :         struct ftl_mngt_step *step;
     496                 :            : 
     497         [ -  + ]:       1358 :         assert(!TAILQ_EMPTY(&mngt->action_queue_todo));
     498                 :       1358 :         step = TAILQ_FIRST(&mngt->action_queue_todo);
     499         [ +  + ]:       1358 :         TAILQ_REMOVE(&mngt->action_queue_todo, step, action.entry);
     500                 :            : 
     501                 :       1358 :         TAILQ_INSERT_TAIL(&mngt->action_queue_done, step, action.entry);
     502         [ +  + ]:       1358 :         if (step->desc->cleanup) {
     503         [ +  + ]:        467 :                 TAILQ_INSERT_HEAD(&mngt->rollback_queue_todo, step,
     504                 :            :                                   rollback.entry);
     505                 :            :         }
     506                 :            : 
     507                 :       1358 :         step->action.stop = spdk_get_ticks();
     508                 :       1358 :         step->action.status = status;
     509                 :            : 
     510                 :       1358 :         trace_step(mngt->dev, step, false);
     511                 :       1358 : }
     512                 :            : 
     513                 :            : /*
     514                 :            :  * Rollback
     515                 :            :  */
     516                 :            : static void
     517                 :        394 : rollback_next(struct ftl_mngt_process *mngt)
     518                 :            : {
     519         [ -  + ]:        394 :         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                 :        394 :                 rollback_done(mngt, 0);
     525                 :        394 :                 rollback_execute(mngt);
     526                 :            :         }
     527                 :            : }
     528                 :            : 
     529                 :            : static void
     530                 :        494 : rollback_msg(void *ctx)
     531                 :            : {
     532                 :        494 :         struct ftl_mngt_process *mngt = ctx;
     533                 :            :         struct ftl_mngt_step *step;
     534                 :            : 
     535                 :        494 :         mngt->continuing = false;
     536                 :            : 
     537         [ +  + ]:        494 :         if (TAILQ_EMPTY(&mngt->rollback_queue_todo)) {
     538                 :         76 :                 ftl_mngt_finish(mngt);
     539                 :         76 :                 return;
     540                 :            :         }
     541                 :            : 
     542                 :        418 :         step = TAILQ_FIRST(&mngt->rollback_queue_todo);
     543         [ +  - ]:        418 :         if (!step->rollback.start) {
     544                 :        418 :                 step->rollback.start = spdk_get_ticks();
     545                 :            :         }
     546                 :        418 :         step->desc->cleanup(mngt->dev, mngt);
     547                 :            : }
     548                 :            : 
     549                 :            : static void
     550                 :        494 : rollback_execute(struct ftl_mngt_process *mngt)
     551                 :            : {
     552                 :        494 :         spdk_thread_send_msg(mngt->dev->core_thread, rollback_msg, mngt);
     553                 :        494 : }
     554                 :            : 
     555                 :            : void
     556                 :        394 : rollback_done(struct ftl_mngt_process *mngt, int status)
     557                 :            : {
     558                 :            :         struct ftl_mngt_step *step;
     559                 :            : 
     560         [ -  + ]:        394 :         assert(!TAILQ_EMPTY(&mngt->rollback_queue_todo));
     561                 :        394 :         step = TAILQ_FIRST(&mngt->rollback_queue_todo);
     562         [ +  + ]:        394 :         TAILQ_REMOVE(&mngt->rollback_queue_todo, step, rollback.entry);
     563                 :        394 :         TAILQ_INSERT_TAIL(&mngt->rollback_queue_done, step, rollback.entry);
     564                 :            : 
     565                 :        394 :         step->rollback.stop = spdk_get_ticks();
     566                 :        394 :         step->rollback.status = status;
     567                 :            : 
     568                 :        394 :         trace_step(mngt->dev, step,  true);
     569                 :        394 : }

Generated by: LCOV version 1.14