Beispiel #1
0
static void kernel_syscall_entry_process(struct ltt_module *mod,
                                             struct parse_result *res, int pass)
{
    unsigned int ip, id;

    kernel_common(res, pass);
    if (sscanf(res->values, " ip = 0x%x, syscall_id = %u",
               &ip, &id) != 2) {
        PARSE_ERROR(mod, res->values);
        return;
    }

    if (pass == 1) {
        atag_store(ip);
    }
    if (pass == 2) {
        struct ltt_trace *current_process;
        current_process = find_task_trace(res->pid);
        emit_trace(current_process, (union ltt_value)PROCESS_KERNEL);
		current_process->value = (union ltt_value)PROCESS_KERNEL;
        if (id < sizeof(syscall_name)/sizeof(syscall_name[0]))
            emit_trace(&current_process[1], (union ltt_value)syscall_name[id]);
        else
            emit_trace(&current_process[1], (union ltt_value)"syscall %d", id);
        emit_trace(&syscall_id, (union ltt_value)id);
        emit_trace(&syscall_pc, (union ltt_value)ip);
    }
}
Beispiel #2
0
static void kernel_common(struct parse_result *res, int pass)
{
    static char old_mode [15];
    static double start_time;

    if (pass == 1) {
        init_traces();
        find_or_add_task_trace(res->pname, res->pid, 0);
    }
    if (pass == 2) {
        if (strcmp(old_mode, res->mode))
            emit_trace(&mode, (union ltt_value)res->mode);
        memcpy(old_mode, res->mode, sizeof(old_mode));
        old_mode[sizeof(old_mode)-1] = 0;

		/* 300 ms average for cpu load */
		if (res->clock - start_time > 0.3) {
			double idle_run = emit_cpu_idle_state(res, (union ltt_value)(char *)NULL);
			if (start_time > 0) {
				emit_trace(&cpu_load, (union ltt_value)(1.0-idle_run/(res->clock - start_time)));
			}
			start_time = res->clock;
		}
    }
}
Beispiel #3
0
static void kernel_softirq_entry_process(struct ltt_module *mod,
                                         struct parse_result *res, int pass)
{
    int id;
    char *s;

    kernel_common(res, pass);
    if (sscanf(res->values, " softirq_id = %d [%m[^]]", &id, &s) != 2) {
        PARSE_ERROR(mod, res->values);
        return;
    }
    if (pass == 2) {
        emit_trace(&sirq[0], (union ltt_value)SOFTIRQ_RUNNING);
        emit_cpu_idle_state(res, (union ltt_value)IDLE_CPU_PREEMPT);
        if (id < sizeof(sofirq_tag)/sizeof(char *) && sofirq_tag[id])
            emit_trace(&sirq[1], (union ltt_value)sofirq_tag[id]);
        else
            emit_trace(&sirq[1], (union ltt_value)"softirq %d", id);
        emit_trace(&sirq[2], (union ltt_value)s);
        softirqstate = SOFTIRQS_RUN;
        /* stat stuff */
        strncpy(softirqtask, s, sizeof(softirqtask));
        softirqtask[sizeof(softirqtask)-1] = 0;
        softirqtime = res->clock;
        /* end stat stuff */
    }
    free(s);
}
Beispiel #4
0
static void kernel_page_fault_get_user_exit_process(struct ltt_module *mod,
                                         struct parse_result *res, int pass)
{
    if (pass == 1) {
        init_traces();
    }
       if (pass == 2) {
               emit_trace(&trace_fault[2], (union ltt_value)LT_IDLE);
       }
}
Beispiel #5
0
static void kernel_tasklet_low_exit_process(struct ltt_module *mod,
                                            struct parse_result *res, int pass)
{
    kernel_common(res, pass);
    if (pass == 1) {
    }
    if (pass == 2) {
        emit_trace(&tlow[0], (union ltt_value)LT_IDLE);
    }
}
Beispiel #6
0
static void kernel_sched_try_wakeup_process(struct ltt_module *mod,
                                          struct parse_result *res, int pass)
{
    unsigned int pid, cpu_id, state;

