LCOV - code coverage report
Current view: top level - spdk/lib/ftl/mngt - ftl_mngt.c (source / functions) Hit Total Coverage
Test: Combined Lines: 239 264 90.5 %
Date: 2024-07-15 21:57:18 Functions: 32 32 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 118 146 80.8 %

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

Generated by: LCOV version 1.14