--- zzzz-none-000/linux-2.6.19.2/kernel/sched.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5505/linux-2.6.19.2/kernel/sched.c 2007-11-28 17:24:14.000000000 +0000 @@ -52,7 +52,9 @@ #include #include #include +#include #include +#include #include @@ -422,6 +424,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) @@ -632,6 +636,7 @@ unsigned long delta_jiffies = jiffies - t->sched_info.last_arrival; t->sched_info.cpu_time += delta_jiffies; + t->sched_info.cpu_last_hist += delta_jiffies; rq_sched_info_depart(task_rq(t), delta_jiffies); } @@ -3037,6 +3042,13 @@ cpustat->steal = cputime64_add(cpustat->steal, tmp); } +#ifdef CONFIG_SCHEDSTATS +static void zero_task_statistics(struct task_struct * 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. @@ -3050,7 +3062,24 @@ struct task_struct *p = current; int cpu = smp_processor_id(); struct rq *rq = cpu_rq(cpu); +#ifdef CONFIG_SCHEDSTATS + if (history_time_elapsed == 0) { + history_time_elapsed = jiffies; + } else { + if (jiffies - history_time_elapsed > (20 * HZ)) { + struct task_struct *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; @@ -4012,7 +4041,8 @@ if (nice > 19) nice = 19; - if (increment < 0 && !can_nice(current, nice)) + if (increment < 0 && (!can_nice(current, nice) || + gr_handle_chroot_nice())) return -EPERM; retval = security_task_setnice(current, nice); @@ -4802,12 +4832,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) +{ + struct task_struct *g, *p; + struct rq *rq; + rq = this_rq(); + __printk(KERN_CRIT "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(KERN_CRIT "%-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) (task_pt_regs(tsk)->regs[31]) +void show_process_eip(unsigned char* name) { + struct task_struct *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(KERN_CRIT "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) { struct task_struct *g, *p; + printk("\nCurrent sched_clock()=%llu\n", sched_clock()); #if (BITS_PER_LONG == 32) printk("\n" " sibling\n");