top: react on too small trace argument buffer size

Issue #3811
This commit is contained in:
Alexander Boettcher
2020-07-07 16:55:13 +02:00
committed by Norman Feske
parent 21e48a8e12
commit c4a8c6798b

View File

@@ -68,9 +68,6 @@ struct Trace_subject_registry
return nullptr; return nullptr;
} }
enum { MAX_SUBJECTS = 1024 };
Genode::Trace::Subject_id _subjects[MAX_SUBJECTS];
enum { MAX_CPUS_X = 16, MAX_CPUS_Y = 4, MAX_ELEMENTS_PER_CPU = 6}; enum { MAX_CPUS_X = 16, MAX_CPUS_Y = 4, MAX_ELEMENTS_PER_CPU = 6};
/* accumulated execution time on all CPUs */ /* accumulated execution time on all CPUs */
@@ -80,37 +77,14 @@ struct Trace_subject_registry
/* most significant consumer per CPU */ /* most significant consumer per CPU */
Entry const * load[MAX_CPUS_X][MAX_CPUS_Y][MAX_ELEMENTS_PER_CPU]; Entry const * load[MAX_CPUS_X][MAX_CPUS_Y][MAX_ELEMENTS_PER_CPU];
bool _reconstruct_trace_connection = false;
template <typename FN>
unsigned update_subjects(Genode::Pd_session &pd,
Genode::Trace::Connection &trace,
FN const &fn)
{
Genode::Ram_quota ram_quota;
do {
try {
return trace.for_each_subject_info(fn).count;
} catch (Genode::Out_of_ram) {
trace.upgrade_ram(4096);
}
ram_quota = pd.avail_ram();
_reconstruct_trace_connection = (ram_quota.value < 4 * 4096);
} while (ram_quota.value >= 2 * 4096);
return 0;
}
public: public:
void update(Genode::Pd_session &pd, Genode::Trace::Connection &trace, bool update(Genode::Trace::Connection &trace,
Genode::Allocator &alloc) Genode::Allocator &alloc)
{ {
update_subjects(pd, trace, [&](Genode::Trace::Subject_id const &id, Genode::Trace::Subject_info const &info) { auto res = trace.for_each_subject_info([&](Genode::Trace::Subject_id const &id,
Genode::Trace::Subject_info const &info)
{
Entry *e = _lookup(id); Entry *e = _lookup(id);
if (!e) { if (!e) {
e = new (alloc) Entry(id); e = new (alloc) Entry(id);
@@ -129,14 +103,11 @@ struct Trace_subject_registry
} }
}); });
if (_reconstruct_trace_connection) return res.count < res.limit;
throw Genode::Out_of_ram();
} }
void flush(Genode::Trace::Connection &trace, Genode::Allocator &alloc) void flush(Genode::Trace::Connection &trace, Genode::Allocator &alloc)
{ {
_reconstruct_trace_connection = false;
while (Entry * const e = _entries.first()) { while (Entry * const e = _entries.first()) {
trace.free(e->id); trace.free(e->id);
_entries.remove(e); _entries.remove(e);
@@ -312,13 +283,16 @@ struct App::Main
Env &_env; Env &_env;
enum { enum {
TRACE_RAM_QUOTA = 20 * 4096,
ARG_BUFFER_RAM = 32 * 1024,
PARENT_LEVELS = 0 PARENT_LEVELS = 0
}; };
Reconstructible<Trace::Connection> _trace { _env, TRACE_RAM_QUOTA, size_t trace_ram_quota { 20 * 4096 };
ARG_BUFFER_RAM, PARENT_LEVELS }; size_t arg_buffer_ram { 10 * 4096 };
Reconstructible<Trace::Connection> _trace { _env,
trace_ram_quota,
arg_buffer_ram,
PARENT_LEVELS };
static uint64_t _default_period_ms() { return 5000; } static uint64_t _default_period_ms() { return 5000; }
@@ -376,27 +350,25 @@ void App::Main::_handle_config()
void App::Main::_handle_period() void App::Main::_handle_period()
{ {
bool reconstruct = false;
/* update subject information */ /* update subject information */
try { bool const arg_buffer_sufficient = _trace_subject_registry.update(*_trace,
_trace_subject_registry.update(_env.pd(), *_trace, _heap); _heap);
} catch (Genode::Out_of_ram) { if (arg_buffer_sufficient) {
reconstruct = true;
}
/* show most significant consumers */ /* show most significant consumers */
_trace_subject_registry.top(_sort); _trace_subject_registry.top(_sort);
return;
}
trace_ram_quota += 4096;
arg_buffer_ram += 4 * 4096;
/* by destructing the session we free up the allocated memory in core */ /* by destructing the session we free up the allocated memory in core */
if (reconstruct) { Genode::warning("re-construct trace session");
Genode::warning("re-construct trace session because of out of memory");
_trace_subject_registry.flush(*_trace, _heap); _trace_subject_registry.flush(*_trace, _heap);
_trace.destruct(); _trace.destruct();
_trace.construct(_env, TRACE_RAM_QUOTA, ARG_BUFFER_RAM, PARENT_LEVELS); _trace.construct(_env, trace_ram_quota, arg_buffer_ram, PARENT_LEVELS);
}
} }