    kernel_common(res, pass);
    if (sscanf(res->values, " pid = %u, cpu_id = %u, state = %u",
               &pid, &cpu_id, &state) != 3) {
        PARSE_ERROR(mod, res->values);
        return;
    }
    if (pass == 2) {
        emit_trace(&sched_event, (union ltt_value)"%d try wakeup %d", res->pid, pid);
        if (res->pid != pid) {
            struct ltt_trace *next_process;
            next_process = find_task_trace(pid);
            emit_trace(next_process, (union ltt_value)PROCESS_WAKEUP);
        }
    }
}
Beispiel #7
0
static void kernel_page_fault_exit_process(struct ltt_module *mod,
                                         struct parse_result *res, int pass)
{
	int fault;
    if (pass == 1) {
        init_traces();
    }
       if (sscanf(res->values, " res = %d",
                          &fault) != 1) {
               PARSE_ERROR(mod, res->values);
               return;
       }

       if (pass == 2) {
               emit_trace(&trace_fault[0], (union ltt_value)LT_IDLE);
               emit_trace(&trace_fault[1], (union ltt_value)"-> %d",
                   fault);

       }
}
Beispiel #8
0
static void kernel_page_fault_get_user_entry_process(struct ltt_module *mod,
                                          struct parse_result *res, int pass)
{
       int wr;
       unsigned long long address;

    if (pass == 1) {
        init_traces();
    }
       if (sscanf(res->values, " address = %llx, write_access = %d",
                          &address, &wr) != 2) {
               PARSE_ERROR(mod, res->values);
               return;
       }
       if (pass == 2) {
               emit_trace(&trace_fault[2], (union ltt_value)(wr?LT_S2:LT_S0));
               emit_trace(&trace_fault[3], (union ltt_value)"%c@0x%08x",
                   (wr)? 'W' : 'R', (uint32_t)address);
       }
}
Beispiel #9
0
static void kernel_softirq_raise_process(struct ltt_module *mod,
                                         struct parse_result *res, int pass)
{
    int id;

    kernel_common(res, pass);
    if (sscanf(res->values, " softirq_id = %d", &id) != 1) {
        PARSE_ERROR(mod, res->values);
        return;
    }
    if (pass == 2) {
        if (softirqstate == SOFTIRQS_IDLE)
            emit_trace(&sirq[0], (union ltt_value)SOFTIRQ_RAISING);
        if (id < sizeof(sofirq_tag)/sizeof(char *) && sofirq_tag[id])
            emit_trace(&sirq[1], (union ltt_value)"! %s", sofirq_tag[id]);
        else
            emit_trace(&sirq[1], (union ltt_value)"raise %d", id);
        softirqstate = SOFTIRQS_RAISE;
    }
}
Beispiel #10
0
static void kernel_irq_exit_process(struct ltt_module *mod,
                                    struct parse_result *res, int pass)
{
    kernel_common(res, pass);
    if ((pass == 2) && (irqlevel > 0)) {
        emit_trace(&trace[irqtab[--irqlevel]], (union ltt_value)IRQ_IDLE);
        if (irqlevel > 0) {
            emit_trace(&trace[irqtab[irqlevel-1]], (union ltt_value)IRQ_RUNNING);
        }
        if (irqlevel == 0 && idle_cpu_state == IDLE_RUNNING)
            emit_cpu_idle_state(res, (union ltt_value)IDLE_CPU_RUNNING);
        else 
            emit_cpu_idle_state(res, (union ltt_value)IDLE_CPU_IDLE);
        /* stat stuff */
        /* we allow up to 0.1ms irq */
        if (irqlevel == 0 && res->clock - irqtime > 0.0001)
            TDIAG(res, "long irq (%s) : %fs!!!\n", irq_tag[irqtab[0]],
                    res->clock - irqtime);
        /* end stat stuff */
    }
}
Beispiel #11
0
static void kernel_syscall_exit_process(struct ltt_module *mod,
                                             struct parse_result *res, int pass)
{
    int ret;

