Internal 64M buffer for profiling
- when profiling is compiled in kernel includes a 64M buffer for sample - 64M is the default used by profile tool as its buffer - when using nmi profiling it is not possible to always copy sample stright to userland as the nmi may (and does) happen in bad moments - reduces sampling overhead as samples are copied out only when profiling stops
This commit is contained in:
parent
e63b85a50b
commit
87c576584d
3 changed files with 20 additions and 18 deletions
|
@ -63,32 +63,26 @@ PUBLIC void stop_profile_clock()
|
||||||
|
|
||||||
PRIVATE sprof_save_sample(struct proc * p)
|
PRIVATE sprof_save_sample(struct proc * p)
|
||||||
{
|
{
|
||||||
struct sprof_sample s;
|
struct sprof_sample *s;
|
||||||
|
|
||||||
s.proc = p->p_endpoint;
|
s = (struct sprof_sample *) (sprof_sample_buffer + sprof_info.mem_used);
|
||||||
s.pc = (void *) p->p_reg.pc;
|
|
||||||
|
|
||||||
/* Store sample (process name and program counter). */
|
s->proc = p->p_endpoint;
|
||||||
data_copy(KERNEL, (vir_bytes) &s,
|
s->pc = (void *) p->p_reg.pc;
|
||||||
sprof_ep, sprof_data_addr_vir + sprof_info.mem_used,
|
|
||||||
sizeof(s));
|
|
||||||
|
|
||||||
sprof_info.mem_used += sizeof(s);
|
sprof_info.mem_used += sizeof(struct sprof_sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIVATE sprof_save_proc(struct proc * p)
|
PRIVATE sprof_save_proc(struct proc * p)
|
||||||
{
|
{
|
||||||
struct sprof_proc s;
|
struct sprof_proc * s;
|
||||||
|
|
||||||
s.proc = p->p_endpoint;
|
s = (struct sprof_proc *) (sprof_sample_buffer + sprof_info.mem_used);
|
||||||
memcpy(s.name, p->p_name, P_NAME_LEN);
|
|
||||||
|
|
||||||
/* Store sample (process name and program counter). */
|
s->proc = p->p_endpoint;
|
||||||
data_copy(KERNEL, (vir_bytes) &s,
|
memcpy(&s->name, p->p_name, P_NAME_LEN);
|
||||||
sprof_ep, sprof_data_addr_vir + sprof_info.mem_used,
|
|
||||||
sizeof(s));
|
|
||||||
|
|
||||||
sprof_info.mem_used += sizeof(s);
|
sprof_info.mem_used += sizeof(struct sprof_proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIVATE void profile_sample(struct proc * p)
|
PRIVATE void profile_sample(struct proc * p)
|
||||||
|
@ -100,7 +94,9 @@ PRIVATE void profile_sample(struct proc * p)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Check if enough memory available before writing sample. */
|
/* Check if enough memory available before writing sample. */
|
||||||
if (sprof_info.mem_used + sizeof(sprof_info) > sprof_mem_size) {
|
if (sprof_info.mem_used + sizeof(sprof_info) +
|
||||||
|
2*sizeof(struct sprof_sample) +
|
||||||
|
2*sizeof(struct sprof_sample) > sprof_mem_size) {
|
||||||
sprof_info.mem_used = -1;
|
sprof_info.mem_used = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
|
|
||||||
#include "arch_watchdog.h"
|
#include "arch_watchdog.h"
|
||||||
|
|
||||||
|
#define SAMPLE_BUFFER_SIZE (64 << 20)
|
||||||
|
EXTERN char sprof_sample_buffer[SAMPLE_BUFFER_SIZE];
|
||||||
|
|
||||||
EXTERN int sprofiling; /* whether profiling is running */
|
EXTERN int sprofiling; /* whether profiling is running */
|
||||||
EXTERN int sprofiling_type; /* whether profiling is running */
|
EXTERN int sprofiling_type; /* whether profiling is running */
|
||||||
EXTERN int sprof_mem_size; /* available user memory for data */
|
EXTERN int sprof_mem_size; /* available user memory for data */
|
||||||
|
|
|
@ -65,7 +65,8 @@ PUBLIC int do_sprofile(struct proc * caller, message * m_ptr)
|
||||||
sprof_info.system_samples = 0;
|
sprof_info.system_samples = 0;
|
||||||
sprof_info.user_samples = 0;
|
sprof_info.user_samples = 0;
|
||||||
|
|
||||||
sprof_mem_size = m_ptr->PROF_MEM_SIZE;
|
sprof_mem_size = m_ptr->PROF_MEM_SIZE < SAMPLE_BUFFER_SIZE ?
|
||||||
|
m_ptr->PROF_MEM_SIZE : SAMPLE_BUFFER_SIZE;
|
||||||
|
|
||||||
switch (sprofiling_type = m_ptr->PROF_INTR_TYPE) {
|
switch (sprofiling_type = m_ptr->PROF_INTR_TYPE) {
|
||||||
case PROF_RTC:
|
case PROF_RTC:
|
||||||
|
@ -111,6 +112,8 @@ PUBLIC int do_sprofile(struct proc * caller, message * m_ptr)
|
||||||
|
|
||||||
data_copy(KERNEL, (vir_bytes) &sprof_info,
|
data_copy(KERNEL, (vir_bytes) &sprof_info,
|
||||||
sprof_ep, sprof_info_addr_vir, sizeof(sprof_info));
|
sprof_ep, sprof_info_addr_vir, sizeof(sprof_info));
|
||||||
|
data_copy(KERNEL, (vir_bytes) sprof_sample_buffer,
|
||||||
|
sprof_ep, sprof_data_addr_vir, sprof_info.mem_used);
|
||||||
|
|
||||||
clean_seen_flag();
|
clean_seen_flag();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue