X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;ds=sidebyside;f=lttv%2Flttv%2Fstate.c;h=25af4116000fc457adf4d7eff7f1d11b0f942bbd;hb=b4242c87f4df774c5700e56fbf28410cc1a30ed2;hp=d65ee57f67ef5c78f0cdc11dcdd9b85eb11a687f;hpb=8f31828398b8a4fcdb679324291132f4f0e3dce6;p=lttv.git diff --git a/lttv/lttv/state.c b/lttv/lttv/state.c index d65ee57f..25af4116 100644 --- a/lttv/lttv/state.c +++ b/lttv/lttv/state.c @@ -136,7 +136,9 @@ GQuark LTT_FIELD_ADDRESS, LTT_FIELD_SYMBOL, LTT_FIELD_IP, - LTT_FIELD_FD; + LTT_FIELD_FD, + LTT_FIELD_STATE, + LTT_FIELD_CPU_ID; LttvExecutionMode LTTV_STATE_MODE_UNKNOWN, @@ -232,7 +234,7 @@ static void bdevstate_free_cb(gpointer key, gpointer value, gpointer user_data); static LttvBdevState *bdevstate_copy(LttvBdevState *bds); -#if (__SIZEOF_LONG__ == 4) +#if (__WORDSIZE == 32) guint guint64_hash(gconstpointer key) { guint64 ukey = *(const guint64 *)key; @@ -355,7 +357,7 @@ static void expand_syscall_table(LttvTraceState *ts, int id) static void expand_kprobe_table(LttvTraceState *ts, guint64 ip, char *symbol) { LttvNameTables *nt = ts->name_tables; -#if (__SIZEOF_LONG__ == 4) +#if (__WORDSIZE == 32) guint64 *ip_ptr = g_new(guint64, 1); g_hash_table_insert(nt->kprobe_hash, ip_ptr, (gpointer)(glong)g_quark_from_string(symbol)); @@ -2055,10 +2057,12 @@ create_name_tables(LttvTraceState *tcs) name_tables->irq_names[i] = g_quark_from_string(ltt_enum_string_get(t, i)); } */ + /* FIXME: LttvIRQState *irq_states should become a g_array */ + /* temp fix: increase from 256 to 512 default size */ - name_tables->nb_irqs = 256; - name_tables->irq_names = g_new(GQuark, 256); - for(i = 0 ; i < 256 ; i++) { + name_tables->nb_irqs = 512; + name_tables->irq_names = g_new(GQuark, 512); + for(i = 0 ; i < 512 ; i++) { g_string_printf(fe_name, "irq %d", i); name_tables->irq_names[i] = g_quark_from_string(fe_name->str); } @@ -2085,7 +2089,7 @@ create_name_tables(LttvTraceState *tcs) g_string_free(fe_name, TRUE); -#if (__SIZEOF_LONG__ == 4) +#if (__WORDSIZE == 32) name_tables->kprobe_hash = g_hash_table_new_full(guint64_hash, guint64_equal, g_free, NULL); #else @@ -2933,6 +2937,30 @@ static gboolean dump_softirq(void *hook_data, void *call_data) return FALSE; } +static gboolean sched_try_wakeup(void *hook_data, void *call_data) +{ + LttvTracefileState *s = (LttvTracefileState *)call_data; + LttEvent *e = ltt_tracefile_get_event(s->parent.tf); + LttvTraceHook *th = (LttvTraceHook *)hook_data; + LttvProcessState *process; + gint woken_pid; + guint woken_cpu; + + woken_pid = ltt_event_get_int(e, lttv_trace_get_hook_field(th, 0)); + woken_cpu = ltt_event_get_unsigned(e, lttv_trace_get_hook_field(th, 1)); + + process = lttv_state_find_process_or_create( + (LttvTraceState*)s->parent.t_context, + woken_cpu, woken_pid, + &s->parent.timestamp); + process->state->s = LTTV_STATE_WAIT_CPU; + process->state->change = s->parent.timestamp; + + g_debug("Wakeup: process %d on CPU %u\n", woken_pid, woken_cpu); + + return FALSE; +} + static gboolean schedchange(void *hook_data, void *call_data) { LttvTracefileState *s = (LttvTracefileState *)call_data; @@ -3285,6 +3313,25 @@ static gboolean fs_open(void *hook_data, void *call_data) return FALSE; } +static void print_stack(LttvProcessState *process) +{ + LttvExecutionState *es; + int i; + + g_debug("Execution stack for process %u %s:\n", + process->pid, g_quark_to_string(process->name)); + + for (i = 0; i < process->execution_stack->len; i++) { + es = &g_array_index(process->execution_stack, + LttvExecutionState, i); + g_debug("Depth %d mode %s submode %s status %s\n", + i, g_quark_to_string(es->t), + g_quark_to_string(es->n), + g_quark_to_string(es->s)); + } + +} + static void fix_process(gpointer key, gpointer value, gpointer user_data) { @@ -3293,6 +3340,8 @@ static void fix_process(gpointer key, gpointer value, process = (LttvProcessState *)value; LttTime *timestamp = (LttTime*)user_data; + print_stack(process); + if(process->type == LTTV_STATE_KERNEL_THREAD) { es = &g_array_index(process->execution_stack, LttvExecutionState, 0); if(es->t == LTTV_STATE_MODE_UNKNOWN) { @@ -3317,21 +3366,28 @@ static void fix_process(gpointer key, gpointer value, es->s = LTTV_STATE_RUN; if(process->execution_stack->len == 1) { - /* Still in bottom unknown mode, means never did a system call + /* Still in bottom unknown mode, means we either: + * - never did a system call + * - are scheduled out from user mode. * May be either in user mode, syscall mode, running or waiting.*/ - /* FIXME : we may be tagging syscall mode when being user mode */ - process->execution_stack = - g_array_set_size(process->execution_stack, 2); - es = process->state = &g_array_index(process->execution_stack, - LttvExecutionState, 1); - es->t = LTTV_STATE_SYSCALL; - es->n = LTTV_STATE_SUBMODE_NONE; - es->entry = *timestamp; - //g_assert(timestamp->tv_sec != 0); - es->change = *timestamp; - es->cum_cpu_time = ltt_time_zero; - if(es->s == LTTV_STATE_WAIT_FORK) - es->s = LTTV_STATE_WAIT; + /* CHECK : we may be tagging syscall mode when being user mode + * (should be fixed now) */ + if (es->s == LTTV_STATE_WAIT_CPU) { + /* nothing to do: scheduled out from userspace */ + } else { + process->execution_stack = + g_array_set_size(process->execution_stack, 2); + es = process->state = &g_array_index(process->execution_stack, + LttvExecutionState, 1); + es->t = LTTV_STATE_SYSCALL; + es->n = LTTV_STATE_SUBMODE_NONE; + es->entry = *timestamp; + //g_assert(timestamp->tv_sec != 0); + es->change = *timestamp; + es->cum_cpu_time = ltt_time_zero; + if(es->s == LTTV_STATE_WAIT_FORK) + es->s = LTTV_STATE_WAIT; + } } } } @@ -3638,6 +3694,12 @@ void lttv_state_add_event_hooks(LttvTracesetState *self) LTT_FIELD_PREV_STATE), schedchange, NULL, &hooks); + lttv_trace_find_hook(ts->parent.t, + LTT_CHANNEL_KERNEL, + LTT_EVENT_SCHED_TRY_WAKEUP, + FIELD_ARRAY(LTT_FIELD_PID, LTT_FIELD_CPU_ID, LTT_FIELD_STATE), + sched_try_wakeup, NULL, &hooks); + lttv_trace_find_hook(ts->parent.t, LTT_CHANNEL_KERNEL, LTT_EVENT_PROCESS_FORK, @@ -4484,6 +4546,8 @@ static void module_init() LTT_FIELD_SYMBOL = g_quark_from_string("symbol"); LTT_FIELD_IP = g_quark_from_string("ip"); LTT_FIELD_FD = g_quark_from_string("fd"); + LTT_FIELD_STATE = g_quark_from_string("state"); + LTT_FIELD_CPU_ID = g_quark_from_string("cpu_id"); LTTV_CPU_UNKNOWN = g_quark_from_string("unknown"); LTTV_CPU_IDLE = g_quark_from_string("idle");