    kernel_common(res, pass);
    if (sscanf(res->values, " ret = %d",
               &ret) != 1) {
        PARSE_ERROR(mod, res->values);
        return;
    }

    if (pass == 2) {
        struct ltt_trace *current_process;
        current_process = find_task_trace(res->pid);
        emit_trace(current_process, (union ltt_value)PROCESS_USER);
		current_process->value = (union ltt_value)PROCESS_USER;
        /* ret is not valid ... */
        emit_trace(&current_process[1], (union ltt_value)"->%d", ret);
    }
}
Beispiel #12
0
static void kernel_page_fault_entry_process(struct ltt_module *mod,
                                          struct parse_result *res, int pass)
{
       int wr;
       unsigned long ip;
       unsigned long address;

    if (pass == 1) {
        init_traces();
    }
       if (sscanf(res->values, " ip = %lx, address = %lx, trap_id = 14, write_access = %d",
                          &ip, &address, &wr) != 3) {
               PARSE_ERROR(mod, res->values);
               return;
       }
       if (pass == 2) {
               emit_trace(&trace_fault[0], (union ltt_value)(wr?LT_S2:LT_S0));
               emit_trace(&trace_fault[1], (union ltt_value)"0x%08x@%c0x%08x",
                   ip, (wr)? 'W' : 'R', (uint32_t)address);
       }
}
Beispiel #13
0
static void userspace_message_process(const char *modname, int pass,
				      double clock, int cpu, void *args)
{
	const char * str = get_arg_str(args, "message");

	if (pass == 1)
		init_trace(&trace_g, TG_PROCESS, 0.1,
			   TRACE_SYM_F_STRING, "user event");

	if (pass == 2)
		emit_trace(&trace_g, (union ltt_value)"%s", str);

}
Beispiel #14
0
static void kernel_softirq_exit_process(struct ltt_module *mod,
                                        struct parse_result *res, int pass)
{
    kernel_common(res, pass);
    if (pass == 2) {
        if (softirqstate == SOFTIRQS_RAISE)
            emit_trace(&sirq[0], (union ltt_value)SOFTIRQ_RAISING);
        else
            emit_trace(&sirq[0], (union ltt_value)SOFTIRQ_IDLE);
        if (idle_cpu_state == IDLE_RUNNING)
            emit_cpu_idle_state(res, (union ltt_value)IDLE_CPU_RUNNING);
        else
            emit_cpu_idle_state(res, (union ltt_value)IDLE_CPU_IDLE);
        softirqstate = SOFTIRQS_IDLE;
        /* stat stuff */
        /* we allow up to 0.7ms softirq */
        if (res->clock - softirqtime > 0.0007)
            TDIAG(res, "long softirq(%s) :  %fs!!!\n", softirqtask,
                    res->clock - softirqtime);
        /* end stat stuff */
    }
}
Beispiel #15
0
static void kernel_parrot_evt_stop_process(struct ltt_module *mod,
                                         struct parse_result *res, int pass)
{
    int id;

    kernel_common(res, pass);
    if (sscanf(res->values, " id = %d", &id) != 1) {
        PARSE_ERROR(mod, res->values);
        return;
    }
	if (pass == 1) {
        init_traces();
        if (id < sizeof(parrot_evt_n)/sizeof(parrot_evt_n[0]) && id >= 0)
            init_trace(&parrot_evt_n[id], TG_PROCESS, 0.0+0.1*id, TRACE_SYM_F_BITS, "kernel event %d", id);
    }

    if (pass == 2) {
        emit_trace(&parrot_evt, (union ltt_value)"%d->", id);
        if (id < sizeof(parrot_evt_n)/sizeof(parrot_evt_n[0]) && id >= 0)
                emit_trace(&parrot_evt_n[id], (union ltt_value)LT_IDLE);
    }
}
Beispiel #16
0
static void kernel_tasklet_low_entry_process(struct ltt_module *mod,
                                             struct parse_result *res, int pass)
{
    unsigned int data, func;

