lockd: Add helper to sanity check incoming NOTIFY requests
[safe/jmp/linux-2.6] / kernel / sched_stats.h
index c20a94d..8385d43 100644 (file)
@@ -9,6 +9,11 @@
 static int show_schedstat(struct seq_file *seq, void *v)
 {
        int cpu;
+       int mask_len = NR_CPUS/32 * 9;
+       char *mask_str = kmalloc(mask_len, GFP_KERNEL);
+
+       if (mask_str == NULL)
+               return -ENOMEM;
 
        seq_printf(seq, "version %d\n", SCHEDSTAT_VERSION);
        seq_printf(seq, "timestamp %lu\n", jiffies);
@@ -16,18 +21,18 @@ static int show_schedstat(struct seq_file *seq, void *v)
                struct rq *rq = cpu_rq(cpu);
 #ifdef CONFIG_SMP
                struct sched_domain *sd;
-               int dcnt = 0;
+               int dcount = 0;
 #endif
 
                /* runqueue-specific stats */
                seq_printf(seq,
-                   "cpu%d %lu %lu %lu %lu %lu %lu %lu %lu %lu %llu %llu %lu",
+                   "cpu%d %u %u %u %u %u %u %u %u %u %llu %llu %lu",
                    cpu, rq->yld_both_empty,
-                   rq->yld_act_empty, rq->yld_exp_empty, rq->yld_cnt,
-                   rq->sched_switch, rq->sched_cnt, rq->sched_goidle,
-                   rq->ttwu_cnt, rq->ttwu_local,
+                   rq->yld_act_empty, rq->yld_exp_empty, rq->yld_count,
+                   rq->sched_switch, rq->sched_count, rq->sched_goidle,
+                   rq->ttwu_count, rq->ttwu_local,
                    rq->rq_sched_info.cpu_time,
-                   rq->rq_sched_info.run_delay, rq->rq_sched_info.pcnt);
+                   rq->rq_sched_info.run_delay, rq->rq_sched_info.pcount);
 
                seq_printf(seq, "\n");
 
@@ -36,15 +41,13 @@ static int show_schedstat(struct seq_file *seq, void *v)
                preempt_disable();
                for_each_domain(cpu, sd) {
                        enum cpu_idle_type itype;
-                       char mask_str[NR_CPUS];
 
-                       cpumask_scnprintf(mask_str, NR_CPUS, sd->span);
-                       seq_printf(seq, "domain%d %s", dcnt++, mask_str);
+                       cpumask_scnprintf(mask_str, mask_len, sd->span);
+                       seq_printf(seq, "domain%d %s", dcount++, mask_str);
                        for (itype = CPU_IDLE; itype < CPU_MAX_IDLE_TYPES;
                                        itype++) {
-                               seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu "
-                                               "%lu",
-                                   sd->lb_cnt[itype],
+                               seq_printf(seq, " %u %u %u %u %u %u %u %u",
+                                   sd->lb_count[itype],
                                    sd->lb_balanced[itype],
                                    sd->lb_failed[itype],
                                    sd->lb_imbalance[itype],
@@ -53,17 +56,18 @@ static int show_schedstat(struct seq_file *seq, void *v)
                                    sd->lb_nobusyq[itype],
                                    sd->lb_nobusyg[itype]);
                        }
-                       seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu %lu"
-                           " %lu %lu %lu\n",
-                           sd->alb_cnt, sd->alb_failed, sd->alb_pushed,
-                           sd->sbe_cnt, sd->sbe_balanced, sd->sbe_pushed,
-                           sd->sbf_cnt, sd->sbf_balanced, sd->sbf_pushed,
+                       seq_printf(seq,
+                                  " %u %u %u %u %u %u %u %u %u %u %u %u\n",
+                           sd->alb_count, sd->alb_failed, sd->alb_pushed,
+                           sd->sbe_count, sd->sbe_balanced, sd->sbe_pushed,
+                           sd->sbf_count, sd->sbf_balanced, sd->sbf_pushed,
                            sd->ttwu_wake_remote, sd->ttwu_move_affine,
                            sd->ttwu_move_balance);
                }
                preempt_enable();
 #endif
        }
+       kfree(mask_str);
        return 0;
 }
 
@@ -101,7 +105,7 @@ rq_sched_info_arrive(struct rq *rq, unsigned long long delta)
 {
        if (rq) {
                rq->rq_sched_info.run_delay += delta;
-               rq->rq_sched_info.pcnt++;
+               rq->rq_sched_info.pcount++;
        }
 }
 
@@ -114,6 +118,13 @@ rq_sched_info_depart(struct rq *rq, unsigned long long delta)
        if (rq)
                rq->rq_sched_info.cpu_time += delta;
 }
+
+static inline void
+rq_sched_info_dequeued(struct rq *rq, unsigned long long delta)
+{
+       if (rq)
+               rq->rq_sched_info.run_delay += delta;
+}
 # define schedstat_inc(rq, field)      do { (rq)->field++; } while (0)
 # define schedstat_add(rq, field, amt) do { (rq)->field += (amt); } while (0)
 # define schedstat_set(var, val)       do { var = (val); } while (0)
@@ -122,6 +133,9 @@ static inline void
 rq_sched_info_arrive(struct rq *rq, unsigned long long delta)
 {}
 static inline void
+rq_sched_info_dequeued(struct rq *rq, unsigned long long delta)
+{}
+static inline void
 rq_sched_info_depart(struct rq *rq, unsigned long long delta)
 {}
 # define schedstat_inc(rq, field)      do { } while (0)
@@ -130,6 +144,11 @@ rq_sched_info_depart(struct rq *rq, unsigned long long delta)
 #endif
 
 #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
+static inline void sched_info_reset_dequeued(struct task_struct *t)
+{
+       t->sched_info.last_queued = 0;
+}
+
 /*
  * Called when a process is dequeued from the active array and given
  * the cpu.  We should note that with the exception of interactive
@@ -139,15 +158,22 @@ rq_sched_info_depart(struct rq *rq, unsigned long long delta)
  * active queue, thus delaying tasks in the expired queue from running;
  * see scheduler_tick()).
  *
- * This function is only called from sched_info_arrive(), rather than
- * dequeue_task(). Even though a task may be queued and dequeued multiple
- * times as it is shuffled about, we're really interested in knowing how
- * long it was from the *first* time it was queued to the time that it
- * finally hit a cpu.
+ * Though we are interested in knowing how long it was from the *first* time a
+ * task was queued to the time that it finally hit a cpu, we call this routine
+ * from dequeue_task() to account for possible rq->clock skew across cpus. The
+ * delta taken on each cpu would annul the skew.
  */
 static inline void sched_info_dequeued(struct task_struct *t)
 {
-       t->sched_info.last_queued = 0;
+       unsigned long long now = task_rq(t)->clock, delta = 0;
+
+       if (unlikely(sched_info_on()))
+               if (t->sched_info.last_queued)
+                       delta = now - t->sched_info.last_queued;
+       sched_info_reset_dequeued(t);
+       t->sched_info.run_delay += delta;
+
+       rq_sched_info_dequeued(task_rq(t), delta);
 }
 
 /*
@@ -157,14 +183,14 @@ static inline void sched_info_dequeued(struct task_struct *t)
  */
 static void sched_info_arrive(struct task_struct *t)
 {
-       unsigned long long now = sched_clock(), delta = 0;
+       unsigned long long now = task_rq(t)->clock, delta = 0;
 
        if (t->sched_info.last_queued)
                delta = now - t->sched_info.last_queued;
-       sched_info_dequeued(t);
+       sched_info_reset_dequeued(t);
        t->sched_info.run_delay += delta;
        t->sched_info.last_arrival = now;
-       t->sched_info.pcnt++;
+       t->sched_info.pcount++;
 
        rq_sched_info_arrive(task_rq(t), delta);
 }
@@ -188,19 +214,26 @@ static inline void sched_info_queued(struct task_struct *t)
 {
        if (unlikely(sched_info_on()))
                if (!t->sched_info.last_queued)
-                       t->sched_info.last_queued = sched_clock();
+                       t->sched_info.last_queued = task_rq(t)->clock;
 }
 
 /*
  * Called when a process ceases being the active-running process, either
  * voluntarily or involuntarily.  Now we can calculate how long we ran.
+ * Also, if the process is still in the TASK_RUNNING state, call
+ * sched_info_queued() to mark that it has now again started waiting on
+ * the runqueue.
  */
 static inline void sched_info_depart(struct task_struct *t)
 {
-       unsigned long long delta = sched_clock() - t->sched_info.last_arrival;
+       unsigned long long delta = task_rq(t)->clock -
+                                       t->sched_info.last_arrival;
 
        t->sched_info.cpu_time += delta;
        rq_sched_info_depart(task_rq(t), delta);
+
+       if (t->state == TASK_RUNNING)
+               sched_info_queued(t);
 }
 
 /*
@@ -231,7 +264,9 @@ sched_info_switch(struct task_struct *prev, struct task_struct *next)
                __sched_info_switch(prev, next);
 }
 #else
-#define sched_info_queued(t)           do { } while (0)
-#define sched_info_switch(t, next)     do { } while (0)
+#define sched_info_queued(t)                   do { } while (0)
+#define sched_info_reset_dequeued(t)   do { } while (0)
+#define sched_info_dequeued(t)                 do { } while (0)
+#define sched_info_switch(t, next)             do { } while (0)
 #endif /* CONFIG_SCHEDSTATS || CONFIG_TASK_DELAY_ACCT */