Setting tag linux-2.6-22-50
[linux-2.6.git] / linux-2.6-630-sched-fix.patch
1 diff -Nurp linux-2.6.22-620/fs/proc/proc_misc.c linux-2.6.22-630/fs/proc/proc_misc.c
2 --- linux-2.6.22-620/fs/proc/proc_misc.c        2008-06-25 14:49:41.000000000 -0400
3 +++ linux-2.6.22-630/fs/proc/proc_misc.c        2008-07-08 16:12:39.000000000 -0400
4 @@ -779,6 +779,34 @@ static const struct file_operations proc
5  };
6  #endif
7  
8 +extern char debug_630_dumped[4087];
9 +static int show_debug_630(struct seq_file *p, void *v)
10 +{
11 +       seq_printf(p, "%s\n", debug_630_dumped);
12 +       return 0;
13 +}
14 +
15 +static int debug_630_open(struct inode *inode, struct file *filp)
16 +{
17 +       int res;
18 +       struct seq_file *m;
19 +
20 +       res = single_open(filp, show_debug_630, NULL);
21 +       if (!res) {
22 +               m = filp->private_data;
23 +               m->buf = kmalloc(4096, GFP_KERNEL);
24 +               m->size = 4096;
25 +       }
26 +       return res;
27 +}
28 +
29 +static const struct file_operations proc_debug_630_operations = {
30 +       .open = debug_630_open,
31 +       .read = seq_read,
32 +       .llseek = seq_lseek,
33 +       .release = single_release,
34 +};
35 +
36  struct proc_dir_entry *proc_root_kcore;
37  
38  void create_seq_entry(char *name, mode_t mode, const struct file_operations *f)
39 @@ -871,4 +899,6 @@ void __init proc_misc_init(void)
40                         entry->proc_fops = &proc_sysrq_trigger_operations;
41         }
42  #endif
43 +
44 +       create_seq_entry("debug_630", 0, &proc_debug_630_operations);
45  }
46 diff -Nurp linux-2.6.22-620/kernel/sched.c linux-2.6.22-630/kernel/sched.c
47 --- linux-2.6.22-620/kernel/sched.c     2008-06-25 14:49:41.000000000 -0400
48 +++ linux-2.6.22-630/kernel/sched.c     2008-07-07 16:29:49.000000000 -0400
49 @@ -3635,6 +3635,12 @@ struct event_spec {
50  };
51  #endif
52  
53 +/* Bypass the vx_unhold infinite loop */
54 +unsigned int merry;
55 +char debug_630_dumped[4087] = { [0] = '\0' };
56 +EXPORT_SYMBOL(merry);
57 +EXPORT_SYMBOL(debug_630_dumped);
58 +
59  asmlinkage void __sched schedule(void)
60  {
61         struct task_struct *prev, *next;
62 @@ -3722,14 +3728,43 @@ need_resched_nonpreemptible:
63  
64         cpu = smp_processor_id();
65         vx_set_rq_time(rq, jiffies);
66 +
67 +       merry=0;
68  try_unhold:
69         vx_try_unhold(rq, cpu);
70  pick_next:
71  
72         if (unlikely(!rq->nr_running)) {
73                 /* can we skip idle time? */
74 -               if (vx_try_skip(rq, cpu))
75 +               if (vx_try_skip(rq, cpu) && merry<10) {
76 +                       merry++;
77                         goto try_unhold;
78 +               }
79 +               else if (merry==10 && !*debug_630_dumped) {
80 +                       char *ptr = debug_630_dumped;
81 +#define append(...)    ptr += snprintf(ptr, ((debug_630_dumped + sizeof(debug_630_dumped)) - ptr), __VA_ARGS__)
82 +
83 +                       if (list_empty(&rq->hold_queue))
84 +                               append("hold queue is empty\n");
85 +                       else {
86 +                               struct list_head *l, *n;
87 +                               append("rq->norm_time = %lu, rq->idle_time = %lu, rq->idle_skip = %d\n",
88 +                                       rq->norm_time, rq->idle_time, rq->idle_skip);
89 +                               list_for_each_safe(l, n, &rq->hold_queue) {
90 +                                       struct task_struct *p;
91 +                                       struct _vx_sched_pc *sched_pc;
92 +                                       struct vx_info *vxi;
93 +
94 +                                       p = list_entry(l, struct task_struct, run_list);
95 +                                       vxi = p->vx_info;
96 +                                       sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
97 +
98 +                                       append("%u: sched_pc->norm_time = %lu, sched_pc->idle_time = %lu\n", vxi->vx_id,
99 +                                               sched_pc->norm_time, sched_pc->idle_time);
100 +                               }
101 +                       }
102 +                       *ptr = '\0';
103 +               }
104  
105                 idle_balance(cpu, rq);
106                 if (!rq->nr_running) {