Commit 91272596 authored by khmel@chromium.org's avatar khmel@chromium.org Committed by Commit Bot

arc: Add GEM stats to tracing model.

This adds chart GEM objects number and size to memory diagram.

TEST=Locally + limited unit tests
BUG=b:122555793

Change-Id: I902c65a016f89041e69ab202f6344eff9838a9dd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1592709Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Commit-Queue: Yury Khmel <khmel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#656250}
parent e37cbc5f
......@@ -62,6 +62,8 @@ class ArcSystemModel {
private:
ThreadMap thread_map_;
AllCpuEvents all_cpu_events_;
// TODO(khmel): For simplification and performance use separate channels
// for each event type.
ValueEvents memory_events_;
DISALLOW_COPY_AND_ASSIGN(ArcSystemModel);
......
......@@ -10,6 +10,7 @@
#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "chrome/browser/chromeos/arc/tracing/arc_system_model.h"
#include "chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.h"
......@@ -42,6 +43,8 @@ struct ArcSystemStatCollector::Sample {
int swap_waiting_time_ms = 0;
int mem_total_kb = 0;
int mem_used_kb = 0;
int gem_objects = 0;
int gem_size_kb = 0;
};
// static
......@@ -50,6 +53,9 @@ constexpr int ArcSystemStatCollector::kZramStatColumns[];
// static
constexpr int ArcSystemStatCollector::kMemInfoColumns[];
// static
constexpr int ArcSystemStatCollector::kGemInfoColumns[];
ArcSystemStatCollector::ArcSystemStatCollector() : weak_ptr_factory_(this) {}
ArcSystemStatCollector::~ArcSystemStatCollector() = default;
......@@ -88,6 +94,10 @@ void ArcSystemStatCollector::Flush(const base::TimeTicks& min_timestamp,
ArcValueEvent::Type::kMemTotal);
ArcValueEventTrimmer mem_used(&system_model->memory_events(),
ArcValueEvent::Type::kMemUsed);
ArcValueEventTrimmer gem_objects(&system_model->memory_events(),
ArcValueEvent::Type::kGemObjects);
ArcValueEventTrimmer gem_size(&system_model->memory_events(),
ArcValueEvent::Type::kGemSize);
ArcValueEventTrimmer swap_read(&system_model->memory_events(),
ArcValueEvent::Type::kSwapRead);
ArcValueEventTrimmer swap_write(&system_model->memory_events(),
......@@ -105,10 +115,19 @@ void ArcSystemStatCollector::Flush(const base::TimeTicks& min_timestamp,
(sample.timestamp - base::TimeTicks()).InMicroseconds();
mem_total.MaybeAdd(timestamp, sample.mem_total_kb);
mem_used.MaybeAdd(timestamp, sample.mem_used_kb);
gem_objects.MaybeAdd(timestamp, sample.gem_objects);
gem_size.MaybeAdd(timestamp, sample.gem_size_kb);
swap_read.MaybeAdd(timestamp, sample.swap_sectors_read);
swap_write.MaybeAdd(timestamp, sample.swap_sectors_write);
swap_wait.MaybeAdd(timestamp, sample.swap_waiting_time_ms);
}
// Trimmer may break time sequence for events of different types. However
// time sequence of events of the same type should be preserved.
std::sort(system_model->memory_events().begin(),
system_model->memory_events().end(),
[](const auto& lhs, const auto& rhs) {
return lhs.timestamp < rhs.timestamp;
});
}
void ArcSystemStatCollector::ScheduleSystemStatUpdate() {
......@@ -143,6 +162,7 @@ ArcSystemStatCollector::ReadSystemStatOnBackgroundThread() {
error_reported = true;
}
}
if (!ParseStatFile(mem_info_path, kMemInfoColumns, current_frame.mem_info)) {
memset(current_frame.mem_info, 0, sizeof(current_frame.mem_info));
static bool error_reported = false;
......@@ -151,6 +171,23 @@ ArcSystemStatCollector::ReadSystemStatOnBackgroundThread() {
error_reported = true;
}
}
#if defined(ARCH_CPU_ARM_FAMILY)
const base::FilePath gem_info_path(
FILE_PATH_LITERAL("/run/debugfs_gpu/exynos_gem_objects"));
#else
const base::FilePath gem_info_path(
FILE_PATH_LITERAL("/run/debugfs_gpu/i915_gem_objects"));
#endif
if (!ParseStatFile(gem_info_path, kGemInfoColumns, current_frame.gem_info)) {
memset(current_frame.gem_info, 0, sizeof(current_frame.gem_info));
static bool error_reported = false;
if (!error_reported) {
LOG(ERROR) << "Failed to read gem info file: " << gem_info_path.value();
error_reported = true;
}
}
return current_frame;
}
......@@ -165,6 +202,9 @@ void ArcSystemStatCollector::UpdateSystemStatOnUiThread(
// Total - available.
current_sample.mem_used_kb =
current_frame.mem_info[0] - current_frame.mem_info[1];
current_sample.gem_objects = current_frame.gem_info[0];
current_sample.gem_size_kb = current_frame.gem_info[1] / 1024;
// We calculate delta, so ignore first update.
if (write_index_) {
current_sample.swap_sectors_read =
......
......@@ -48,6 +48,17 @@ class ArcSystemStatCollector {
-1, // End of sequence
};
// Indices of fields to parse /run/debugfs_gpu/i915_gem_objects
// As an example:
// 656 objects, 354971648 bytes
// 113 unbound objects, 17240064 bytes
// ...
static constexpr int kGemInfoColumns[] = {
0, // Number of objects.
2, // Used memory in bytes.
-1, // End of sequence
};
ArcSystemStatCollector();
~ArcSystemStatCollector();
......@@ -71,6 +82,8 @@ class ArcSystemStatCollector {
int64_t zram_stat[base::size(kZramStatColumns) - 1] = {0};
// total, available.
int64_t mem_info[base::size(kMemInfoColumns) - 1] = {0};
// objects, used bytes.
int64_t gem_info[base::size(kGemInfoColumns) - 1] = {0};
};
// Schedule reading System stat files in |ReadSystemStatOnBackgroundThread| on
......
......@@ -38,6 +38,13 @@ TEST_F(ArcSystemStatCollectorTest, Parse) {
mem_values));
EXPECT_EQ(8058940, mem_values[0]);
EXPECT_EQ(2714260, mem_values[1]);
int64_t gem_values[2];
EXPECT_TRUE(ParseStatFile(GetPath("gem_objects"),
ArcSystemStatCollector::kGemInfoColumns,
gem_values));
EXPECT_EQ(853, gem_values[0]);
EXPECT_EQ(458256384, gem_values[1]);
}
} // namespace arc
......@@ -45,6 +45,8 @@ bool LoadValueEvents(const base::Value* value, ValueEvents* value_events) {
case ArcValueEvent::Type::kSwapRead:
case ArcValueEvent::Type::kSwapWrite:
case ArcValueEvent::Type::kSwapWait:
case ArcValueEvent::Type::kGemObjects:
case ArcValueEvent::Type::kGemSize:
break;
default:
return false;
......
......@@ -20,6 +20,8 @@ struct ArcValueEvent {
kSwapRead,
kSwapWrite,
kSwapWait,
kGemObjects,
kGemSize,
};
ArcValueEvent(int64_t timestamp, Type type, int value);
......@@ -34,6 +36,8 @@ struct ArcValueEvent {
* kSwapRead - number of sectors.
* kSwapWrite - number of sectors.
* kSwapWait - milliseconds.
* kGemObjects - number of objects
* kGemSize - kb
*/
int value;
};
......
......@@ -162,6 +162,10 @@ var valueAttributes = {
2: {color: '#ffc400', name: 'swap read sectors', scale: 1.0, width: 1.0},
// kSwapWrite.
3: {color: '#ff9100', name: 'swap write sectors', scale: 1.0, width: 1.0},
// kGemObjects.
5: {color: '#3d5afe', name: 'geom. objects', scale: 1.0, width: 1.0},
// kGemSize.
6: {color: '#7c4dff', name: 'geom. size mb', scale: 1.0 / 1024.0, width: 1.0},
};
/**
......@@ -1559,6 +1563,11 @@ function setGraphicBuffersModel(model) {
new Events(model.system.memory, 2 /* kSwapRead */, 2 /* kSwapRead */),
new Events(model.system.memory, 3 /* kSwapWrite */, 3 /* kSwapWrite */)
]);
// Geom objects and size.
memoryBands.addChartSources([new Events(
model.system.memory, 5 /* kGemObjects */, 5 /* kGemObjects */)]);
memoryBands.addChartSources(
[new Events(model.system.memory, 6 /* kGemSize */, 6 /* kGemSize */)]);
memoryBands.setVSync(vsyncEvents);
var chromeTitle =
......
853 objects, 458256384 bytes
188 unbound objects, 56565760 bytes
659 bound objects, 386105344 bytes
159 purgeable objects, 51441664 bytes
25 mapped objects, 1945600 bytes
1 display objects (pinned), 15360000 bytes
4294967296 [268435456] gtt total
[k]contexts: 46 objects, 2297856 bytes (0 active, 2297856 inactive, 2297856 global, 0 shared, 0 unbound)
frecon: 3 objects, 46080000 bytes (0 active, 46080000 inactive, 46080000 global, 0 shared, 0 unbound)
chrome: 5 objects, 46604288 bytes (0 active, 46604288 inactive, 46604288 global, 46080000 shared, 0 unbound)
chrome: 494 objects, 204873728 bytes (0 active, 296136704 inactive, 46080000 global, 46080000 shared, 876544 unbound)
surfaceflinger: 29 objects, 46206976 bytes (0 active, 44929024 inactive, 14475264 global, 45400064 shared, 15753216 unbound)
RenderThread: 22 objects, 401408 bytes (0 active, 180224 inactive, 0 global, 4096 shared, 221184 unbound)
Binder:12_3: 11 objects, 30973952 bytes (0 active, 0 inactive, 0 global, 30973952 shared, 30965760 unbound)
RenderThread: 1 objects, 4096 bytes (0 active, 0 inactive, 0 global, 4096 shared, 0 unbound)
RenderThread: 33 objects, 716800 bytes (0 active, 581632 inactive, 0 global, 4096 shared, 135168 unbound)
RenderThread: 2 objects, 8192 bytes (0 active, 0 inactive, 0 global, 8192 shared, 4096 unbound)
RenderThread: 33 objects, 8388608 bytes (0 active, 8253440 inactive, 0 global, 0 shared, 135168 unbound)
android.display: 3 objects, 30736384 bytes (0 active, 0 inactive, 0 global, 30736384 shared, 30736384 unbound)
Binder:730_1: 2 objects, 30720000 bytes (0 active, 0 inactive, 0 global, 30720000 shared, 15360000 unbound)
RenderThread: 148 objects, 51597312 bytes (0 active, 27537408 inactive, 0 global, 0 shared, 24059904 unbound)
RenderThread: 26 objects, 50978816 bytes (0 active, 50769920 inactive, 0 global, 0 shared, 208896 unbound)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment