diff --git a/lib/event/app.c b/lib/event/app.c index 534662668..f4b34aca1 100644 --- a/lib/event/app.c +++ b/lib/event/app.c @@ -367,9 +367,9 @@ static int app_setup_trace(struct spdk_app_opts *opts) { char shm_name[64]; - uint64_t tpoint_group_mask; - char *end = NULL, *tpoint_group_mask_str; - char *tpoint_group_str, *tp_g_str; + uint64_t tpoint_group_mask, tpoint_mask = -1ULL; + char *end = NULL, *tpoint_group_mask_str, *tpoint_group_str = NULL; + char *tp_g_str, *tpoint_group, *tpoints; if (opts->shm_id >= 0) { snprintf(shm_name, sizeof(shm_name), "/%s_trace.%d", opts->name, opts->shm_id); @@ -394,13 +394,41 @@ app_setup_trace(struct spdk_app_opts *opts) * to free later, because spdk_strsepq() modifies given char*. */ tp_g_str = tpoint_group_mask_str; while ((tpoint_group_str = spdk_strsepq(&tpoint_group_mask_str, ",")) != NULL) { - errno = 0; - tpoint_group_mask = strtoull(tpoint_group_str, &end, 16); - if (*end != '\0' || errno) { - break; + if (strchr(tpoint_group_str, ':')) { + /* Get the tpoint group mask */ + tpoint_group = spdk_strsepq(&tpoint_group_str, ":"); + /* Get the tpoint mask inside that group */ + tpoints = spdk_strsepq(&tpoint_group_str, ":"); + + errno = 0; + tpoint_group_mask = strtoull(tpoint_group, &end, 16); + if (*end != '\0' || errno) { + break; + } + /* Check if tpoint group mask has only one bit set. + * This is to avoid enabling individual tpoints in + * more than one tracepoint group at once. */ + if (!spdk_u64_is_pow2(tpoint_group_mask)) { + SPDK_ERRLOG("Tpoint group mask: %s contains multiple tpoint groups.\n", tpoint_group); + SPDK_ERRLOG("This is not supported, to prevent from activating tpoints by mistake.\n"); + break; + } + + errno = 0; + tpoint_mask = strtoull(tpoints, &end, 16); + if (*end != '\0' || errno) { + break; + } + } else { + errno = 0; + tpoint_group_mask = strtoull(tpoint_group_str, &end, 16); + if (*end != '\0' || errno) { + break; + } + tpoint_mask = -1ULL; } - spdk_trace_set_tpoint_group_mask(tpoint_group_mask); + spdk_trace_set_tpoints(spdk_u64log2(tpoint_group_mask), tpoint_mask); } if (tpoint_group_str != NULL) { diff --git a/lib/trace/trace_flags.c b/lib/trace/trace_flags.c index c2701c6d6..7f5043554 100644 --- a/lib/trace/trace_flags.c +++ b/lib/trace/trace_flags.c @@ -222,8 +222,9 @@ spdk_trace_mask_usage(FILE *f, const char *tmask_arg) { struct spdk_trace_register_fn *register_fn; - fprintf(f, " %s, --tpoint-group-mask \n", tmask_arg); - fprintf(f, " tracepoint group mask for spdk trace buffers (default 0x0"); + fprintf(f, " %s, --tpoint-group-mask [:]\n", tmask_arg); + fprintf(f, " group_mask - tracepoint group mask "); + fprintf(f, "for spdk trace buffers (default 0x0"); register_fn = g_reg_fn_head; while (register_fn) { @@ -232,6 +233,13 @@ spdk_trace_mask_usage(FILE *f, const char *tmask_arg) } fprintf(f, ", all 0xffff)\n"); + fprintf(f, " tpoint_mask - tracepoint mask for enabling individual"); + fprintf(f, " tpoints inside a tracepoint group."); + fprintf(f, " First tpoint inside a group can be"); + fprintf(f, " enabled by setting tpoint_mask to 1 (e.g. 0x8:1).\n"); + fprintf(f, " Masks can be combined (e.g. 0x400,0x8:1).\n"); + fprintf(f, " All available tpoints can be found in"); + fprintf(f, " /include/spdk_internal/trace_defs.h\n"); } void