diff options
author | Yordan Karadzhov (VMware) <y.karadz@gmail.com> | 2021-05-11 16:36:19 +0300 |
---|---|---|
committer | Yordan Karadzhov (VMware) <y.karadz@gmail.com> | 2021-05-14 14:27:59 +0300 |
commit | 6555daee2da02dd3f0b13399ea99cd0459379c7a (patch) | |
tree | 00390b0f42426100a89081aad2897731669aeadc | |
parent | 0a04671bb8dd09f3dd1ddb88333b130fb3324400 (diff) | |
download | kernel-shark-6555daee2da02dd3f0b13399ea99cd0459379c7a.tar.gz |
kernel-shark: Fix bug in filter clearing
Applying a filter to the loaded tracing data requires looping over
the entire data-set of entries. On large data-set this can be very
expensive operation. To coop with this, a number of checks are putted
in place to making sure that a loop is not performed in a case when
it is not really needed. However, there is a mistake in the logic of
these checks. So far we considered that calling filter_entries() with
no filter being set does not require looping over the data. But this
is not correct because if a filter had been applied already, calling
the function with an empty filter is equivalent of clearing the
existing filter, hence it is a legitimate operation and indeed we
need to loop over the data.
Link: https://lore.kernel.org/linux-trace-devel/20210511133619.287496-1-y.karadz@gmail.com
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=206131
Reported-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
-rw-r--r-- | src/libkshark.c | 20 | ||||
-rw-r--r-- | src/libkshark.h | 5 |
2 files changed, 23 insertions, 2 deletions
diff --git a/src/libkshark.c b/src/libkshark.c index dc58dcf6..1222a815 100644 --- a/src/libkshark.c +++ b/src/libkshark.c @@ -166,6 +166,7 @@ static struct kshark_data_stream *kshark_stream_alloc() goto fail; } + stream->filter_is_applied = false; kshark_set_data_format(stream->data_format, KS_INVALID_DATA); stream->name = strdup(KS_UNNAMED); @@ -1271,8 +1272,11 @@ static void filter_entries(struct kshark_context *kshark_ctx, int sd, return; } - if (!kshark_filter_is_set(kshark_ctx, sd)) + if (!kshark_filter_is_set(kshark_ctx, sd) && + !stream->filter_is_applied) { + /* Nothing to be done. */ return; + } } /* Apply only the Id filters. */ @@ -1294,6 +1298,9 @@ static void filter_entries(struct kshark_context *kshark_ctx, int sd, /* Apply Id filtering. */ kshark_apply_filters(kshark_ctx, stream, data[i]); + + stream->filter_is_applied = + kshark_filter_is_set(kshark_ctx, sd)? true : false; } } @@ -1356,10 +1363,19 @@ void kshark_clear_all_filters(struct kshark_context *kshark_ctx, struct kshark_entry **data, size_t n_entries) { - int i; + struct kshark_data_stream *stream; + int *stream_ids, i; for (i = 0; i < n_entries; ++i) set_all_visible(&data[i]->visible); + + stream_ids = kshark_all_streams(kshark_ctx); + for (i = 0; i < kshark_ctx->n_streams; i++) { + stream = kshark_get_data_stream(kshark_ctx, stream_ids[i]); + stream->filter_is_applied = false; + } + + free(stream_ids); } /** diff --git a/src/libkshark.h b/src/libkshark.h index ee3a1d38..23e3b492 100644 --- a/src/libkshark.h +++ b/src/libkshark.h @@ -324,6 +324,11 @@ struct kshark_data_stream { /** Hash of CPUs to not display. */ struct kshark_hash_id *hide_cpu_filter; + /** + * Flag showing if some entries are filtered out (marked as invisible). + */ + bool filter_is_applied; + /** The type of the data. */ char data_format[KS_DATA_FORMAT_SIZE]; |