    kernel_common(res, pass);
    if (sscanf(res->values, " func = 0x%x, data = %u", &func, &data) != 2) {
        PARSE_ERROR(mod, res->values);
        return;
    }
    if (pass == 1) {
        atag_store(func);
    }
    if (pass == 2) {
        emit_trace(&tlow[0], (union ltt_value)LT_S0);
        emit_trace(&tlow[1], (union ltt_value)func);
        if (atag_enabled) {
            strncpy(softirqtask, atag_get(func), sizeof(softirqtask));
            softirqtask[sizeof(softirqtask)-1] = 0;
        }
    }
}
Beispiel #17
0
static void kernel_sched_schedule_process(struct ltt_module *mod,
                                          struct parse_result *res, int pass)
{
    unsigned int prev_pid, next_pid, prev_state;

    kernel_common(res, pass);
    if (sscanf(res->values, " prev_pid = %u, next_pid = %u, prev_state = %u",
               &prev_pid, &next_pid, &prev_state) != 3) {
        PARSE_ERROR(mod, res->values);
        return;
    }
    if (pass == 2) {
        struct ltt_trace *current_process;
        current_process = find_task_trace(prev_pid);
        emit_trace(current_process,(union ltt_value)PROCESS_IDLE);
        if (prev_pid == 0) {
            emit_cpu_idle_state(res, (union ltt_value)IDLE_CPU_IDLE);
            idle_cpu_state = IDLE_IDLE;
        }

        current_process = find_task_trace(next_pid);
        /* XXX this is often buggy : some process are in SYCALL mode while running
           in userspace ...
         */
		if(current_process->value.state)
        	emit_trace(current_process, current_process->value);
		else if (strcmp(res->mode, "USER_MODE") == 0)
            emit_trace(current_process, (union ltt_value)PROCESS_USER);
        else
            emit_trace(current_process, (union ltt_value)PROCESS_KERNEL);
        if (next_pid == 0) {
            emit_cpu_idle_state(res, (union ltt_value)IDLE_CPU_RUNNING);
            idle_cpu_state = IDLE_RUNNING;
        }
    }
}
Beispiel #18
0
static void kernel_sched_wakeup_new_task_process(struct ltt_module *mod,
                                          struct parse_result *res, int pass)
{
    unsigned int pid, cpu_id, state;

    kernel_common(res, pass);
    if (sscanf(res->values, " pid = %u, state = %u, cpu_id = %u",
               &pid, &state, &cpu_id) != 3) {
        PARSE_ERROR(mod, res->values);
        return;
    }
    if (pass == 2) {
        emit_trace(&sched_event, (union ltt_value)"new task %d", pid);
    }
}
Beispiel #19
0
static void kernel_send_signal_process(struct ltt_module *mod,
                                          struct parse_result *res, int pass)
{
    unsigned int pid, signal;

    kernel_common(res, pass);
    if (sscanf(res->values, " pid = %u, signal = %u",
               &pid, &signal) != 2) {
        PARSE_ERROR(mod, res->values);
        return;
    }
    if (pass == 2) {
        emit_trace(&sched_event, (union ltt_value)"%d send signal %d to pid %d",
                res->pid, signal, pid);
    }
}
Beispiel #20
0
static void userspace_event_stop_process(const char *modname, int pass,
					 double clock, int cpu, void *args)
{
	int num = (int)get_arg_i64(args, "event_stop");

	if (pass == 1) {
		if (num < (int)(sizeof(traces)/sizeof(traces[0])) && num >= 0)
			init_trace(&traces[num], TG_PROCESS, 0.1+0.1*num,
				   TRACE_SYM_F_BITS, "user event %d", num);
	}

	if (pass == 2) {
		if (num < (int)(sizeof(traces)/sizeof(traces[0])) && num >= 0) {
			emit_trace(&traces[num], (union ltt_value)LT_IDLE);
		}
	}
}
Beispiel #21
0
static void kernel_process_free_process(struct ltt_module *mod,
                                             struct parse_result *res, int pass)
{
    int pid;

    kernel_common(res, pass);
    if (sscanf(res->values, " pid = %d",
               &pid) != 1) {
        PARSE_ERROR(mod, res->values);
        return;
    }

    if (pass == 2) {
        struct ltt_trace *current_process;
        current_process = find_task_trace(pid);
        emit_trace(current_process, (union ltt_value)PROCESS_DEAD);
    }
}
Beispiel #22
0
static void ardupilot_end_process(const char *modname, int pass,
					 double clock, int cpu, void *args)
{
	const char *name = get_arg_str(args, "name_field");
	struct perf_apm *perf = find_or_add_perf(name);

	if (pass == 1) {
		init_trace(&perf->trace,
		   TG_APM,
		   1 + 0.1 * perf->pos,
		   TRACE_SYM_F_BITS,
		   "%s",
		   name);
	}

	if (pass == 2) {
		emit_trace(&perf->trace, (union ltt_value)LT_IDLE);
	}
}
Beispiel #23
0
static void kernel_timer_update_time_process(struct ltt_module *mod,
                                             struct parse_result *res, int pass)
{
    unsigned int c_jiffies;
    unsigned long long c_jiffies64;

    kernel_common(res, pass);
    if (sscanf(res->values, " jiffies = %llu",
               &c_jiffies64) != 1) {
        PARSE_ERROR(mod, res->values);
        return;
    }
    c_jiffies = c_jiffies64 & 0xffffffff;

    if (pass == 2) {
		static unsigned int old_jiffies;
		static double jiffies_clock;
		static double jiffies_diff;

		if (old_jiffies && old_jiffies+1 != c_jiffies)
			TDIAG(res, "missing jiffies jump from %x to %x (broken trace ?)\n",
				   old_jiffies, c_jiffies);
		if (jiffies_clock > 0) {
			double diff = res->clock - jiffies_clock;
			if (jiffies_diff > 0) {
				/* we allow a jitter of 0,1 ms */
				if (diff > jiffies_diff + 0.0001 ||
						diff < jiffies_diff - 0.0001) {
					TDIAG(res, "unstable jiffies for %x took %fs (instead of %fs)\n", old_jiffies, diff, jiffies_diff);
				}
			}
			else {
				jiffies_diff = diff;
				TDIAG(res, "set jiffies times to %fs\n", jiffies_diff);
			}

		}
		jiffies_clock = res->clock;

		old_jiffies = c_jiffies;
        emit_trace(&jiffies, (union ltt_value)c_jiffies);
    }
}
Beispiel #24
0
static void kernel_printk_process(struct ltt_module *mod,
                                             struct parse_result *res, int pass)
{
    unsigned int ip;

    kernel_common(res, pass);
    if (sscanf(res->values, " ip = 0x%x",
               &ip) != 1) {
        PARSE_ERROR(mod, res->values);
        return;
    }

    if (pass == 1) {
        atag_store(ip);
    }

    if (pass == 2) {
        emit_trace(&printk_pc, (union ltt_value)ip);
    }
}
Beispiel #25
0
static double emit_cpu_idle_state(struct parse_result *res, union ltt_value val)
{
    static double run_start;
    static double total_run;
    double ret;
    if (val.state) {
        emit_trace(&idle_cpu, val);

        //printf("clock %f %s start %f  total %f\n", res->clock, val.state, run_start, total_run);
		/* if running account the time */
        if (strcmp(val.state, IRQ_RUNNING) == 0) {
			/* if already started, do nothing */
            if (run_start == 0)
                run_start = res->clock;
        }
		/* if stoping record the idle time */
        else {
			/* if already stop, do nothing */
            if (run_start > 0) {
                total_run += res->clock - run_start;
                run_start = 0;
            }
        }
        //printf("%s start %f  total %f\n", val.state, run_start, total_run);
        ret = total_run;
    }
	/* give the total idle time and reset counter */
    else {
        /* idle is running */
        if (run_start > 0) {
            total_run += res->clock - run_start;
            run_start = res->clock;
        }
        ret = total_run;
        /* reset counter */
        total_run = 0;
        //printf("total clock : %f ret : %f\n", res->clock, ret);
    }
    return ret;
}
Beispiel #26
0
static void task_state_process_state_process(struct ltt_module *mod,
                                             struct parse_result *res, int pass)
{
    char *s;
    uint32_t pid, parent_pid, type, mode, submode, status, tgid;

    if (sscanf(res->values, " pid = %d, parent_pid = %d, name = \"%m[^\"]\", "
               "type = %d, mode = %d, submode = %d, status = %d, tgid = %d",
               &pid, &parent_pid, &s, &type, &mode, &submode, &status,
               &tgid) != 8) {
        PARSE_ERROR(mod, res->values);
        return;
    }
	if (pass == 1) {
		find_or_add_task_trace(clean_name(s), pid, tgid)/*[0].group = 0*/;
	}
    if (pass == 2) {
        //XXX
		if (status == 1) 
        	emit_trace(find_task_trace(pid), (union ltt_value)LT_S0);
    }
	free(s);
}
Beispiel #27
0
static void kernel_irq_entry_process(struct ltt_module *mod,
                                     struct parse_result *res, int pass)
{
    int kernel_mode;
    unsigned int ip,irq;
#if defined(ARCH_2_6_3X)
	void *handler;
#endif

    kernel_common(res, pass);
#if defined(ARCH_2_6_3X)
    if (sscanf(res->values, " ip = %u, handler = %p, irq_id = %u, kernel_mode = %d",
               &ip, &handler, &irq, &kernel_mode) != 4) {
        PARSE_ERROR(mod, res->values);
        return;
    }
#else
	if (sscanf(res->values, " ip = %u, irq_id = %u, kernel_mode = %d",
               &ip, &irq, &kernel_mode) != 3) {
        PARSE_ERROR(mod, res->values);
        return;
    }
#endif

    if (irq >= MAX_IRQS) {
        DIAG("invalid IRQ vector ? (%d)\n", irq);
        return;
    }

    if (pass == 1 && irq_tag[irq]) {
        init_trace(&trace[irq], TG_IRQ, 1.0+irq, TRACE_SYM_F_BITS, irq_tag[irq]);
        atag_store(ip);
    }
    if (pass == 2) {
        if (!irq_tag[irq]) {
            char name[20];
            snprintf(name, sizeof(name), "irq %d", irq);
            init_trace(&trace[irq], TG_IRQ, 1.0+irq, TRACE_SYM_F_BITS, strdup(name));
        }
        if (irqlevel >= MAX_IRQS) {
            DIAG("IRQ nesting level is too high (%d)\n", irqlevel);
            return;
        }
        if (irqlevel > 0 && irq == irqtab[irqlevel-1]) {
            DIAG("IRQ reentering in same irq (broken trace ?) %d\n", irqlevel);
            return;
        }

        if (irqlevel > 0) {
            TDIAG(res, "nesting irq %s -> %s\n", irq_tag[irqtab[irqlevel-1]],
                    irq_tag[irq]);
            emit_trace(&trace[irqtab[irqlevel-1]], (union ltt_value)IRQ_PREEMPT);
        }
        emit_trace(&trace[irq], (union ltt_value)IRQ_RUNNING);
        emit_trace(&irq_pc, (union ltt_value)ip);
        irqtab[irqlevel++] = irq;

        if (irqlevel == 1)
            emit_cpu_idle_state(res, (union ltt_value)IDLE_CPU_PREEMPT);
        /* stat stuff */
#ifndef ARCH_2_6_3X
        if (irq == 19) {
			static double timer3clock;
			static double timer3diff;
            if (timer3clock > 0) {
                double diff = res->clock - timer3clock;
                if (timer3diff > 0) {
                    /* we allow a jitter of 0,1 ms */
                    if (diff > timer3diff + 0.0001) {
                        TDIAG(res, "late irq !!! system timer took %fs (instead of %fs)\n", diff, timer3diff);
                    }
                }
                else
                    timer3diff = diff;
            }

            timer3clock = res->clock;
        }
#endif
        /* only account on the first irq */
        if (irqlevel == 1)
            irqtime = res->clock;
        /* end stat stuff */
    }
}