--- zzzz-none-000/linux-2.6.13.1/kernel/sched.c 2005-09-10 02:42:58.000000000 +0000 +++ ohio-7170-487/linux-2.6.13.1/kernel/sched.c 2007-09-05 14:27:28.000000000 +0000 @@ -18,6 +18,7 @@ * 2004-04-02 Scheduler domains code by Nick Piggin */ +#include #include #include #include @@ -369,6 +370,8 @@ } #ifdef CONFIG_SCHEDSTATS +static volatile unsigned long history_time_elapsed = 0; + /* * bump this up when changing the output format or the meaning of an existing * format, so that tools can adapt (or abort) @@ -557,6 +560,7 @@ unsigned long diff = jiffies - t->sched_info.last_arrival; t->sched_info.cpu_time += diff; + t->sched_info.cpu_last_hist += diff; if (rq) rq->rq_sched_info.cpu_time += diff; @@ -2474,6 +2478,13 @@ cpustat->steal = cputime64_add(cpustat->steal, tmp); } +#ifdef CONFIG_SCHEDSTATS +static void zero_task_statistics(task_t * p) { + /*--- memset(&p->sched_info, 0, sizeof(p->sched_info)); ---*/ + p->sched_info.cpu_last_hist = 0; +} +#endif + /* * This function gets called by the timer code, with HZ frequency. * We call it with interrupts disabled. @@ -2487,7 +2498,24 @@ runqueue_t *rq = this_rq(); task_t *p = current; unsigned long long now = sched_clock(); +#ifdef CONFIG_SCHEDSTATS + if (history_time_elapsed == 0) { + history_time_elapsed = jiffies; + } else { + if (jiffies - history_time_elapsed > (20 * HZ)) { + task_t *g, *p; + read_lock(&tasklist_lock); + do_each_thread(g, p) { + zero_task_statistics(p); + } while_each_thread(g, p); + + read_unlock(&tasklist_lock); + history_time_elapsed = jiffies; + } + } +#endif + update_cpu_clock(p, rq, now); rq->timestamp_last_tick = now; @@ -4147,12 +4175,53 @@ if (state != TASK_RUNNING) show_stack(p, NULL); + + printk(" activated: %llu, last_ran: %llu, sched_time: %llu\n", p->timestamp, p->last_ran, p->sched_time); } +#ifdef CONFIG_SCHEDSTATS +void show_sched_stats(void) +{ + task_t *g, *p; + runqueue_t *rq; + rq = this_rq(); + printk("task statistics for the last %lu jiffies (now: %lu), current is: %s\n", jiffies - history_time_elapsed, jiffies, current->comm); + do_each_thread(g, p) { + char whichqueue = '?'; + + /* + * reset the NMI-timeout, listing all files on a slow + * console might take alot of time: + */ + touch_nmi_watchdog(); + if (p->array == rq->active) { whichqueue = 'A'; } + if (p->array == rq->expired) { whichqueue = 'E'; } + printk("%-13.13s last_queued: %10lu (%10luj ago) to %c, last_arrival: %10lu (%10luj ago), cpu_time: %5lu j (%10lu total)\n", p->comm, p->sched_info.last_queued, jiffies - p->sched_info.last_queued, whichqueue, p->sched_info.last_arrival, jiffies - p->sched_info.last_arrival, p->sched_info.cpu_last_hist, p->sched_info.cpu_time); + } while_each_thread(g, p); +} +EXPORT_SYMBOL(show_sched_stats); + +#define KSTK_RA(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(regs[31]))) +void show_process_eip(unsigned char* name) { + task_t *g, *p; + do_each_thread(g, p) { + if (strcmp(p->comm, name) == 0) { + unsigned long esp = 0, eip = 0, ra; + eip = KSTK_EIP(p); + esp = KSTK_ESP(p); + ra = KSTK_RA(p); + __printk("process %s has ip %lx, sp %lx, ra %lx\n", name, eip, esp, ra); + } + } while_each_thread(g, p); +} +EXPORT_SYMBOL(show_process_eip); +#endif + void show_state(void) { task_t *g, *p; + printk("\nCurrent sched_clock()=%llu\n", sched_clock()); #if (BITS_PER_LONG == 32) printk("\n" " sibling\n");