A hash table, storring all idle CPUs is added to the session context. If a CPU does not contain any data (is idle), its plot is not shown by default when KernelShark starts. Note that, if the option '--cpu' is used, it has priority and if idle CPUs are selected, the corresponding empty CPU plots will be displayed. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=215677 Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@xxxxxxxxx> --- src/KsGLWidget.cpp | 11 ++++++++--- src/libkshark-tepdata.c | 5 ++++- src/libkshark.c | 6 ++++++ src/libkshark.h | 3 +++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/KsGLWidget.cpp b/src/KsGLWidget.cpp index 3b2e0d4..1c71ecb 100644 --- a/src/KsGLWidget.cpp +++ b/src/KsGLWidget.cpp @@ -419,6 +419,7 @@ void KsGLWidget::keyReleaseEvent(QKeyEvent *event) void KsGLWidget::_defaultPlots(kshark_context *kshark_ctx) { + struct kshark_data_stream *stream; QVector<int> streamIds, plotVec; uint64_t tMin, tMax; int nCPUs, nBins; @@ -432,15 +433,19 @@ void KsGLWidget::_defaultPlots(kshark_context *kshark_ctx) */ streamIds = KsUtils::getStreamIdList(kshark_ctx); for (auto const &sd: streamIds) { - nCPUs = kshark_ctx->stream[sd]->n_cpus; + stream = kshark_ctx->stream[sd]; + nCPUs = stream->n_cpus; plotVec.clear(); /* If the number of CPUs is too big show only the first 16. */ if (nCPUs > KS_MAX_START_PLOTS / kshark_ctx->n_streams) nCPUs = KS_MAX_START_PLOTS / kshark_ctx->n_streams; - for (int i = 0; i < nCPUs; ++i) - plotVec.append(i); + for (int cpu{0}; cpu < stream->n_cpus && plotVec.count() < nCPUs; ++cpu) { + /* Do not add plots for idle CPUs. */ + if (!kshark_hash_id_find(stream->idle_cpus, cpu)) + plotVec.append(cpu); + } _streamPlots[sd]._cpuList = plotVec; _streamPlots[sd]._taskList = {}; diff --git a/src/libkshark-tepdata.c b/src/libkshark-tepdata.c index 9740ed9..e9244b0 100644 --- a/src/libkshark-tepdata.c +++ b/src/libkshark-tepdata.c @@ -391,7 +391,10 @@ static ssize_t get_records(struct kshark_context *kshark_ctx, rec = tracecmd_read_data(kshark_get_tep_input(stream), cpu); } - total += count; + if (!count) + kshark_hash_id_add(stream->idle_cpus, cpu); + else + total += count; } *rec_list = cpu_list; diff --git a/src/libkshark.c b/src/libkshark.c index 1222a81..44e553f 100644 --- a/src/libkshark.c +++ b/src/libkshark.c @@ -121,6 +121,8 @@ static void kshark_stream_free(struct kshark_data_stream *stream) if (!stream) return; + kshark_hash_id_free(stream->idle_cpus); + kshark_hash_id_free(stream->show_task_filter); kshark_hash_id_free(stream->hide_task_filter); @@ -147,6 +149,8 @@ static struct kshark_data_stream *kshark_stream_alloc() if (!stream) goto fail; + stream->idle_cpus = kshark_hash_id_alloc(KS_FILTER_HASH_NBITS); + stream->show_task_filter = kshark_hash_id_alloc(KS_FILTER_HASH_NBITS); stream->hide_task_filter = kshark_hash_id_alloc(KS_FILTER_HASH_NBITS); @@ -433,6 +437,8 @@ static int kshark_stream_close(struct kshark_data_stream *stream) kshark_hash_id_clear(stream->show_cpu_filter); kshark_hash_id_clear(stream->hide_cpu_filter); + kshark_hash_id_clear(stream->idle_cpus); + if (kshark_is_tep(stream)) return kshark_tep_close_interface(stream); diff --git a/src/libkshark.h b/src/libkshark.h index 23e3b49..1514f33 100644 --- a/src/libkshark.h +++ b/src/libkshark.h @@ -286,6 +286,9 @@ struct kshark_data_stream { /** The number of CPUs presented in this data stream. */ int n_cpus; + /** Hash table of Idle CPUs. */ + struct kshark_hash_id *idle_cpus; + /** * The number of distinct event types presented in this data stream. */ -- 2.32.0