X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Flttv%2Fstate.c;h=3ef8a2162318cbaa26a82aae9ec39cd35d6f833d;hb=a81d2a59d85b15507a64cc2e8cc53b7be4330fdc;hp=5fb450f0ea2385dbd38bf3ec36f4f61dca044f77;hpb=0e2767c231bc73762d35be6471671ef76b3954a3;p=lttv.git diff --git a/ltt/branches/poly/lttv/lttv/state.c b/ltt/branches/poly/lttv/lttv/state.c index 5fb450f0..3ef8a216 100644 --- a/ltt/branches/poly/lttv/lttv/state.c +++ b/ltt/branches/poly/lttv/lttv/state.c @@ -142,6 +142,7 @@ LttvCPUMode LTTV_CPU_IDLE, LTTV_CPU_BUSY, LTTV_CPU_IRQ, + LTTV_CPU_SOFT_IRQ, LTTV_CPU_TRAP; LttvIRQMode @@ -170,6 +171,8 @@ static GQuark LTTV_STATE_RESOURCE_CPUS, LTTV_STATE_RESOURCE_CPUS_COUNT, LTTV_STATE_RESOURCE_IRQS, + LTTV_STATE_RESOURCE_SOFT_IRQS, + LTTV_STATE_RESOURCE_TRAPS, LTTV_STATE_RESOURCE_BLKDEVS; static void create_max_time(LttvTraceState *tcs); @@ -261,7 +264,7 @@ gboolean rettrue(gpointer key, gpointer value, gpointer user_data) static void restore_init_state(LttvTraceState *self) { - guint i, nb_cpus, nb_irqs; + guint i, nb_cpus, nb_irqs, nb_soft_irqs, nb_traps; //LttvTracefileState *tfcs; @@ -287,6 +290,8 @@ restore_init_state(LttvTraceState *self) nb_cpus = ltt_trace_get_num_cpu(self->parent.t); nb_irqs = self->nb_irqs; + nb_soft_irqs = self->nb_soft_irqs; + nb_traps = self->nb_traps; /* Put the per cpu running_process to beginning state : process 0. */ for(i=0; i< nb_cpus; i++) { @@ -317,6 +322,16 @@ restore_init_state(LttvTraceState *self) g_array_remove_range(self->irq_states[i].mode_stack, 0, self->irq_states[i].mode_stack->len); } + /* reset softirq states */ + for(i=0; isoft_irq_states[i].running = 0; + } + + /* reset trap states */ + for(i=0; itrap_states[i].running = 0; + } + /* reset bdev states */ g_hash_table_foreach(self->bdev_states, bdevstate_free_cb, NULL); //g_hash_table_steal_all(self->bdev_states); @@ -486,6 +501,13 @@ init(LttvTracesetState *self, LttvTraceset *ts) g_assert(tcs->irq_states[j].mode_stack != NULL); } + /* init soft irq stuff */ + /* the kernel has a statically fixed max of 32 softirqs */ + tcs->soft_irq_states = g_new(LttvSoftIRQState, tcs->nb_soft_irqs); + + /* init trap stuff */ + tcs->trap_states = g_new(LttvTrapState, tcs->nb_traps); + /* init bdev resource stuff */ tcs->bdev_states = g_hash_table_new(g_int_hash, g_int_equal); @@ -1194,6 +1216,44 @@ static void lttv_state_free_irq_states(LttvIRQState *states, guint n) g_free(states); } +static LttvSoftIRQState *lttv_state_copy_soft_irq_states(LttvSoftIRQState *states, guint n) +{ + guint i; + LttvSoftIRQState *retval; + + retval = g_malloc(n*sizeof(LttvSoftIRQState)); + + for(i=0; iirq_states, nb_irqs); } + /* save the soft irq state */ + nb_soft_irqs = self->nb_soft_irqs; + { + value = lttv_attribute_add(container, LTTV_STATE_RESOURCE_SOFT_IRQS, + LTTV_POINTER); + *(value.v_pointer) = lttv_state_copy_soft_irq_states(self->soft_irq_states, nb_soft_irqs); + } + + /* save the trap state */ + nb_traps = self->nb_traps; + { + value = lttv_attribute_add(container, LTTV_STATE_RESOURCE_TRAPS, + LTTV_POINTER); + *(value.v_pointer) = lttv_state_copy_trap_states(self->trap_states, nb_traps); + } + /* save the blkdev states */ value = lttv_attribute_add(container, LTTV_STATE_RESOURCE_BLKDEVS, LTTV_POINTER); @@ -1382,7 +1458,7 @@ static void state_save(LttvTraceState *self, LttvAttribute *container) static void state_restore(LttvTraceState *self, LttvAttribute *container) { - guint i, nb_tracefile, pid, nb_cpus, nb_irqs; + guint i, nb_tracefile, pid, nb_cpus, nb_irqs, nb_soft_irqs, nb_traps; LttvTracefileState *tfcs; @@ -1441,6 +1517,20 @@ static void state_restore(LttvTraceState *self, LttvAttribute *container) lttv_state_free_irq_states(self->irq_states, nb_irqs); self->irq_states = lttv_state_copy_irq_states(*(value.v_pointer), nb_irqs); + /* restore soft irq resource states */ + nb_soft_irqs = self->nb_soft_irqs; + type = lttv_attribute_get_by_name(container, LTTV_STATE_RESOURCE_SOFT_IRQS, &value); + g_assert(type == LTTV_POINTER); + lttv_state_free_soft_irq_states(self->soft_irq_states, nb_soft_irqs); + self->soft_irq_states = lttv_state_copy_soft_irq_states(*(value.v_pointer), nb_soft_irqs); + + /* restore trap resource states */ + nb_traps = self->nb_traps; + type = lttv_attribute_get_by_name(container, LTTV_STATE_RESOURCE_TRAPS, &value); + g_assert(type == LTTV_POINTER); + lttv_state_free_trap_states(self->trap_states, nb_traps); + self->trap_states = lttv_state_copy_trap_states(*(value.v_pointer), nb_traps); + /* restore the blkdev states */ type = lttv_attribute_get_by_name(container, LTTV_STATE_RESOURCE_BLKDEVS, &value); g_assert(type == LTTV_POINTER); @@ -1755,9 +1845,10 @@ create_name_tables(LttvTraceState *tcs) } */ - name_tables->nb_softirqs = 256; - name_tables->soft_irq_names = g_new(GQuark, 256); - for(i = 0 ; i < 256 ; i++) { + /* the kernel is limited to 32 statically defined softirqs */ + name_tables->nb_softirqs = 32; + name_tables->soft_irq_names = g_new(GQuark, name_tables->nb_softirqs); + for(i = 0 ; i < name_tables->nb_softirqs ; i++) { g_string_printf(fe_name, "softirq %d", i); name_tables->soft_irq_names[i] = g_quark_from_string(fe_name->str); } @@ -1786,7 +1877,7 @@ get_name_tables(LttvTraceState *tcs) tcs->irq_names = name_tables->irq_names; tcs->soft_irq_names = name_tables->soft_irq_names; tcs->nb_irqs = name_tables->nb_irqs; - tcs->nb_softirqs = name_tables->nb_softirqs; + tcs->nb_soft_irqs = name_tables->nb_softirqs; } @@ -2223,6 +2314,7 @@ static gboolean syscall_exit(void *hook_data, void *call_data) static gboolean trap_entry(void *hook_data, void *call_data) { LttvTracefileState *s = (LttvTracefileState *)call_data; + LttvTraceState *ts = (LttvTraceState *)s->parent.t_context; LttEvent *e = ltt_tracefile_get_event(s->parent.tf); LttvTraceHook *th = (LttvTraceHook *)hook_data; struct marker_field *f = lttv_trace_get_hook_field(th, 0); @@ -2247,18 +2339,28 @@ static gboolean trap_entry(void *hook_data, void *call_data) /* update cpu status */ cpu_push_mode(s->cpu_state, LTTV_CPU_TRAP); + /* update trap status */ + s->cpu_state->last_trap = trap; + ts->trap_states[trap].running++; + return FALSE; } static gboolean trap_exit(void *hook_data, void *call_data) { LttvTracefileState *s = (LttvTracefileState *)call_data; + LttvTraceState *ts = (LttvTraceState *)s->parent.t_context; + guint trap = s->cpu_state->last_trap; pop_state(s, LTTV_STATE_TRAP); /* update cpu status */ cpu_pop_mode(s->cpu_state); + /* update trap status */ + if(ts->trap_states[trap].running) + ts->trap_states[trap].running--; + return FALSE; } @@ -2301,12 +2403,20 @@ static gboolean irq_entry(void *hook_data, void *call_data) static gboolean soft_irq_exit(void *hook_data, void *call_data) { LttvTracefileState *s = (LttvTracefileState *)call_data; + LttvTraceState *ts = (LttvTraceState *)s->parent.t_context; + guint softirq = s->cpu_state->last_soft_irq; pop_state(s, LTTV_STATE_SOFT_IRQ); - return FALSE; -} + /* update softirq status */ + if(ts->soft_irq_states[softirq].running) + ts->soft_irq_states[softirq].running--; + + /* update cpu status */ + cpu_pop_mode(s->cpu_state); + return FALSE; +} static gboolean irq_exit(void *hook_data, void *call_data) { @@ -2327,6 +2437,7 @@ static gboolean irq_exit(void *hook_data, void *call_data) static gboolean soft_irq_entry(void *hook_data, void *call_data) { LttvTracefileState *s = (LttvTracefileState *)call_data; + LttvTraceState *ts = (LttvTraceState *)s->parent.t_context; LttEvent *e = ltt_tracefile_get_event(s->parent.tf); //guint8 ev_id = ltt_event_eventtype_id(e); LttvTraceHook *th = (LttvTraceHook *)hook_data; @@ -2334,7 +2445,7 @@ static gboolean soft_irq_entry(void *hook_data, void *call_data) LttvExecutionSubmode submode; guint64 softirq = ltt_event_get_long_unsigned(e, f); - guint64 nb_softirqs = ((LttvTraceState *)(s->parent.t_context))->nb_softirqs; + guint64 nb_softirqs = ((LttvTraceState *)(s->parent.t_context))->nb_soft_irqs; if(softirq < nb_softirqs) { submode = ((LttvTraceState *)(s->parent.t_context))->soft_irq_names[softirq]; @@ -2348,6 +2459,14 @@ static gboolean soft_irq_entry(void *hook_data, void *call_data) /* Do something with the info about being in user or system mode when int? */ push_state(s, LTTV_STATE_SOFT_IRQ, submode); + + /* update cpu status */ + cpu_push_mode(s->cpu_state, LTTV_CPU_SOFT_IRQ); + + /* update softirq status */ + s->cpu_state->last_soft_irq = softirq; + ts->soft_irq_states[softirq].running++; + return FALSE; } @@ -2550,7 +2669,7 @@ static gboolean schedchange(void *hook_data, void *call_data) process->state->change = s->parent.timestamp; } - if(state_out == 32 || state_out == 128) + if(state_out == 32 || state_out == 64) exit_process(s, process); /* EXIT_DEAD || TASK_DEAD */ /* see sched.h for states */ } @@ -3864,6 +3983,8 @@ static void module_init() LTTV_STATE_RESOURCE_CPUS = g_quark_from_string("cpu resource states"); LTTV_STATE_RESOURCE_CPUS = g_quark_from_string("cpu count"); LTTV_STATE_RESOURCE_IRQS = g_quark_from_string("irq resource states"); + LTTV_STATE_RESOURCE_SOFT_IRQS = g_quark_from_string("soft irq resource states"); + LTTV_STATE_RESOURCE_TRAPS = g_quark_from_string("trap resource states"); LTTV_STATE_RESOURCE_BLKDEVS = g_quark_from_string("blkdevs resource states"); @@ -3928,6 +4049,7 @@ static void module_init() LTTV_CPU_IDLE = g_quark_from_string("idle"); LTTV_CPU_BUSY = g_quark_from_string("busy"); LTTV_CPU_IRQ = g_quark_from_string("irq"); + LTTV_CPU_SOFT_IRQ = g_quark_from_string("softirq"); LTTV_CPU_TRAP = g_quark_from_string("trap"); LTTV_IRQ_UNKNOWN = g_quark_from_string("unknown");