LCOV - code coverage report
Current view: top level - spdk/lib/trace - trace_flags.c (source / functions) Hit Total Coverage
Test: Combined Lines: 195 278 70.1 %
Date: 2024-07-15 15:30:47 Functions: 21 27 77.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 131 241 54.4 %

           Branch data     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                 :       3299 : SPDK_LOG_REGISTER_COMPONENT(trace)
      25                 :            : 
      26                 :            : uint64_t
      27                 :        570 : spdk_trace_get_tpoint_mask(uint32_t group_id)
      28                 :            : {
      29         [ -  + ]:        570 :         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         [ -  + ]:        570 :         if (g_trace_file == NULL) {
      35                 :          0 :                 return 0ULL;
      36                 :            :         }
      37                 :            : 
      38                 :        570 :         return g_trace_file->tpoint_mask[group_id];
      39                 :            : }
      40                 :            : 
      41                 :            : void
      42                 :       3217 : spdk_trace_set_tpoints(uint32_t group_id, uint64_t tpoint_mask)
      43                 :            : {
      44         [ -  + ]:       3217 :         if (g_trace_file == NULL) {
      45                 :          0 :                 SPDK_ERRLOG("trace is not initialized\n");
      46                 :          0 :                 return;
      47                 :            :         }
      48                 :            : 
      49         [ -  + ]:       3217 :         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                 :       3217 :         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                 :         19 : spdk_trace_get_tpoint_group_mask(void)
      75                 :            : {
      76                 :         19 :         uint64_t mask = 0x0;
      77                 :            :         int i;
      78                 :            : 
      79         [ +  + ]:        323 :         for (i = 0; i < SPDK_TRACE_MAX_GROUP_ID; i++) {
      80         [ +  + ]:        304 :                 if (spdk_trace_get_tpoint_mask(i) != 0) {
      81         [ -  + ]:         19 :                         mask |= (1ULL << i);
      82                 :            :                 }
      83                 :            :         }
      84                 :            : 
      85                 :         19 :         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                 :         41 : spdk_trace_get_first_register_fn(void)
     124                 :            : {
     125                 :         41 :         return g_reg_fn_head;
     126                 :            : }
     127                 :            : 
     128                 :            : struct spdk_trace_register_fn *
     129                 :        330 : spdk_trace_get_next_register_fn(struct spdk_trace_register_fn *register_fn)
     130                 :            : {
     131                 :        330 :         return register_fn->next;
     132                 :            : }
     133                 :            : 
     134                 :            : uint64_t
     135                 :         22 : spdk_trace_create_tpoint_group_mask(const char *group_name)
     136                 :            : {
     137                 :         22 :         uint64_t tpoint_group_mask = 0;
     138                 :            :         struct spdk_trace_register_fn *register_fn;
     139                 :            : 
     140                 :         22 :         register_fn = spdk_trace_get_first_register_fn();
     141   [ -  +  +  + ]:         22 :         if (strcmp(group_name, "all") == 0) {
     142         [ +  + ]:         26 :                 while (register_fn) {
     143         [ -  + ]:         24 :                         tpoint_group_mask |= (1UL << register_fn->tgroup_id);
     144                 :            : 
     145                 :         24 :                         register_fn = spdk_trace_get_next_register_fn(register_fn);
     146                 :            :                 }
     147                 :            :         } else {
     148         [ +  - ]:         60 :                 while (register_fn) {
     149   [ +  +  -  +  :         60 :                         if (strcmp(group_name, register_fn->name) == 0) {
                   +  + ]
     150                 :         20 :                                 break;
     151                 :            :                         }
     152                 :            : 
     153                 :         40 :                         register_fn = spdk_trace_get_next_register_fn(register_fn);
     154                 :            :                 }
     155                 :            : 
     156         [ +  - ]:         20 :                 if (register_fn != NULL) {
     157         [ -  + ]:         20 :                         tpoint_group_mask |= (1UL << register_fn->tgroup_id);
     158                 :            :                 }
     159                 :            :         }
     160                 :            : 
     161                 :         22 :         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                 :         36 : 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                 :         36 :         uint64_t prefix_len = strlen(LINE_PREFIX);
     207                 :         36 :         uint64_t separator_len = strlen(ENTRY_SEPARATOR);
     208                 :         36 :         const char *first_entry = "group_name - tracepoint group name for spdk trace buffers (";
     209                 :         36 :         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         [ -  + ]:         36 :         fprintf(f, " %s, --tpoint-group <group-name>[:<tpoint_mask>]\n", tmask_arg);
     215         [ -  + ]:         36 :         fprintf(f, "%s%s", LINE_PREFIX, first_entry);
     216         [ -  + ]:         36 :         curr_line_len = prefix_len + strlen(first_entry);
     217                 :            : 
     218                 :         36 :         register_fn = g_reg_fn_head;
     219         [ +  - ]:        149 :         while (register_fn) {
     220         [ -  + ]:        149 :                 curr_entry_len = strlen(register_fn->name);
     221         [ +  + ]:        149 :                 if ((curr_line_len + curr_entry_len + separator_len > MAX_LINE_LENGTH)) {
     222         [ -  + ]:         27 :                         fprintf(f, "\n%s", LINE_PREFIX);
     223                 :         27 :                         curr_line_len = prefix_len;
     224                 :            :                 }
     225                 :            : 
     226         [ -  + ]:        149 :                 fprintf(f, "%s%s", register_fn->name, ENTRY_SEPARATOR);
     227                 :        149 :                 curr_line_len += curr_entry_len + separator_len;
     228                 :            : 
     229         [ +  + ]:        149 :                 if (register_fn->next == NULL) {
     230   [ -  +  +  + ]:         36 :                         if (curr_line_len + strlen(last_entry) > MAX_LINE_LENGTH) {
     231         [ -  + ]:          3 :                                 fprintf(f, " ");
     232                 :            :                         }
     233         [ -  + ]:         36 :                         fprintf(f, "%s\n", last_entry);
     234                 :         36 :                         break;
     235                 :            :                 }
     236                 :            : 
     237                 :        113 :                 register_fn = register_fn->next;
     238                 :            :         }
     239                 :            : 
     240         [ -  + ]:         36 :         fprintf(f, "%stpoint_mask - tracepoint mask for enabling individual tpoints inside\n",
     241                 :            :                 LINE_PREFIX);
     242         [ -  + ]:         36 :         fprintf(f, "%sa tracepoint group. First tpoint inside a group can be enabled by\n",
     243                 :            :                 LINE_PREFIX);
     244         [ -  + ]:         36 :         fprintf(f, "%ssetting tpoint_mask to 1 (e.g. bdev:0x1). Groups and masks can be\n",
     245                 :            :                 LINE_PREFIX);
     246         [ -  + ]:         36 :         fprintf(f, "%scombined (e.g. thread,bdev:0x1). All available tpoints can be found\n",
     247                 :            :                 LINE_PREFIX);
     248         [ -  + ]:         36 :         fprintf(f, "%sin /include/spdk_internal/trace_defs.h\n", LINE_PREFIX);
     249                 :         36 : }
     250                 :            : 
     251                 :            : void
     252                 :      12306 : spdk_trace_register_owner_type(uint8_t type, char id_prefix)
     253                 :            : {
     254                 :            :         struct spdk_trace_owner_type *owner_type;
     255                 :            : 
     256         [ -  + ]:      12306 :         assert(type != OWNER_TYPE_NONE);
     257                 :            : 
     258         [ -  + ]:      12306 :         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                 :      12306 :         owner_type = &g_trace_file->owner_type[type];
     267         [ -  + ]:      12306 :         assert(owner_type->type == 0);
     268                 :            : 
     269                 :      12306 :         owner_type->type = type;
     270                 :      12306 :         owner_type->id_prefix = id_prefix;
     271                 :            : }
     272                 :            : 
     273                 :            : static void
     274                 :      19603 : _owner_set_description(uint16_t owner_id, const char *description, bool append)
     275                 :            : {
     276                 :            :         struct spdk_trace_owner *owner;
     277                 :      19603 :         char old[256] = {};
     278                 :            : 
     279         [ -  + ]:      19603 :         assert(sizeof(old) >= g_trace_file->owner_description_size);
     280                 :      19603 :         owner = spdk_get_trace_owner(g_trace_file, owner_id);
     281         [ -  + ]:      19603 :         assert(owner != NULL);
     282         [ +  + ]:      19603 :         if (append) {
     283   [ -  +  -  + ]:       6064 :                 memcpy(old, owner->description, g_trace_file->owner_description_size);
     284                 :            :         }
     285                 :            : 
     286   [ +  +  -  + ]:      19603 :         snprintf(owner->description, g_trace_file->owner_description_size,
     287                 :            :                  "%s%s%s", old, append ? " " : "", description);
     288                 :      19603 : }
     289                 :            : 
     290                 :            : uint16_t
     291                 :      14267 : 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         [ +  + ]:      14267 :         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                 :        728 :                 return 0;
     301                 :            :         }
     302                 :            : 
     303         [ -  + ]:      13539 :         pthread_spin_lock(&g_owner_ids.lock);
     304                 :            : 
     305         [ -  + ]:      13539 :         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                 :      13539 :         owner_id = g_owner_ids.ring[g_owner_ids.head];
     312         [ -  + ]:      13539 :         if (++g_owner_ids.head == g_owner_ids.size) {
     313                 :          0 :                 g_owner_ids.head = 0;
     314                 :            :         }
     315                 :            : 
     316                 :      13539 :         owner = spdk_get_trace_owner(g_trace_file, owner_id);
     317                 :      13539 :         owner->tsc = spdk_get_ticks();
     318                 :      13539 :         owner->type = owner_type;
     319                 :      13539 :         _owner_set_description(owner_id, description, false);
     320         [ -  + ]:      13539 :         pthread_spin_unlock(&g_owner_ids.lock);
     321                 :      13539 :         return owner_id;
     322                 :            : }
     323                 :            : 
     324                 :            : void
     325                 :      13719 : spdk_trace_unregister_owner(uint16_t owner_id)
     326                 :            : {
     327         [ +  + ]:      13719 :         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                 :        731 :                 return;
     332                 :            :         }
     333                 :            : 
     334         [ -  + ]:      12988 :         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         [ -  + ]:      12988 :         pthread_spin_lock(&g_owner_ids.lock);
     342                 :      12988 :         g_owner_ids.ring[g_owner_ids.tail] = owner_id;
     343         [ +  + ]:      12988 :         if (++g_owner_ids.tail == g_owner_ids.size) {
     344                 :          5 :                 g_owner_ids.tail = 0;
     345                 :            :         }
     346         [ -  + ]:      12988 :         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                 :       7652 : spdk_trace_owner_append_description(uint16_t owner_id, const char *description)
     366                 :            : {
     367         [ +  + ]:       7652 :         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                 :         30 :                 return;
     372                 :            :         }
     373                 :            : 
     374         [ +  + ]:       7622 :         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                 :       1558 :                 return;
     379                 :            :         }
     380                 :            : 
     381         [ -  + ]:       6064 :         pthread_spin_lock(&g_owner_ids.lock);
     382                 :       6064 :         _owner_set_description(owner_id, description, true);
     383         [ -  + ]:       6064 :         pthread_spin_unlock(&g_owner_ids.lock);
     384                 :            : }
     385                 :            : 
     386                 :            : void
     387                 :      13090 : spdk_trace_register_object(uint8_t type, char id_prefix)
     388                 :            : {
     389                 :            :         struct spdk_trace_object *object;
     390                 :            : 
     391         [ -  + ]:      13090 :         assert(type != OBJECT_NONE);
     392                 :            : 
     393         [ -  + ]:      13090 :         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                 :      13090 :         object = &g_trace_file->object[type];
     402         [ -  + ]:      13090 :         assert(object->type == 0);
     403                 :            : 
     404                 :      13090 :         object->type = type;
     405                 :      13090 :         object->id_prefix = id_prefix;
     406                 :            : }
     407                 :            : 
     408                 :            : static void
     409                 :     165299 : 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         [ -  + ]:     165299 :         assert(opts->tpoint_id < SPDK_TRACE_MAX_TPOINT_ID);
     415                 :            : 
     416   [ -  +  -  + ]:     165299 :         if (strnlen(opts->name, sizeof(tpoint->name)) == sizeof(tpoint->name)) {
     417                 :          0 :                 SPDK_ERRLOG("name (%s) too long\n", opts->name);
     418                 :            :         }
     419                 :            : 
     420                 :     165299 :         tpoint = &g_trace_file->tpoint[opts->tpoint_id];
     421         [ -  + ]:     165299 :         assert(tpoint->tpoint_id == 0);
     422                 :            : 
     423                 :     165299 :         snprintf(tpoint->name, sizeof(tpoint->name), "%s", opts->name);
     424                 :     165299 :         tpoint->tpoint_id = opts->tpoint_id;
     425                 :     165299 :         tpoint->object_type = opts->object_type;
     426                 :     165299 :         tpoint->owner_type = opts->owner_type;
     427                 :     165299 :         tpoint->new_object = opts->new_object;
     428                 :            : 
     429                 :     165299 :         max_name_length = sizeof(tpoint->args[0].name);
     430         [ +  - ]:     355774 :         for (i = 0; i < SPDK_TRACE_MAX_ARGS_COUNT; ++i) {
     431   [ +  +  +  + ]:     355774 :                 if (!opts->args[i].name || opts->args[i].name[0] == '\0') {
     432                 :            :                         break;
     433                 :            :                 }
     434                 :            : 
     435      [ +  +  - ]:     190475 :                 switch (opts->args[i].type) {
     436                 :     178511 :                 case SPDK_TRACE_ARG_TYPE_INT:
     437                 :            :                 case SPDK_TRACE_ARG_TYPE_PTR:
     438                 :            :                         /* The integers and pointers have to be exactly 4 or 8 bytes */
     439   [ +  +  -  + ]:     178511 :                         assert(opts->args[i].size == 4 || opts->args[i].size == 8);
     440                 :     178511 :                         break;
     441                 :      11964 :                 case SPDK_TRACE_ARG_TYPE_STR:
     442                 :            :                         /* Strings need to have at least one byte for the NULL terminator */
     443         [ -  + ]:      11964 :                         assert(opts->args[i].size > 0);
     444                 :      11964 :                         break;
     445                 :          0 :                 default:
     446                 :          0 :                         assert(0 && "invalid trace argument type");
     447                 :            :                         break;
     448                 :            :                 }
     449                 :            : 
     450   [ -  +  -  + ]:     190475 :                 if (strnlen(opts->args[i].name, max_name_length) == max_name_length) {
     451                 :          0 :                         SPDK_ERRLOG("argument name (%s) is too long\n", opts->args[i].name);
     452                 :            :                 }
     453                 :            : 
     454                 :     190475 :                 snprintf(tpoint->args[i].name, sizeof(tpoint->args[i].name),
     455                 :     170458 :                          "%s", opts->args[i].name);
     456                 :     190475 :                 tpoint->args[i].type = opts->args[i].type;
     457                 :     190475 :                 tpoint->args[i].size = opts->args[i].size;
     458                 :            :         }
     459                 :            : 
     460                 :     165299 :         tpoint->num_args = i;
     461                 :     165299 : }
     462                 :            : 
     463                 :            : void
     464                 :     135537 : spdk_trace_register_description_ext(const struct spdk_trace_tpoint_opts *opts, size_t num_opts)
     465                 :            : {
     466                 :            :         size_t i;
     467                 :            : 
     468         [ -  + ]:     135537 :         if (g_trace_file == NULL) {
     469                 :          0 :                 SPDK_ERRLOG("trace is not initialized\n");
     470                 :          0 :                 return;
     471                 :            :         }
     472                 :            : 
     473         [ +  + ]:     300836 :         for (i = 0; i < num_opts; ++i) {
     474                 :     165299 :                 trace_register_description(&opts[i]);
     475                 :            :         }
     476                 :            : }
     477                 :            : 
     478                 :            : void
     479                 :     119998 : spdk_trace_register_description(const char *name, uint16_t tpoint_id, uint8_t owner_type,
     480                 :            :                                 uint8_t object_type, uint8_t new_object,
     481                 :            :                                 uint8_t arg1_type, const char *arg1_name)
     482                 :            : {
     483                 :     119998 :         struct spdk_trace_tpoint_opts opts = {
     484                 :            :                 .name = name,
     485                 :            :                 .tpoint_id = tpoint_id,
     486                 :            :                 .owner_type = owner_type,
     487                 :            :                 .object_type = object_type,
     488                 :            :                 .new_object = new_object,
     489                 :            :                 .args = {{
     490                 :            :                                 .name = arg1_name,
     491                 :            :                                 .type = arg1_type,
     492                 :            :                                 .size = sizeof(uint64_t)
     493                 :            :                         }
     494                 :            :                 }
     495                 :            :         };
     496                 :            : 
     497                 :     119998 :         spdk_trace_register_description_ext(&opts, 1);
     498                 :     119998 : }
     499                 :            : 
     500                 :            : void
     501                 :      25393 : spdk_trace_tpoint_register_relation(uint16_t tpoint_id, uint8_t object_type, uint8_t arg_index)
     502                 :            : {
     503                 :            :         struct spdk_trace_tpoint *tpoint;
     504                 :            :         uint16_t i;
     505                 :            : 
     506         [ -  + ]:      25393 :         assert(object_type != OBJECT_NONE);
     507         [ -  + ]:      25393 :         assert(tpoint_id != OBJECT_NONE);
     508                 :            : 
     509         [ -  + ]:      25393 :         if (g_trace_file == NULL) {
     510                 :          0 :                 SPDK_ERRLOG("trace is not initialized\n");
     511                 :          0 :                 return;
     512                 :            :         }
     513                 :            : 
     514                 :            :         /* We do not check whether a tpoint_id exists here, because
     515                 :            :          * there is no order in which trace definitions are registered.
     516                 :            :          * This way we can create relations between tpoint and objects
     517                 :            :          * that will be declared later. */
     518                 :      25393 :         tpoint = &g_trace_file->tpoint[tpoint_id];
     519         [ +  - ]:      32895 :         for (i = 0; i < SPDK_COUNTOF(tpoint->related_objects); ++i) {
     520         [ +  + ]:      32895 :                 if (tpoint->related_objects[i].object_type == OBJECT_NONE) {
     521                 :      25393 :                         tpoint->related_objects[i].object_type = object_type;
     522                 :      25393 :                         tpoint->related_objects[i].arg_index = arg_index;
     523                 :      25393 :                         return;
     524                 :            :                 }
     525                 :            :         }
     526                 :          0 :         SPDK_ERRLOG("Unable to register new relation for tpoint %" PRIu16 ", object %" PRIu8 "\n",
     527                 :            :                     tpoint_id, object_type);
     528                 :            : }
     529                 :            : 
     530                 :            : void
     531                 :      27918 : spdk_trace_add_register_fn(struct spdk_trace_register_fn *reg_fn)
     532                 :            : {
     533                 :            :         struct spdk_trace_register_fn *_reg_fn;
     534                 :            : 
     535         [ -  + ]:      27918 :         if (reg_fn->name == NULL) {
     536                 :          0 :                 SPDK_ERRLOG("missing name for registering spdk trace tpoint group\n");
     537                 :          0 :                 assert(false);
     538                 :            :                 return;
     539                 :            :         }
     540                 :            : 
     541   [ -  +  -  + ]:      27918 :         if (strcmp(reg_fn->name, "all") == 0) {
     542                 :          0 :                 SPDK_ERRLOG("illegal name (%s) for tpoint group\n", reg_fn->name);
     543                 :          0 :                 assert(false);
     544                 :            :                 return;
     545                 :            :         }
     546                 :            : 
     547                 :            :         /* Ensure that no trace point group IDs and names are ever duplicated */
     548         [ +  + ]:     163814 :         for (_reg_fn = g_reg_fn_head; _reg_fn; _reg_fn = _reg_fn->next) {
     549         [ -  + ]:     135896 :                 if (reg_fn->tgroup_id == _reg_fn->tgroup_id) {
     550                 :          0 :                         SPDK_ERRLOG("group %d, %s has duplicate tgroup_id with %s\n",
     551                 :            :                                     reg_fn->tgroup_id, reg_fn->name, _reg_fn->name);
     552                 :          0 :                         assert(false);
     553                 :            :                         return;
     554                 :            :                 }
     555                 :            : 
     556   [ -  +  -  +  :     135896 :                 if (strcmp(reg_fn->name, _reg_fn->name) == 0) {
                   -  + ]
     557                 :          0 :                         SPDK_ERRLOG("name %s is duplicated between groups with ids %d and %d\n",
     558                 :            :                                     reg_fn->name, reg_fn->tgroup_id, _reg_fn->tgroup_id);
     559                 :          0 :                         assert(false);
     560                 :            :                         return;
     561                 :            :                 }
     562                 :            :         }
     563                 :            : 
     564                 :            :         /* Arrange trace registration in order on tgroup_id */
     565   [ +  +  +  + ]:      27918 :         if (g_reg_fn_head == NULL || reg_fn->tgroup_id < g_reg_fn_head->tgroup_id) {
     566                 :       9156 :                 reg_fn->next = g_reg_fn_head;
     567                 :       9156 :                 g_reg_fn_head = reg_fn;
     568                 :       9156 :                 return;
     569                 :            :         }
     570                 :            : 
     571         [ +  - ]:      69178 :         for (_reg_fn = g_reg_fn_head; _reg_fn; _reg_fn = _reg_fn->next) {
     572   [ +  +  +  + ]:      69178 :                 if (_reg_fn->next == NULL || reg_fn->tgroup_id < _reg_fn->next->tgroup_id) {
     573                 :      18762 :                         reg_fn->next = _reg_fn->next;
     574                 :      18762 :                         _reg_fn->next = reg_fn;
     575                 :      18762 :                         return;
     576                 :            :                 }
     577                 :            :         }
     578                 :            : }
     579                 :            : 
     580                 :            : int
     581                 :       2626 : trace_flags_init(void)
     582                 :            : {
     583                 :            :         struct spdk_trace_register_fn *reg_fn;
     584                 :            :         uint16_t i;
     585                 :            :         uint16_t owner_id_start;
     586                 :            :         int rc;
     587                 :            : 
     588                 :       2626 :         reg_fn = g_reg_fn_head;
     589         [ +  + ]:      27132 :         while (reg_fn) {
     590                 :      24506 :                 reg_fn->reg_fn();
     591                 :      24506 :                 reg_fn = reg_fn->next;
     592                 :            :         }
     593                 :            : 
     594                 :            :         /* We will not use owner_id 0, it will be reserved to mean "no owner".
     595                 :            :          * But for now, we will start with owner_id 256 instead of owner_id 1.
     596                 :            :          * This will account for some libraries and modules which pass a
     597                 :            :          * "poller_id" to spdk_trace_record() which is now an owner_id. Until
     598                 :            :          * all of those libraries and modules are converted, we will start
     599                 :            :          * owner_ids at 256 to avoid collisions.
     600                 :            :          */
     601                 :       2626 :         owner_id_start = 256;
     602                 :       2626 :         g_owner_ids.ring = calloc(g_trace_file->num_owners, sizeof(uint16_t));
     603         [ -  + ]:       2626 :         if (g_owner_ids.ring == NULL) {
     604                 :          0 :                 SPDK_ERRLOG("could not allocate g_owner_ids.ring\n");
     605                 :          0 :                 return -ENOMEM;
     606                 :            :         }
     607                 :       2626 :         g_owner_ids.head = 0;
     608                 :       2626 :         g_owner_ids.tail = g_trace_file->num_owners - owner_id_start;
     609                 :       2626 :         g_owner_ids.size = g_trace_file->num_owners;
     610         [ +  + ]:   42354753 :         for (i = 0; i < g_owner_ids.tail; i++) {
     611                 :   42352126 :                 g_owner_ids.ring[i] = i + owner_id_start;
     612                 :            :         }
     613                 :            : 
     614         [ -  + ]:       2626 :         rc = pthread_spin_init(&g_owner_ids.lock, PTHREAD_PROCESS_PRIVATE);
     615         [ -  + ]:       2626 :         if (rc != 0) {
     616                 :          0 :                 free(g_owner_ids.ring);
     617                 :          0 :                 g_owner_ids.ring = NULL;
     618                 :            :         }
     619                 :            : 
     620                 :       2626 :         return rc;
     621                 :            : }
     622                 :            : 
     623                 :            : void
     624                 :       2626 : trace_flags_fini(void)
     625                 :            : {
     626         [ -  + ]:       2626 :         if (g_owner_ids.ring == NULL) {
     627                 :          0 :                 return;
     628                 :            :         }
     629         [ -  + ]:       2626 :         pthread_spin_destroy(&g_owner_ids.lock);
     630                 :       2626 :         free(g_owner_ids.ring);
     631                 :       2626 :         g_owner_ids.ring = NULL;
     632                 :            : }

Generated by: LCOV version 1.14