LCOV - code coverage report
Current view: top level - lib/trace - trace_flags.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 49 278 17.6 %
Date: 2024-07-13 10:23:12 Functions: 6 27 22.2 %

          Line data    Source code
       1             : /*   SPDX-License-Identifier: BSD-3-Clause
       2             :  *   Copyright (C) 2017 Intel Corporation.
       3             :  *   All rights reserved.
       4             :  */
       5             : 
       6             : #include "spdk/stdinc.h"
       7             : 
       8             : #include "spdk/env.h"
       9             : #include "spdk/trace.h"
      10             : #include "spdk/log.h"
      11             : #include "spdk/util.h"
      12             : #include "trace_internal.h"
      13             : #include "spdk/bit_array.h"
      14             : 
      15             : static struct spdk_trace_register_fn *g_reg_fn_head = NULL;
      16             : static struct {
      17             :         uint16_t *ring;
      18             :         uint32_t head;
      19             :         uint32_t tail;
      20             :         uint32_t size;
      21             :         pthread_spinlock_t lock;
      22             : } g_owner_ids;
      23             : 
      24          44 : SPDK_LOG_REGISTER_COMPONENT(trace)
      25             : 
      26             : uint64_t
      27           0 : spdk_trace_get_tpoint_mask(uint32_t group_id)
      28             : {
      29           0 :         if (group_id >= SPDK_TRACE_MAX_GROUP_ID) {
      30           0 :                 SPDK_ERRLOG("invalid group ID %d\n", group_id);
      31           0 :                 return 0ULL;
      32             :         }
      33             : 
      34           0 :         if (g_trace_file == NULL) {
      35           0 :                 return 0ULL;
      36             :         }
      37             : 
      38           0 :         return g_trace_file->tpoint_mask[group_id];
      39             : }
      40             : 
      41             : void
      42           0 : spdk_trace_set_tpoints(uint32_t group_id, uint64_t tpoint_mask)
      43             : {
      44           0 :         if (g_trace_file == NULL) {
      45           0 :                 SPDK_ERRLOG("trace is not initialized\n");
      46           0 :                 return;
      47             :         }
      48             : 
      49           0 :         if (group_id >= SPDK_TRACE_MAX_GROUP_ID) {
      50           0 :                 SPDK_ERRLOG("invalid group ID %d\n", group_id);
      51           0 :                 return;
      52             :         }
      53             : 
      54           0 :         g_trace_file->tpoint_mask[group_id] |= tpoint_mask;
      55             : }
      56             : 
      57             : void
      58           0 : spdk_trace_clear_tpoints(uint32_t group_id, uint64_t tpoint_mask)
      59             : {
      60           0 :         if (g_trace_file == NULL) {
      61           0 :                 SPDK_ERRLOG("trace is not initialized\n");
      62           0 :                 return;
      63             :         }
      64             : 
      65           0 :         if (group_id >= SPDK_TRACE_MAX_GROUP_ID) {
      66           0 :                 SPDK_ERRLOG("invalid group ID %d\n", group_id);
      67           0 :                 return;
      68             :         }
      69             : 
      70           0 :         g_trace_file->tpoint_mask[group_id] &= ~tpoint_mask;
      71             : }
      72             : 
      73             : uint64_t
      74           0 : spdk_trace_get_tpoint_group_mask(void)
      75             : {
      76           0 :         uint64_t mask = 0x0;
      77             :         int i;
      78             : 
      79           0 :         for (i = 0; i < SPDK_TRACE_MAX_GROUP_ID; i++) {
      80           0 :                 if (spdk_trace_get_tpoint_mask(i) != 0) {
      81           0 :                         mask |= (1ULL << i);
      82             :                 }
      83             :         }
      84             : 
      85           0 :         return mask;
      86             : }
      87             : 
      88             : void
      89           0 : spdk_trace_set_tpoint_group_mask(uint64_t tpoint_group_mask)
      90             : {
      91             :         int i;
      92             : 
      93           0 :         if (g_trace_file == NULL) {
      94           0 :                 SPDK_ERRLOG("trace is not initialized\n");
      95           0 :                 return;
      96             :         }
      97             : 
      98           0 :         for (i = 0; i < SPDK_TRACE_MAX_GROUP_ID; i++) {
      99           0 :                 if (tpoint_group_mask & (1ULL << i)) {
     100           0 :                         spdk_trace_set_tpoints(i, -1ULL);
     101             :                 }
     102             :         }
     103             : }
     104             : 
     105             : void
     106           0 : spdk_trace_clear_tpoint_group_mask(uint64_t tpoint_group_mask)
     107             : {
     108             :         int i;
     109             : 
     110           0 :         if (g_trace_file == NULL) {
     111           0 :                 SPDK_ERRLOG("trace is not initialized\n");
     112           0 :                 return;
     113             :         }
     114             : 
     115           0 :         for (i = 0; i < SPDK_TRACE_MAX_GROUP_ID; i++) {
     116           0 :                 if (tpoint_group_mask & (1ULL << i)) {
     117           0 :                         spdk_trace_clear_tpoints(i, -1ULL);
     118             :                 }
     119             :         }
     120             : }
     121             : 
     122             : struct spdk_trace_register_fn *
     123           0 : spdk_trace_get_first_register_fn(void)
     124             : {
     125           0 :         return g_reg_fn_head;
     126             : }
     127             : 
     128             : struct spdk_trace_register_fn *
     129           0 : spdk_trace_get_next_register_fn(struct spdk_trace_register_fn *register_fn)
     130             : {
     131           0 :         return register_fn->next;
     132             : }
     133             : 
     134             : uint64_t
     135           0 : spdk_trace_create_tpoint_group_mask(const char *group_name)
     136             : {
     137           0 :         uint64_t tpoint_group_mask = 0;
     138             :         struct spdk_trace_register_fn *register_fn;
     139             : 
     140           0 :         register_fn = spdk_trace_get_first_register_fn();
     141           0 :         if (strcmp(group_name, "all") == 0) {
     142           0 :                 while (register_fn) {
     143           0 :                         tpoint_group_mask |= (1UL << register_fn->tgroup_id);
     144             : 
     145           0 :                         register_fn = spdk_trace_get_next_register_fn(register_fn);
     146             :                 }
     147             :         } else {
     148           0 :                 while (register_fn) {
     149           0 :                         if (strcmp(group_name, register_fn->name) == 0) {
     150           0 :                                 break;
     151             :                         }
     152             : 
     153           0 :                         register_fn = spdk_trace_get_next_register_fn(register_fn);
     154             :                 }
     155             : 
     156           0 :                 if (register_fn != NULL) {
     157           0 :                         tpoint_group_mask |= (1UL << register_fn->tgroup_id);
     158             :                 }
     159             :         }
     160             : 
     161           0 :         return tpoint_group_mask;
     162             : }
     163             : 
     164             : int
     165           0 : spdk_trace_enable_tpoint_group(const char *group_name)
     166             : {
     167           0 :         uint64_t tpoint_group_mask = 0;
     168             : 
     169           0 :         if (g_trace_file == NULL) {
     170           0 :                 return -1;
     171             :         }
     172             : 
     173           0 :         tpoint_group_mask = spdk_trace_create_tpoint_group_mask(group_name);
     174           0 :         if (tpoint_group_mask == 0) {
     175           0 :                 return -1;
     176             :         }
     177             : 
     178           0 :         spdk_trace_set_tpoint_group_mask(tpoint_group_mask);
     179           0 :         return 0;
     180             : }
     181             : 
     182             : int
     183           0 : spdk_trace_disable_tpoint_group(const char *group_name)
     184             : {
     185           0 :         uint64_t tpoint_group_mask = 0;
     186             : 
     187           0 :         if (g_trace_file == NULL) {
     188           0 :                 return -1;
     189             :         }
     190             : 
     191           0 :         tpoint_group_mask = spdk_trace_create_tpoint_group_mask(group_name);
     192           0 :         if (tpoint_group_mask == 0) {
     193           0 :                 return -1;
     194             :         }
     195             : 
     196           0 :         spdk_trace_clear_tpoint_group_mask(tpoint_group_mask);
     197           0 :         return 0;
     198             : }
     199             : 
     200             : void
     201           3 : spdk_trace_mask_usage(FILE *f, const char *tmask_arg)
     202             : {
     203             : #define LINE_PREFIX                     "                           "
     204             : #define ENTRY_SEPARATOR                 ", "
     205             : #define MAX_LINE_LENGTH                 100
     206           3 :         uint64_t prefix_len = strlen(LINE_PREFIX);
     207           3 :         uint64_t separator_len = strlen(ENTRY_SEPARATOR);
     208           3 :         const char *first_entry = "group_name - tracepoint group name for spdk trace buffers (";
     209           3 :         const char *last_entry = "all).";
     210             :         uint64_t curr_line_len;
     211             :         uint64_t curr_entry_len;
     212             :         struct spdk_trace_register_fn *register_fn;
     213             : 
     214           3 :         fprintf(f, " %s, --tpoint-group <group-name>[:<tpoint_mask>]\n", tmask_arg);
     215           3 :         fprintf(f, "%s%s", LINE_PREFIX, first_entry);
     216           3 :         curr_line_len = prefix_len + strlen(first_entry);
     217             : 
     218           3 :         register_fn = g_reg_fn_head;
     219           3 :         while (register_fn) {
     220           3 :                 curr_entry_len = strlen(register_fn->name);
     221           3 :                 if ((curr_line_len + curr_entry_len + separator_len > MAX_LINE_LENGTH)) {
     222           0 :                         fprintf(f, "\n%s", LINE_PREFIX);
     223           0 :                         curr_line_len = prefix_len;
     224             :                 }
     225             : 
     226           3 :                 fprintf(f, "%s%s", register_fn->name, ENTRY_SEPARATOR);
     227           3 :                 curr_line_len += curr_entry_len + separator_len;
     228             : 
     229           3 :                 if (register_fn->next == NULL) {
     230           3 :                         if (curr_line_len + strlen(last_entry) > MAX_LINE_LENGTH) {
     231           0 :                                 fprintf(f, " ");
     232             :                         }
     233           3 :                         fprintf(f, "%s\n", last_entry);
     234           3 :                         break;
     235             :                 }
     236             : 
     237           0 :                 register_fn = register_fn->next;
     238             :         }
     239             : 
     240           3 :         fprintf(f, "%stpoint_mask - tracepoint mask for enabling individual tpoints inside\n",
     241             :                 LINE_PREFIX);
     242           3 :         fprintf(f, "%sa tracepoint group. First tpoint inside a group can be enabled by\n",
     243             :                 LINE_PREFIX);
     244           3 :         fprintf(f, "%ssetting tpoint_mask to 1 (e.g. bdev:0x1). Groups and masks can be\n",
     245             :                 LINE_PREFIX);
     246           3 :         fprintf(f, "%scombined (e.g. thread,bdev:0x1). All available tpoints can be found\n",
     247             :                 LINE_PREFIX);
     248           3 :         fprintf(f, "%sin /include/spdk_internal/trace_defs.h\n", LINE_PREFIX);
     249           3 : }
     250             : 
     251             : void
     252           0 : spdk_trace_register_owner_type(uint8_t type, char id_prefix)
     253             : {
     254             :         struct spdk_trace_owner_type *owner_type;
     255             : 
     256           0 :         assert(type != OWNER_TYPE_NONE);
     257             : 
     258           0 :         if (g_trace_file == NULL) {
     259           0 :                 SPDK_ERRLOG("trace is not initialized\n");
     260           0 :                 return;
     261             :         }
     262             : 
     263             :         /* 'owner_type' has 256 entries and since 'type' is a uint8_t, it
     264             :          * can't overrun the array.
     265             :          */
     266           0 :         owner_type = &g_trace_file->owner_type[type];
     267           0 :         assert(owner_type->type == 0);
     268             : 
     269           0 :         owner_type->type = type;
     270           0 :         owner_type->id_prefix = id_prefix;
     271             : }
     272             : 
     273             : static void
     274           0 : _owner_set_description(uint16_t owner_id, const char *description, bool append)
     275             : {
     276             :         struct spdk_trace_owner *owner;
     277           0 :         char old[256] = {};
     278             : 
     279           0 :         assert(sizeof(old) >= g_trace_file->owner_description_size);
     280           0 :         owner = spdk_get_trace_owner(g_trace_file, owner_id);
     281           0 :         assert(owner != NULL);
     282           0 :         if (append) {
     283           0 :                 memcpy(old, owner->description, g_trace_file->owner_description_size);
     284             :         }
     285             : 
     286           0 :         snprintf(owner->description, g_trace_file->owner_description_size,
     287             :                  "%s%s%s", old, append ? " " : "", description);
     288           0 : }
     289             : 
     290             : uint16_t
     291         123 : spdk_trace_register_owner(uint8_t owner_type, const char *description)
     292             : {
     293             :         struct spdk_trace_owner *owner;
     294             :         uint32_t owner_id;
     295             : 
     296         123 :         if (g_owner_ids.ring == NULL) {
     297             :                 /* Help the unit test environment by simply returning instead
     298             :                  * of requiring it to initialize the trace library.
     299             :                  */
     300         123 :                 return 0;
     301             :         }
     302             : 
     303           0 :         pthread_spin_lock(&g_owner_ids.lock);
     304             : 
     305           0 :         if (g_owner_ids.head == g_owner_ids.tail) {
     306             :                 /* No owner ids available. Return 0 which means no owner. */
     307           0 :                 pthread_spin_unlock(&g_owner_ids.lock);
     308           0 :                 return 0;
     309             :         }
     310             : 
     311           0 :         owner_id = g_owner_ids.ring[g_owner_ids.head];
     312           0 :         if (++g_owner_ids.head == g_owner_ids.size) {
     313           0 :                 g_owner_ids.head = 0;
     314             :         }
     315             : 
     316           0 :         owner = spdk_get_trace_owner(g_trace_file, owner_id);
     317           0 :         owner->tsc = spdk_get_ticks();
     318           0 :         owner->type = owner_type;
     319           0 :         _owner_set_description(owner_id, description, false);
     320           0 :         pthread_spin_unlock(&g_owner_ids.lock);
     321           0 :         return owner_id;
     322             : }
     323             : 
     324             : void
     325         124 : spdk_trace_unregister_owner(uint16_t owner_id)
     326             : {
     327         124 :         if (g_owner_ids.ring == NULL) {
     328             :                 /* Help the unit test environment by simply returning instead
     329             :                  * of requiring it to initialize the trace library.
     330             :                  */
     331         124 :                 return;
     332             :         }
     333             : 
     334           0 :         if (owner_id == 0) {
     335             :                 /* owner_id 0 means no owner. Allow this to be passed here, it
     336             :                  * avoids caller having to do extra checking.
     337             :                  */
     338           0 :                 return;
     339             :         }
     340             : 
     341           0 :         pthread_spin_lock(&g_owner_ids.lock);
     342           0 :         g_owner_ids.ring[g_owner_ids.tail] = owner_id;
     343           0 :         if (++g_owner_ids.tail == g_owner_ids.size) {
     344           0 :                 g_owner_ids.tail = 0;
     345             :         }
     346           0 :         pthread_spin_unlock(&g_owner_ids.lock);
     347             : }
     348             : 
     349             : void
     350           0 : spdk_trace_owner_set_description(uint16_t owner_id, const char *description)
     351             : {
     352           0 :         if (g_owner_ids.ring == NULL) {
     353             :                 /* Help the unit test environment by simply returning instead
     354             :                  * of requiring it to initialize the trace library.
     355             :                  */
     356           0 :                 return;
     357             :         }
     358             : 
     359           0 :         pthread_spin_lock(&g_owner_ids.lock);
     360           0 :         _owner_set_description(owner_id, description, false);
     361           0 :         pthread_spin_unlock(&g_owner_ids.lock);
     362             : }
     363             : 
     364             : void
     365           8 : spdk_trace_owner_append_description(uint16_t owner_id, const char *description)
     366             : {
     367           8 :         if (g_owner_ids.ring == NULL) {
     368             :                 /* Help the unit test environment by simply returning instead
     369             :                  * of requiring it to initialize the trace library.
     370             :                  */
     371           8 :                 return;
     372             :         }
     373             : 
     374           0 :         if (owner_id == 0) {
     375             :                 /* owner_id 0 means no owner. Allow this to be passed here, it
     376             :                  * avoids caller having to do extra checking.
     377             :                  */
     378           0 :                 return;
     379             :         }
     380             : 
     381           0 :         pthread_spin_lock(&g_owner_ids.lock);
     382           0 :         _owner_set_description(owner_id, description, true);
     383           0 :         pthread_spin_unlock(&g_owner_ids.lock);
     384             : }
     385             : 
     386             : void
     387           0 : spdk_trace_register_object(uint8_t type, char id_prefix)
     388             : {
     389             :         struct spdk_trace_object *object;
     390             : 
     391           0 :         assert(type != OBJECT_NONE);
     392             : 
     393           0 :         if (g_trace_file == NULL) {
     394           0 :                 SPDK_ERRLOG("trace is not initialized\n");
     395           0 :                 return;
     396             :         }
     397             : 
     398             :         /* 'object' has 256 entries and since 'type' is a uint8_t, it
     399             :          * can't overrun the array.
     400             :          */
     401           0 :         object = &g_trace_file->object[type];
     402           0 :         assert(object->type == 0);
     403             : 
     404           0 :         object->type = type;
     405           0 :         object->id_prefix = id_prefix;
     406             : }
     407             : 
     408             : static void
     409           0 : trace_register_description(const struct spdk_trace_tpoint_opts *opts)
     410             : {
     411             :         struct spdk_trace_tpoint *tpoint;
     412             :         size_t i, max_name_length;
     413             : 
     414           0 :         assert(opts->tpoint_id != 0);
     415           0 :         assert(opts->tpoint_id < SPDK_TRACE_MAX_TPOINT_ID);
     416             : 
     417           0 :         if (strnlen(opts->name, sizeof(tpoint->name)) == sizeof(tpoint->name)) {
     418           0 :                 SPDK_ERRLOG("name (%s) too long\n", opts->name);
     419             :         }
     420             : 
     421           0 :         tpoint = &g_trace_file->tpoint[opts->tpoint_id];
     422           0 :         assert(tpoint->tpoint_id == 0);
     423             : 
     424           0 :         snprintf(tpoint->name, sizeof(tpoint->name), "%s", opts->name);
     425           0 :         tpoint->tpoint_id = opts->tpoint_id;
     426           0 :         tpoint->object_type = opts->object_type;
     427           0 :         tpoint->owner_type = opts->owner_type;
     428           0 :         tpoint->new_object = opts->new_object;
     429             : 
     430           0 :         max_name_length = sizeof(tpoint->args[0].name);
     431           0 :         for (i = 0; i < SPDK_TRACE_MAX_ARGS_COUNT; ++i) {
     432           0 :                 if (!opts->args[i].name || opts->args[i].name[0] == '\0') {
     433             :                         break;
     434             :                 }
     435             : 
     436           0 :                 switch (opts->args[i].type) {
     437           0 :                 case SPDK_TRACE_ARG_TYPE_INT:
     438             :                 case SPDK_TRACE_ARG_TYPE_PTR:
     439             :                         /* The integers and pointers have to be exactly 4 or 8 bytes */
     440           0 :                         assert(opts->args[i].size == 4 || opts->args[i].size == 8);
     441           0 :                         break;
     442           0 :                 case SPDK_TRACE_ARG_TYPE_STR:
     443             :                         /* Strings need to have at least one byte for the NULL terminator */
     444           0 :                         assert(opts->args[i].size > 0);
     445           0 :                         break;
     446           0 :                 default:
     447           0 :                         assert(0 && "invalid trace argument type");
     448             :                         break;
     449             :                 }
     450             : 
     451           0 :                 if (strnlen(opts->args[i].name, max_name_length) == max_name_length) {
     452           0 :                         SPDK_ERRLOG("argument name (%s) is too long\n", opts->args[i].name);
     453             :                 }
     454             : 
     455           0 :                 snprintf(tpoint->args[i].name, sizeof(tpoint->args[i].name),
     456             :                          "%s", opts->args[i].name);
     457           0 :                 tpoint->args[i].type = opts->args[i].type;
     458           0 :                 tpoint->args[i].size = opts->args[i].size;
     459             :         }
     460             : 
     461           0 :         tpoint->num_args = i;
     462           0 : }
     463             : 
     464             : void
     465           0 : spdk_trace_register_description_ext(const struct spdk_trace_tpoint_opts *opts, size_t num_opts)
     466             : {
     467             :         size_t i;
     468             : 
     469           0 :         if (g_trace_file == NULL) {
     470           0 :                 SPDK_ERRLOG("trace is not initialized\n");
     471           0 :                 return;
     472             :         }
     473             : 
     474           0 :         for (i = 0; i < num_opts; ++i) {
     475           0 :                 trace_register_description(&opts[i]);
     476             :         }
     477             : }
     478             : 
     479             : void
     480           0 : spdk_trace_register_description(const char *name, uint16_t tpoint_id, uint8_t owner_type,
     481             :                                 uint8_t object_type, uint8_t new_object,
     482             :                                 uint8_t arg1_type, const char *arg1_name)
     483             : {
     484           0 :         struct spdk_trace_tpoint_opts opts = {
     485             :                 .name = name,
     486             :                 .tpoint_id = tpoint_id,
     487             :                 .owner_type = owner_type,
     488             :                 .object_type = object_type,
     489             :                 .new_object = new_object,
     490             :                 .args = {{
     491             :                                 .name = arg1_name,
     492             :                                 .type = arg1_type,
     493             :                                 .size = sizeof(uint64_t)
     494             :                         }
     495             :                 }
     496             :         };
     497             : 
     498           0 :         spdk_trace_register_description_ext(&opts, 1);
     499           0 : }
     500             : 
     501             : void
     502           0 : spdk_trace_tpoint_register_relation(uint16_t tpoint_id, uint8_t object_type, uint8_t arg_index)
     503             : {
     504             :         struct spdk_trace_tpoint *tpoint;
     505             :         uint16_t i;
     506             : 
     507           0 :         assert(object_type != OBJECT_NONE);
     508           0 :         assert(tpoint_id != OBJECT_NONE);
     509             : 
     510           0 :         if (g_trace_file == NULL) {
     511           0 :                 SPDK_ERRLOG("trace is not initialized\n");
     512           0 :                 return;
     513             :         }
     514             : 
     515             :         /* We do not check whether a tpoint_id exists here, because
     516             :          * there is no order in which trace definitions are registered.
     517             :          * This way we can create relations between tpoint and objects
     518             :          * that will be declared later. */
     519           0 :         tpoint = &g_trace_file->tpoint[tpoint_id];
     520           0 :         for (i = 0; i < SPDK_COUNTOF(tpoint->related_objects); ++i) {
     521           0 :                 if (tpoint->related_objects[i].object_type == OBJECT_NONE) {
     522           0 :                         tpoint->related_objects[i].object_type = object_type;
     523           0 :                         tpoint->related_objects[i].arg_index = arg_index;
     524           0 :                         return;
     525             :                 }
     526             :         }
     527           0 :         SPDK_ERRLOG("Unable to register new relation for tpoint %" PRIu16 ", object %" PRIu8 "\n",
     528             :                     tpoint_id, object_type);
     529             : }
     530             : 
     531             : void
     532          53 : spdk_trace_add_register_fn(struct spdk_trace_register_fn *reg_fn)
     533             : {
     534             :         struct spdk_trace_register_fn *_reg_fn;
     535             : 
     536          53 :         if (reg_fn->name == NULL) {
     537           0 :                 SPDK_ERRLOG("missing name for registering spdk trace tpoint group\n");
     538           0 :                 assert(false);
     539             :                 return;
     540             :         }
     541             : 
     542          53 :         if (strcmp(reg_fn->name, "all") == 0) {
     543           0 :                 SPDK_ERRLOG("illegal name (%s) for tpoint group\n", reg_fn->name);
     544           0 :                 assert(false);
     545             :                 return;
     546             :         }
     547             : 
     548             :         /* Ensure that no trace point group IDs and names are ever duplicated */
     549          63 :         for (_reg_fn = g_reg_fn_head; _reg_fn; _reg_fn = _reg_fn->next) {
     550          10 :                 if (reg_fn->tgroup_id == _reg_fn->tgroup_id) {
     551           0 :                         SPDK_ERRLOG("group %d, %s has duplicate tgroup_id with %s\n",
     552             :                                     reg_fn->tgroup_id, reg_fn->name, _reg_fn->name);
     553           0 :                         assert(false);
     554             :                         return;
     555             :                 }
     556             : 
     557          10 :                 if (strcmp(reg_fn->name, _reg_fn->name) == 0) {
     558           0 :                         SPDK_ERRLOG("name %s is duplicated between groups with ids %d and %d\n",
     559             :                                     reg_fn->name, reg_fn->tgroup_id, _reg_fn->tgroup_id);
     560           0 :                         assert(false);
     561             :                         return;
     562             :                 }
     563             :         }
     564             : 
     565             :         /* Arrange trace registration in order on tgroup_id */
     566          53 :         if (g_reg_fn_head == NULL || reg_fn->tgroup_id < g_reg_fn_head->tgroup_id) {
     567          44 :                 reg_fn->next = g_reg_fn_head;
     568          44 :                 g_reg_fn_head = reg_fn;
     569          44 :                 return;
     570             :         }
     571             : 
     572           9 :         for (_reg_fn = g_reg_fn_head; _reg_fn; _reg_fn = _reg_fn->next) {
     573           9 :                 if (_reg_fn->next == NULL || reg_fn->tgroup_id < _reg_fn->next->tgroup_id) {
     574           9 :                         reg_fn->next = _reg_fn->next;
     575           9 :                         _reg_fn->next = reg_fn;
     576           9 :                         return;
     577             :                 }
     578             :         }
     579             : }
     580             : 
     581             : int
     582           0 : trace_flags_init(void)
     583             : {
     584             :         struct spdk_trace_register_fn *reg_fn;
     585             :         uint16_t i;
     586             :         uint16_t owner_id_start;
     587             :         int rc;
     588             : 
     589           0 :         reg_fn = g_reg_fn_head;
     590           0 :         while (reg_fn) {
     591           0 :                 reg_fn->reg_fn();
     592           0 :                 reg_fn = reg_fn->next;
     593             :         }
     594             : 
     595             :         /* We will not use owner_id 0, it will be reserved to mean "no owner".
     596             :          * But for now, we will start with owner_id 256 instead of owner_id 1.
     597             :          * This will account for some libraries and modules which pass a
     598             :          * "poller_id" to spdk_trace_record() which is now an owner_id. Until
     599             :          * all of those libraries and modules are converted, we will start
     600             :          * owner_ids at 256 to avoid collisions.
     601             :          */
     602           0 :         owner_id_start = 256;
     603           0 :         g_owner_ids.ring = calloc(g_trace_file->num_owners, sizeof(uint16_t));
     604           0 :         if (g_owner_ids.ring == NULL) {
     605           0 :                 SPDK_ERRLOG("could not allocate g_owner_ids.ring\n");
     606           0 :                 return -ENOMEM;
     607             :         }
     608           0 :         g_owner_ids.head = 0;
     609           0 :         g_owner_ids.tail = g_trace_file->num_owners - owner_id_start;
     610           0 :         g_owner_ids.size = g_trace_file->num_owners;
     611           0 :         for (i = 0; i < g_owner_ids.tail; i++) {
     612           0 :                 g_owner_ids.ring[i] = i + owner_id_start;
     613             :         }
     614             : 
     615           0 :         rc = pthread_spin_init(&g_owner_ids.lock, PTHREAD_PROCESS_PRIVATE);
     616           0 :         if (rc != 0) {
     617           0 :                 free(g_owner_ids.ring);
     618           0 :                 g_owner_ids.ring = NULL;
     619             :         }
     620             : 
     621           0 :         return rc;
     622             : }
     623             : 
     624             : void
     625           0 : trace_flags_fini(void)
     626             : {
     627           0 :         if (g_owner_ids.ring == NULL) {
     628           0 :                 return;
     629             :         }
     630           0 :         pthread_spin_destroy(&g_owner_ids.lock);
     631           0 :         free(g_owner_ids.ring);
     632           0 :         g_owner_ids.ring = NULL;
     633             : }

Generated by: LCOV version 1.15