diff options
| -rw-r--r-- | Documentation/feature-removal-schedule.txt | 15 | ||||
| -rw-r--r-- | Documentation/filesystems/proc.txt | 3 | ||||
| -rw-r--r-- | Documentation/kernel-parameters.txt | 2 | ||||
| -rw-r--r-- | fs/proc/array.c | 23 | ||||
| -rw-r--r-- | fs/proc/stat.c | 19 | ||||
| -rw-r--r-- | include/linux/jiffies.h | 1 | ||||
| -rw-r--r-- | include/linux/kernel_stat.h | 1 | ||||
| -rw-r--r-- | include/linux/preempt.h | 5 | ||||
| -rw-r--r-- | include/linux/sched.h | 22 | ||||
| -rw-r--r-- | kernel/cpuset.c | 27 | ||||
| -rw-r--r-- | kernel/exit.c | 22 | ||||
| -rw-r--r-- | kernel/fork.c | 5 | ||||
| -rw-r--r-- | kernel/kgdb.c | 2 | ||||
| -rw-r--r-- | kernel/sched.c | 270 | ||||
| -rw-r--r-- | kernel/sched_debug.c | 4 | ||||
| -rw-r--r-- | kernel/sched_fair.c | 65 | ||||
| -rw-r--r-- | kernel/sched_rt.c | 61 | ||||
| -rw-r--r-- | kernel/sys.c | 21 | ||||
| -rw-r--r-- | kernel/time.c | 30 |
19 files changed, 397 insertions, 201 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index bc693fffabe0..f613df8ec7bf 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
| @@ -6,6 +6,21 @@ be removed from this file. | |||
| 6 | 6 | ||
| 7 | --------------------------- | 7 | --------------------------- |
| 8 | 8 | ||
| 9 | What: USER_SCHED | ||
| 10 | When: 2.6.34 | ||
| 11 | |||
| 12 | Why: USER_SCHED was implemented as a proof of concept for group scheduling. | ||
| 13 | The effect of USER_SCHED can already be achieved from userspace with | ||
| 14 | the help of libcgroup. The removal of USER_SCHED will also simplify | ||
| 15 | the scheduler code with the removal of one major ifdef. There are also | ||
| 16 | issues USER_SCHED has with USER_NS. A decision was taken not to fix | ||
| 17 | those and instead remove USER_SCHED. Also new group scheduling | ||
| 18 | features will not be implemented for USER_SCHED. | ||
| 19 | |||
| 20 | Who: Dhaval Giani <dhaval@linux.vnet.ibm.com> | ||
| 21 | |||
| 22 | --------------------------- | ||
| 23 | |||
| 9 | What: PRISM54 | 24 | What: PRISM54 |
| 10 | When: 2.6.34 | 25 | When: 2.6.34 |
| 11 | 26 | ||
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 2c48f945546b..4af0018533f2 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt | |||
| @@ -1072,7 +1072,8 @@ second). The meanings of the columns are as follows, from left to right: | |||
| 1072 | - irq: servicing interrupts | 1072 | - irq: servicing interrupts |
| 1073 | - softirq: servicing softirqs | 1073 | - softirq: servicing softirqs |
| 1074 | - steal: involuntary wait | 1074 | - steal: involuntary wait |
| 1075 | - guest: running a guest | 1075 | - guest: running a normal guest |
| 1076 | - guest_nice: running a niced guest | ||
| 1076 | 1077 | ||
| 1077 | The "intr" line gives counts of interrupts serviced since boot time, for each | 1078 | The "intr" line gives counts of interrupts serviced since boot time, for each |
| 1078 | of the possible system interrupts. The first column is the total of all | 1079 | of the possible system interrupts. The first column is the total of all |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 51138b3dc8cc..5820eb0cd7e7 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -2186,6 +2186,8 @@ and is between 256 and 4096 characters. It is defined in the file | |||
| 2186 | 2186 | ||
| 2187 | sbni= [NET] Granch SBNI12 leased line adapter | 2187 | sbni= [NET] Granch SBNI12 leased line adapter |
| 2188 | 2188 | ||
| 2189 | sched_debug [KNL] Enables verbose scheduler debug messages. | ||
| 2190 | |||
| 2189 | sc1200wdt= [HW,WDT] SC1200 WDT (watchdog) driver | 2191 | sc1200wdt= [HW,WDT] SC1200 WDT (watchdog) driver |
| 2190 | Format: <io>[,<timeout>[,<isapnp>]] | 2192 | Format: <io>[,<timeout>[,<isapnp>]] |
| 2191 | 2193 | ||
diff --git a/fs/proc/array.c b/fs/proc/array.c index 822c2d506518..4badde179b18 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
| @@ -410,6 +410,16 @@ static void task_show_stack_usage(struct seq_file *m, struct task_struct *task) | |||
| 410 | } | 410 | } |
| 411 | #endif /* CONFIG_MMU */ | 411 | #endif /* CONFIG_MMU */ |
| 412 | 412 | ||
| 413 | static void task_cpus_allowed(struct seq_file *m, struct task_struct *task) | ||
| 414 | { | ||
| 415 | seq_printf(m, "Cpus_allowed:\t"); | ||
| 416 | seq_cpumask(m, &task->cpus_allowed); | ||
| 417 | seq_printf(m, "\n"); | ||
| 418 | seq_printf(m, "Cpus_allowed_list:\t"); | ||
| 419 | seq_cpumask_list(m, &task->cpus_allowed); | ||
| 420 | seq_printf(m, "\n"); | ||
| 421 | } | ||
| 422 | |||
| 413 | int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, | 423 | int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, |
| 414 | struct pid *pid, struct task_struct *task) | 424 | struct pid *pid, struct task_struct *task) |
| 415 | { | 425 | { |
| @@ -424,6 +434,7 @@ int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, | |||
| 424 | } | 434 | } |
| 425 | task_sig(m, task); | 435 | task_sig(m, task); |
| 426 | task_cap(m, task); | 436 | task_cap(m, task); |
| 437 | task_cpus_allowed(m, task); | ||
| 427 | cpuset_task_status_allowed(m, task); | 438 | cpuset_task_status_allowed(m, task); |
| 428 | #if defined(CONFIG_S390) | 439 | #if defined(CONFIG_S390) |
| 429 | task_show_regs(m, task); | 440 | task_show_regs(m, task); |
| @@ -495,20 +506,17 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, | |||
| 495 | 506 | ||
| 496 | /* add up live thread stats at the group level */ | 507 | /* add up live thread stats at the group level */ |
| 497 | if (whole) { | 508 | if (whole) { |
| 498 | struct task_cputime cputime; | ||
| 499 | struct task_struct *t = task; | 509 | struct task_struct *t = task; |
| 500 | do { | 510 | do { |
| 501 | min_flt += t->min_flt; | 511 | min_flt += t->min_flt; |
| 502 | maj_flt += t->maj_flt; | 512 | maj_flt += t->maj_flt; |
| 503 | gtime = cputime_add(gtime, task_gtime(t)); | 513 | gtime = cputime_add(gtime, t->gtime); |
| 504 | t = next_thread(t); | 514 | t = next_thread(t); |
| 505 | } while (t != task); | 515 | } while (t != task); |
| 506 | 516 | ||
| 507 | min_flt += sig->min_flt; | 517 | min_flt += sig->min_flt; |
| 508 | maj_flt += sig->maj_flt; | 518 | maj_flt += sig->maj_flt; |
| 509 | thread_group_cputime(task, &cputime); | 519 | thread_group_times(task, &utime, &stime); |
| 510 | utime = cputime.utime; | ||
| 511 | stime = cputime.stime; | ||
| 512 | gtime = cputime_add(gtime, sig->gtime); | 520 | gtime = cputime_add(gtime, sig->gtime); |
| 513 | } | 521 | } |
| 514 | 522 | ||
| @@ -524,9 +532,8 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, | |||
| 524 | if (!whole) { | 532 | if (!whole) { |
| 525 | min_flt = task->min_flt; | 533 | min_flt = task->min_flt; |
| 526 | maj_flt = task->maj_flt; | 534 | maj_flt = task->maj_flt; |
| 527 | utime = task_utime(task); | 535 | task_times(task, &utime, &stime); |
| 528 | stime = task_stime(task); | 536 | gtime = task->gtime; |
| 529 | gtime = task_gtime(task); | ||
| 530 | } | 537 | } |
| 531 | 538 | ||
| 532 | /* scale priority and nice values from timeslices to -20..20 */ | 539 | /* scale priority and nice values from timeslices to -20..20 */ |
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index 7cc726c6d70a..b9b7aad2003d 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c | |||
| @@ -27,7 +27,7 @@ static int show_stat(struct seq_file *p, void *v) | |||
| 27 | int i, j; | 27 | int i, j; |
| 28 | unsigned long jif; | 28 | unsigned long jif; |
| 29 | cputime64_t user, nice, system, idle, iowait, irq, softirq, steal; | 29 | cputime64_t user, nice, system, idle, iowait, irq, softirq, steal; |
| 30 | cputime64_t guest; | 30 | cputime64_t guest, guest_nice; |
| 31 | u64 sum = 0; | 31 | u64 sum = 0; |
| 32 | u64 sum_softirq = 0; | 32 | u64 sum_softirq = 0; |
| 33 | unsigned int per_softirq_sums[NR_SOFTIRQS] = {0}; | 33 | unsigned int per_softirq_sums[NR_SOFTIRQS] = {0}; |
| @@ -36,7 +36,7 @@ static int show_stat(struct seq_file *p, void *v) | |||
| 36 | 36 | ||
| 37 | user = nice = system = idle = iowait = | 37 | user = nice = system = idle = iowait = |
| 38 | irq = softirq = steal = cputime64_zero; | 38 | irq = softirq = steal = cputime64_zero; |
| 39 | guest = cputime64_zero; | 39 | guest = guest_nice = cputime64_zero; |
| 40 | getboottime(&boottime); | 40 | getboottime(&boottime); |
| 41 | jif = boottime.tv_sec; | 41 | jif = boottime.tv_sec; |
| 42 | 42 | ||
| @@ -51,6 +51,8 @@ static int show_stat(struct seq_file *p, void *v) | |||
| 51 | softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq); | 51 | softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq); |
| 52 | steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal); | 52 | steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal); |
| 53 | guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest); | 53 | guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest); |
| 54 | guest_nice = cputime64_add(guest_nice, | ||
| 55 | kstat_cpu(i).cpustat.guest_nice); | ||
| 54 | for_each_irq_nr(j) { | 56 | for_each_irq_nr(j) { |
| 55 | sum += kstat_irqs_cpu(j, i); | 57 | sum += kstat_irqs_cpu(j, i); |
| 56 | } | 58 | } |
| @@ -65,7 +67,8 @@ static int show_stat(struct seq_file *p, void *v) | |||
| 65 | } | 67 | } |
| 66 | sum += arch_irq_stat(); | 68 | sum += arch_irq_stat(); |
| 67 | 69 | ||
| 68 | seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n", | 70 | seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu " |
| 71 | "%llu\n", | ||
| 69 | (unsigned long long)cputime64_to_clock_t(user), | 72 | (unsigned long long)cputime64_to_clock_t(user), |
| 70 | (unsigned long long)cputime64_to_clock_t(nice), | 73 | (unsigned long long)cputime64_to_clock_t(nice), |
| 71 | (unsigned long long)cputime64_to_clock_t(system), | 74 | (unsigned long long)cputime64_to_clock_t(system), |
| @@ -74,7 +77,8 @@ static int show_stat(struct seq_file *p, void *v) | |||
| 74 | (unsigned long long)cputime64_to_clock_t(irq), | 77 | (unsigned long long)cputime64_to_clock_t(irq), |
| 75 | (unsigned long long)cputime64_to_clock_t(softirq), | 78 | (unsigned long long)cputime64_to_clock_t(softirq), |
| 76 | (unsigned long long)cputime64_to_clock_t(steal), | 79 | (unsigned long long)cputime64_to_clock_t(steal), |
| 77 | (unsigned long long)cputime64_to_clock_t(guest)); | 80 | (unsigned long long)cputime64_to_clock_t(guest), |
| 81 | (unsigned long long)cputime64_to_clock_t(guest_nice)); | ||
| 78 | for_each_online_cpu(i) { | 82 | for_each_online_cpu(i) { |
| 79 | 83 | ||
| 80 | /* Copy values here to work around gcc-2.95.3, gcc-2.96 */ | 84 | /* Copy values here to work around gcc-2.95.3, gcc-2.96 */ |
| @@ -88,8 +92,10 @@ static int show_stat(struct seq_file *p, void *v) | |||
| 88 | softirq = kstat_cpu(i).cpustat.softirq; | 92 | softirq = kstat_cpu(i).cpustat.softirq; |
| 89 | steal = kstat_cpu(i).cpustat.steal; | 93 | steal = kstat_cpu(i).cpustat.steal; |
| 90 | guest = kstat_cpu(i).cpustat.guest; | 94 | guest = kstat_cpu(i).cpustat.guest; |
| 95 | guest_nice = kstat_cpu(i).cpustat.guest_nice; | ||
| 91 | seq_printf(p, | 96 | seq_printf(p, |
| 92 | "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu\n", | 97 | "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu " |
| 98 | "%llu\n", | ||
| 93 | i, | 99 | i, |
| 94 | (unsigned long long)cputime64_to_clock_t(user), | 100 | (unsigned long long)cputime64_to_clock_t(user), |
| 95 | (unsigned long long)cputime64_to_clock_t(nice), | 101 | (unsigned long long)cputime64_to_clock_t(nice), |
| @@ -99,7 +105,8 @@ static int show_stat(struct seq_file *p, void *v) | |||
| 99 | (unsigned long long)cputime64_to_clock_t(irq), | 105 | (unsigned long long)cputime64_to_clock_t(irq), |
| 100 | (unsigned long long)cputime64_to_clock_t(softirq), | 106 | (unsigned long long)cputime64_to_clock_t(softirq), |
| 101 | (unsigned long long)cputime64_to_clock_t(steal), | 107 | (unsigned long long)cputime64_to_clock_t(steal), |
| 102 | (unsigned long long)cputime64_to_clock_t(guest)); | 108 | (unsigned long long)cputime64_to_clock_t(guest), |
| 109 | (unsigned long long)cputime64_to_clock_t(guest_nice)); | ||
| 103 | } | 110 | } |
| 104 | seq_printf(p, "intr %llu", (unsigned long long)sum); | 111 | seq_printf(p, "intr %llu", (unsigned long long)sum); |
| 105 | 112 | ||
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h index 1a9cf78bfce5..6811f4bfc6e7 100644 --- a/include/linux/jiffies.h +++ b/include/linux/jiffies.h | |||
| @@ -307,6 +307,7 @@ extern clock_t jiffies_to_clock_t(long x); | |||
| 307 | extern unsigned long clock_t_to_jiffies(unsigned long x); | 307 | extern unsigned long clock_t_to_jiffies(unsigned long x); |
| 308 | extern u64 jiffies_64_to_clock_t(u64 x); | 308 | extern u64 jiffies_64_to_clock_t(u64 x); |
| 309 | extern u64 nsec_to_clock_t(u64 x); | 309 | extern u64 nsec_to_clock_t(u64 x); |
| 310 | extern unsigned long nsecs_to_jiffies(u64 n); | ||
| 310 | 311 | ||
| 311 | #define TIMESTAMP_SIZE 30 | 312 | #define TIMESTAMP_SIZE 30 |
| 312 | 313 | ||
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 348fa8874b52..c059044bc6dc 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h | |||
| @@ -25,6 +25,7 @@ struct cpu_usage_stat { | |||
| 25 | cputime64_t iowait; | 25 | cputime64_t iowait; |
| 26 | cputime64_t steal; | 26 | cputime64_t steal; |
| 27 | cputime64_t guest; | 27 | cputime64_t guest; |
| 28 | cputime64_t guest_nice; | ||
| 28 | }; | 29 | }; |
| 29 | 30 | ||
| 30 | struct kernel_stat { | 31 | struct kernel_stat { |
diff --git a/include/linux/preempt.h b/include/linux/preempt.h index 72b1a10a59b6..2e681d9555bd 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h | |||
| @@ -105,6 +105,11 @@ struct preempt_notifier; | |||
| 105 | * @sched_out: we've just been preempted | 105 | * @sched_out: we've just been preempted |
| 106 | * notifier: struct preempt_notifier for the task being preempted | 106 | * notifier: struct preempt_notifier for the task being preempted |
| 107 | * next: the task that's kicking us out | 107 | * next: the task that's kicking us out |
| 108 | * | ||
| 109 | * Please note that sched_in and out are called under different | ||
| 110 | * contexts. sched_out is called with rq lock held and irq disabled | ||
| 111 | * while sched_in is called without rq lock and irq enabled. This | ||
| 112 | * difference is intentional and depended upon by its users. | ||
| 108 | */ | 113 | */ |
| 109 | struct preempt_ops { | 114 | struct preempt_ops { |
| 110 | void (*sched_in)(struct preempt_notifier *notifier, int cpu); | 115 | void (*sched_in)(struct preempt_notifier *notifier, int cpu); |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 882dc48163b4..89115ec7d43f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
| @@ -145,7 +145,6 @@ extern unsigned long this_cpu_load(void); | |||
| 145 | 145 | ||
| 146 | 146 | ||
| 147 | extern void calc_global_load(void); | 147 | extern void calc_global_load(void); |
| 148 | extern u64 cpu_nr_migrations(int cpu); | ||
| 149 | 148 | ||
| 150 | extern unsigned long get_parent_ip(unsigned long addr); | 149 | extern unsigned long get_parent_ip(unsigned long addr); |
| 151 | 150 | ||
| @@ -171,8 +170,6 @@ print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) | |||
| 171 | } | 170 | } |
| 172 | #endif | 171 | #endif |
| 173 | 172 | ||
| 174 | extern unsigned long long time_sync_thresh; | ||
| 175 | |||
| 176 | /* | 173 | /* |
| 177 | * Task state bitmask. NOTE! These bits are also | 174 | * Task state bitmask. NOTE! These bits are also |
| 178 | * encoded in fs/proc/array.c: get_task_state(). | 175 | * encoded in fs/proc/array.c: get_task_state(). |
| @@ -349,7 +346,6 @@ extern signed long schedule_timeout(signed long timeout); | |||
| 349 | extern signed long schedule_timeout_interruptible(signed long timeout); | 346 | extern signed long schedule_timeout_interruptible(signed long timeout); |
| 350 | extern signed long schedule_timeout_killable(signed long timeout); | 347 | extern signed long schedule_timeout_killable(signed long timeout); |
| 351 | extern signed long schedule_timeout_uninterruptible(signed long timeout); | 348 | extern signed long schedule_timeout_uninterruptible(signed long timeout); |
| 352 | asmlinkage void __schedule(void); | ||
| 353 | asmlinkage void schedule(void); | 349 | asmlinkage void schedule(void); |
| 354 | extern int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner); | 350 | extern int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner); |
| 355 | 351 | ||
| @@ -628,6 +624,9 @@ struct signal_struct { | |||
| 628 | cputime_t utime, stime, cutime, cstime; | 624 | cputime_t utime, stime, cutime, cstime; |
| 629 | cputime_t gtime; | 625 | cputime_t gtime; |
| 630 | cputime_t cgtime; | 626 | cputime_t cgtime; |
| 627 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | ||
| 628 | cputime_t prev_utime, prev_stime; | ||
| 629 | #endif | ||
| 631 | unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; | 630 | unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; |
| 632 | unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt; | 631 | unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt; |
| 633 | unsigned long inblock, oublock, cinblock, coublock; | 632 | unsigned long inblock, oublock, cinblock, coublock; |
| @@ -1013,9 +1012,13 @@ static inline struct cpumask *sched_domain_span(struct sched_domain *sd) | |||
| 1013 | return to_cpumask(sd->span); | 1012 | return to_cpumask(sd->span); |
| 1014 | } | 1013 | } |
| 1015 | 1014 | ||
| 1016 | extern void partition_sched_domains(int ndoms_new, struct cpumask *doms_new, | 1015 | extern void partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[], |
| 1017 | struct sched_domain_attr *dattr_new); | 1016 | struct sched_domain_attr *dattr_new); |
| 1018 | 1017 | ||
| 1018 | /* Allocate an array of sched domains, for partition_sched_domains(). */ | ||
| 1019 | cpumask_var_t *alloc_sched_domains(unsigned int ndoms); | ||
| 1020 | void free_sched_domains(cpumask_var_t doms[], unsigned int ndoms); | ||
| 1021 | |||
| 1019 | /* Test a flag in parent sched domain */ | 1022 | /* Test a flag in parent sched domain */ |
| 1020 | static inline int test_sd_parent(struct sched_domain *sd, int flag) | 1023 | static inline int test_sd_parent(struct sched_domain *sd, int flag) |
| 1021 | { | 1024 | { |
| @@ -1033,7 +1036,7 @@ unsigned long default_scale_smt_power(struct sched_domain *sd, int cpu); | |||
| 1033 | struct sched_domain_attr; | 1036 | struct sched_domain_attr; |
| 1034 | 1037 | ||
| 1035 | static inline void | 1038 | static inline void |
| 1036 | partition_sched_domains(int ndoms_new, struct cpumask *doms_new, | 1039 | partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[], |
| 1037 | struct sched_domain_attr *dattr_new) | 1040 | struct sched_domain_attr *dattr_new) |
| 1038 | { | 1041 | { |
| 1039 | } | 1042 | } |
| @@ -1331,7 +1334,9 @@ struct task_struct { | |||
| 1331 | 1334 | ||
| 1332 | cputime_t utime, stime, utimescaled, stimescaled; | 1335 | cputime_t utime, stime, utimescaled, stimescaled; |
| 1333 | cputime_t gtime; | 1336 | cputime_t gtime; |
| 1337 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | ||
| 1334 | cputime_t prev_utime, prev_stime; | 1338 | cputime_t prev_utime, prev_stime; |
| 1339 | #endif | ||
| 1335 | unsigned long nvcsw, nivcsw; /* context switch counts */ | 1340 | unsigned long nvcsw, nivcsw; /* context switch counts */ |
| 1336 | struct timespec start_time; /* monotonic time */ | 1341 | struct timespec start_time; /* monotonic time */ |
| 1337 | struct timespec real_start_time; /* boot based time */ | 1342 | struct timespec real_start_time; /* boot based time */ |
| @@ -1720,9 +1725,8 @@ static inline void put_task_struct(struct task_struct *t) | |||
| 1720 | __put_task_struct(t); | 1725 | __put_task_struct(t); |
| 1721 | } | 1726 | } |
| 1722 | 1727 | ||
| 1723 | extern cputime_t task_utime(struct task_struct *p); | 1728 | extern void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st); |
| 1724 | extern cputime_t task_stime(struct task_struct *p); | 1729 | extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st); |
| 1725 | extern cputime_t task_gtime(struct task_struct *p); | ||
| 1726 | 1730 | ||
| 1727 | /* | 1731 | /* |
| 1728 | * Per process flags | 1732 | * Per process flags |
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index b5cb469d2545..3cf2183b472d 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
| @@ -537,8 +537,7 @@ update_domain_attr_tree(struct sched_domain_attr *dattr, struct cpuset *c) | |||
| 537 | * element of the partition (one sched domain) to be passed to | 537 | * element of the partition (one sched domain) to be passed to |
| 538 | * partition_sched_domains(). | 538 | * partition_sched_domains(). |
| 539 | */ | 539 | */ |
| 540 | /* FIXME: see the FIXME in partition_sched_domains() */ | 540 | static int generate_sched_domains(cpumask_var_t **domains, |
| 541 | static int generate_sched_domains(struct cpumask **domains, | ||
| 542 | struct sched_domain_attr **attributes) | 541 | struct sched_domain_attr **attributes) |
| 543 | { | 542 | { |
| 544 | LIST_HEAD(q); /* queue of cpusets to be scanned */ | 543 | LIST_HEAD(q); /* queue of cpusets to be scanned */ |
| @@ -546,7 +545,7 @@ static int generate_sched_domains(struct cpumask **domains, | |||
| 546 | struct cpuset **csa; /* array of all cpuset ptrs */ | 545 | struct cpuset **csa; /* array of all cpuset ptrs */ |
| 547 | int csn; /* how many cpuset ptrs in csa so far */ | 546 | int csn; /* how many cpuset ptrs in csa so far */ |
| 548 | int i, j, k; /* indices for partition finding loops */ | 547 | int i, j, k; /* indices for partition finding loops */ |
| 549 | struct cpumask *doms; /* resulting partition; i.e. sched domains */ | 548 | cpumask_var_t *doms; /* resulting partition; i.e. sched domains */ |
| 550 | struct sched_domain_attr *dattr; /* attributes for custom domains */ | 549 | struct sched_domain_attr *dattr; /* attributes for custom domains */ |
| 551 | int ndoms = 0; /* number of sched domains in result */ | 550 | int ndoms = 0; /* number of sched domains in result */ |
| 552 | int nslot; /* next empty doms[] struct cpumask slot */ | 551 | int nslot; /* next empty doms[] struct cpumask slot */ |
| @@ -557,7 +556,8 @@ static int generate_sched_domains(struct cpumask **domains, | |||
| 557 | 556 | ||
| 558 | /* Special case for the 99% of systems with one, full, sched domain */ | 557 | /* Special case for the 99% of systems with one, full, sched domain */ |
| 559 | if (is_sched_load_balance(&top_cpuset)) { | 558 | if (is_sched_load_balance(&top_cpuset)) { |
| 560 | doms = kmalloc(cpumask_size(), GFP_KERNEL); | 559 | ndoms = 1; |
| 560 | doms = alloc_sched_domains(ndoms); | ||
| 561 | if (!doms) | 561 | if (!doms) |
| 562 | goto done; | 562 | goto done; |
| 563 | 563 | ||
| @@ -566,9 +566,8 @@ static int generate_sched_domains(struct cpumask **domains, | |||
| 566 | *dattr = SD_ATTR_INIT; | 566 | *dattr = SD_ATTR_INIT; |
| 567 | update_domain_attr_tree(dattr, &top_cpuset); | 567 | update_domain_attr_tree(dattr, &top_cpuset); |
| 568 | } | 568 | } |
| 569 | cpumask_copy(doms, top_cpuset.cpus_allowed); | 569 | cpumask_copy(doms[0], top_cpuset.cpus_allowed); |
| 570 | 570 | ||
| 571 | ndoms = 1; | ||
| 572 | goto done; | 571 | goto done; |
| 573 | } | 572 | } |
| 574 | 573 | ||
| @@ -636,7 +635,7 @@ restart: | |||
| 636 | * Now we know how many domains to create. | 635 | * Now we know how many domains to create. |
| 637 | * Convert <csn, csa> to <ndoms, doms> and populate cpu masks. | 636 | * Convert <csn, csa> to <ndoms, doms> and populate cpu masks. |
| 638 | */ | 637 | */ |
| 639 | doms = kmalloc(ndoms * cpumask_size(), GFP_KERNEL); | 638 | doms = alloc_sched_domains(ndoms); |
| 640 | if (!doms) | 639 | if (!doms) |
| 641 | goto done; | 640 | goto done; |
| 642 | 641 | ||
| @@ -656,7 +655,7 @@ restart: | |||
| 656 | continue; | 655 | continue; |
| 657 | } | 656 | } |
| 658 | 657 | ||
| 659 | dp = doms + nslot; | 658 | dp = doms[nslot]; |
| 660 | 659 | ||
| 661 | if (nslot == ndoms) { | 660 | if (nslot == ndoms) { |
| 662 | static int warnings = 10; | 661 | static int warnings = 10; |
| @@ -718,7 +717,7 @@ done: | |||
| 718 | static void do_rebuild_sched_domains(struct work_struct *unused) | 717 | static void do_rebuild_sched_domains(struct work_struct *unused) |
| 719 | { | 718 | { |
| 720 | struct sched_domain_attr *attr; | 719 | struct sched_domain_attr *attr; |
| 721 | struct cpumask *doms; | 720 | cpumask_var_t *doms; |
| 722 | int ndoms; | 721 | int ndoms; |
| 723 | 722 | ||
| 724 | get_online_cpus(); | 723 | get_online_cpus(); |
| @@ -2052,7 +2051,7 @@ static int cpuset_track_online_cpus(struct notifier_block *unused_nb, | |||
| 2052 | unsigned long phase, void *unused_cpu) | 2051 | unsigned long phase, void *unused_cpu) |
| 2053 | { | 2052 | { |
| 2054 | struct sched_domain_attr *attr; | 2053 | struct sched_domain_attr *attr; |
| 2055 | struct cpumask *doms; | 2054 | cpumask_var_t *doms; |
| 2056 | int ndoms; | 2055 | int ndoms; |
| 2057 | 2056 | ||
| 2058 | switch (phase) { | 2057 | switch (phase) { |
| @@ -2537,15 +2536,9 @@ const struct file_operations proc_cpuset_operations = { | |||
| 2537 | }; | 2536 | }; |
| 2538 | #endif /* CONFIG_PROC_PID_CPUSET */ | 2537 | #endif /* CONFIG_PROC_PID_CPUSET */ |
| 2539 | 2538 | ||
| 2540 | /* Display task cpus_allowed, mems_allowed in /proc/<pid>/status file. */ | 2539 | /* Display task mems_allowed in /proc/<pid>/status file. */ |
| 2541 | void cpuset_task_status_allowed(struct seq_file *m, struct task_struct *task) | 2540 | void cpuset_task_status_allowed(struct seq_file *m, struct task_struct *task) |
| 2542 | { | 2541 | { |
| 2543 | seq_printf(m, "Cpus_allowed:\t"); | ||
| 2544 | seq_cpumask(m, &task->cpus_allowed); | ||
| 2545 | seq_printf(m, "\n"); | ||
| 2546 | seq_printf(m, "Cpus_allowed_list:\t"); | ||
| 2547 | seq_cpumask_list(m, &task->cpus_allowed); | ||
| 2548 | seq_printf(m, "\n"); | ||
| 2549 | seq_printf(m, "Mems_allowed:\t"); | 2542 | seq_printf(m, "Mems_allowed:\t"); |
| 2550 | seq_nodemask(m, &task->mems_allowed); | 2543 | seq_nodemask(m, &task->mems_allowed); |
| 2551 | seq_printf(m, "\n"); | 2544 | seq_printf(m, "\n"); |
diff --git a/kernel/exit.c b/kernel/exit.c index 3f45e3cf931d..80ae941cfd2e 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -111,9 +111,9 @@ static void __exit_signal(struct task_struct *tsk) | |||
| 111 | * We won't ever get here for the group leader, since it | 111 | * We won't ever get here for the group leader, since it |
| 112 | * will have been the last reference on the signal_struct. | 112 | * will have been the last reference on the signal_struct. |
| 113 | */ | 113 | */ |
| 114 | sig->utime = cputime_add(sig->utime, task_utime(tsk)); | 114 | sig->utime = cputime_add(sig->utime, tsk->utime); |
| 115 | sig->stime = cputime_add(sig->stime, task_stime(tsk)); | 115 | sig->stime = cputime_add(sig->stime, tsk->stime); |
| 116 | sig->gtime = cputime_add(sig->gtime, task_gtime(tsk)); | 116 | sig->gtime = cputime_add(sig->gtime, tsk->gtime); |
| 117 | sig->min_flt += tsk->min_flt; | 117 | sig->min_flt += tsk->min_flt; |
| 118 | sig->maj_flt += tsk->maj_flt; | 118 | sig->maj_flt += tsk->maj_flt; |
| 119 | sig->nvcsw += tsk->nvcsw; | 119 | sig->nvcsw += tsk->nvcsw; |
| @@ -1210,6 +1210,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) | |||
| 1210 | struct signal_struct *psig; | 1210 | struct signal_struct *psig; |
| 1211 | struct signal_struct *sig; | 1211 | struct signal_struct *sig; |
| 1212 | unsigned long maxrss; | 1212 | unsigned long maxrss; |
| 1213 | cputime_t tgutime, tgstime; | ||
| 1213 | 1214 | ||
| 1214 | /* | 1215 | /* |
| 1215 | * The resource counters for the group leader are in its | 1216 | * The resource counters for the group leader are in its |
| @@ -1225,20 +1226,23 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) | |||
| 1225 | * need to protect the access to parent->signal fields, | 1226 | * need to protect the access to parent->signal fields, |
| 1226 | * as other threads in the parent group can be right | 1227 | * as other threads in the parent group can be right |
| 1227 | * here reaping other children at the same time. | 1228 | * here reaping other children at the same time. |
| 1229 | * | ||
| 1230 | * We use thread_group_times() to get times for the thread | ||
| 1231 | * group, which consolidates times for all threads in the | ||
| 1232 | * group including the group leader. | ||
| 1228 | */ | 1233 | */ |
| 1234 | thread_group_times(p, &tgutime, &tgstime); | ||
| 1229 | spin_lock_irq(&p->real_parent->sighand->siglock); | 1235 | spin_lock_irq(&p->real_parent->sighand->siglock); |
| 1230 | psig = p->real_parent->signal; | 1236 | psig = p->real_parent->signal; |
| 1231 | sig = p->signal; | 1237 | sig = p->signal; |
| 1232 | psig->cutime = | 1238 | psig->cutime = |
| 1233 | cputime_add(psig->cutime, | 1239 | cputime_add(psig->cutime, |
| 1234 | cputime_add(p->utime, | 1240 | cputime_add(tgutime, |
| 1235 | cputime_add(sig->utime, | 1241 | sig->cutime)); |
| 1236 | sig->cutime))); | ||
| 1237 | psig->cstime = | 1242 | psig->cstime = |
| 1238 | cputime_add(psig->cstime, | 1243 | cputime_add(psig->cstime, |
| 1239 | cputime_add(p->stime, | 1244 | cputime_add(tgstime, |
| 1240 | cputime_add(sig->stime, | 1245 | sig->cstime)); |
| 1241 | sig->cstime))); | ||
| 1242 | psig->cgtime = | 1246 | psig->cgtime = |
| 1243 | cputime_add(psig->cgtime, | 1247 | cputime_add(psig->cgtime, |
| 1244 | cputime_add(p->gtime, | 1248 | cputime_add(p->gtime, |
diff --git a/kernel/fork.c b/kernel/fork.c index 166b8c49257c..3d6f121bbe8a 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -884,6 +884,9 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
| 884 | sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; | 884 | sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; |
| 885 | sig->gtime = cputime_zero; | 885 | sig->gtime = cputime_zero; |
| 886 | sig->cgtime = cputime_zero; | 886 | sig->cgtime = cputime_zero; |
| 887 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | ||
| 888 | sig->prev_utime = sig->prev_stime = cputime_zero; | ||
| 889 | #endif | ||
| 887 | sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; | 890 | sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; |
| 888 | sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; | 891 | sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; |
| 889 | sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; | 892 | sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; |
| @@ -1066,8 +1069,10 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1066 | p->gtime = cputime_zero; | 1069 | p->gtime = cputime_zero; |
| 1067 | p->utimescaled = cputime_zero; | 1070 | p->utimescaled = cputime_zero; |
| 1068 | p->stimescaled = cputime_zero; | 1071 | p->stimescaled = cputime_zero; |
| 1072 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | ||
| 1069 | p->prev_utime = cputime_zero; | 1073 | p->prev_utime = cputime_zero; |
| 1070 | p->prev_stime = cputime_zero; | 1074 | p->prev_stime = cputime_zero; |
| 1075 | #endif | ||
| 1071 | 1076 | ||
| 1072 | p->default_timer_slack_ns = current->timer_slack_ns; | 1077 | p->default_timer_slack_ns = current->timer_slack_ns; |
| 1073 | 1078 | ||
diff --git a/kernel/kgdb.c b/kernel/kgdb.c index 9147a3190c9d..7d7014634022 100644 --- a/kernel/kgdb.c +++ b/kernel/kgdb.c | |||
| @@ -870,7 +870,7 @@ static void gdb_cmd_getregs(struct kgdb_state *ks) | |||
| 870 | 870 | ||
| 871 | /* | 871 | /* |
| 872 | * All threads that don't have debuggerinfo should be | 872 | * All threads that don't have debuggerinfo should be |
| 873 | * in __schedule() sleeping, since all other CPUs | 873 | * in schedule() sleeping, since all other CPUs |
| 874 | * are in kgdb_wait, and thus have debuggerinfo. | 874 | * are in kgdb_wait, and thus have debuggerinfo. |
| 875 | */ | 875 | */ |
| 876 | if (local_debuggerinfo) { | 876 | if (local_debuggerinfo) { |
diff --git a/kernel/sched.c b/kernel/sched.c index 6ae2739b8f19..aa31244caa9f 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -535,14 +535,12 @@ struct rq { | |||
| 535 | #define CPU_LOAD_IDX_MAX 5 | 535 | #define CPU_LOAD_IDX_MAX 5 |
| 536 | unsigned long cpu_load[CPU_LOAD_IDX_MAX]; | 536 | unsigned long cpu_load[CPU_LOAD_IDX_MAX]; |
| 537 | #ifdef CONFIG_NO_HZ | 537 | #ifdef CONFIG_NO_HZ |
| 538 | unsigned long last_tick_seen; | ||
| 539 | unsigned char in_nohz_recently; | 538 | unsigned char in_nohz_recently; |
| 540 | #endif | 539 | #endif |
| 541 | /* capture load from *all* tasks on this cpu: */ | 540 | /* capture load from *all* tasks on this cpu: */ |
| 542 | struct load_weight load; | 541 | struct load_weight load; |
| 543 | unsigned long nr_load_updates; | 542 | unsigned long nr_load_updates; |
| 544 | u64 nr_switches; | 543 | u64 nr_switches; |
| 545 | u64 nr_migrations_in; | ||
| 546 | 544 | ||
| 547 | struct cfs_rq cfs; | 545 | struct cfs_rq cfs; |
| 548 | struct rt_rq rt; | 546 | struct rt_rq rt; |
| @@ -591,6 +589,8 @@ struct rq { | |||
| 591 | 589 | ||
| 592 | u64 rt_avg; | 590 | u64 rt_avg; |
| 593 | u64 age_stamp; | 591 | u64 age_stamp; |
| 592 | u64 idle_stamp; | ||
| 593 | u64 avg_idle; | ||
| 594 | #endif | 594 | #endif |
| 595 | 595 | ||
| 596 | /* calc_load related fields */ | 596 | /* calc_load related fields */ |
| @@ -772,7 +772,7 @@ sched_feat_write(struct file *filp, const char __user *ubuf, | |||
| 772 | if (!sched_feat_names[i]) | 772 | if (!sched_feat_names[i]) |
| 773 | return -EINVAL; | 773 | return -EINVAL; |
| 774 | 774 | ||
| 775 | filp->f_pos += cnt; | 775 | *ppos += cnt; |
| 776 | 776 | ||
| 777 | return cnt; | 777 | return cnt; |
| 778 | } | 778 | } |
| @@ -2017,6 +2017,7 @@ void kthread_bind(struct task_struct *p, unsigned int cpu) | |||
| 2017 | } | 2017 | } |
| 2018 | 2018 | ||
| 2019 | spin_lock_irqsave(&rq->lock, flags); | 2019 | spin_lock_irqsave(&rq->lock, flags); |
| 2020 | update_rq_clock(rq); | ||
| 2020 | set_task_cpu(p, cpu); | 2021 | set_task_cpu(p, cpu); |
| 2021 | p->cpus_allowed = cpumask_of_cpu(cpu); | 2022 | p->cpus_allowed = cpumask_of_cpu(cpu); |
| 2022 | p->rt.nr_cpus_allowed = 1; | 2023 | p->rt.nr_cpus_allowed = 1; |
| @@ -2078,7 +2079,6 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) | |||
| 2078 | #endif | 2079 | #endif |
| 2079 | if (old_cpu != new_cpu) { | 2080 | if (old_cpu != new_cpu) { |
| 2080 | p->se.nr_migrations++; | 2081 | p->se.nr_migrations++; |
| 2081 | new_rq->nr_migrations_in++; | ||
| 2082 | #ifdef CONFIG_SCHEDSTATS | 2082 | #ifdef CONFIG_SCHEDSTATS |
| 2083 | if (task_hot(p, old_rq->clock, NULL)) | 2083 | if (task_hot(p, old_rq->clock, NULL)) |
| 2084 | schedstat_inc(p, se.nr_forced2_migrations); | 2084 | schedstat_inc(p, se.nr_forced2_migrations); |
| @@ -2115,6 +2115,7 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req) | |||
| 2115 | * it is sufficient to simply update the task's cpu field. | 2115 | * it is sufficient to simply update the task's cpu field. |
| 2116 | */ | 2116 | */ |
| 2117 | if (!p->se.on_rq && !task_running(rq, p)) { | 2117 | if (!p->se.on_rq && !task_running(rq, p)) { |
| 2118 | update_rq_clock(rq); | ||
| 2118 | set_task_cpu(p, dest_cpu); | 2119 | set_task_cpu(p, dest_cpu); |
| 2119 | return 0; | 2120 | return 0; |
| 2120 | } | 2121 | } |
| @@ -2376,14 +2377,15 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, | |||
| 2376 | task_rq_unlock(rq, &flags); | 2377 | task_rq_unlock(rq, &flags); |
| 2377 | 2378 | ||
| 2378 | cpu = p->sched_class->select_task_rq(p, SD_BALANCE_WAKE, wake_flags); | 2379 | cpu = p->sched_class->select_task_rq(p, SD_BALANCE_WAKE, wake_flags); |
| 2379 | if (cpu != orig_cpu) | 2380 | if (cpu != orig_cpu) { |
| 2381 | local_irq_save(flags); | ||
| 2382 | rq = cpu_rq(cpu); | ||
| 2383 | update_rq_clock(rq); | ||
| 2380 | set_task_cpu(p, cpu); | 2384 | set_task_cpu(p, cpu); |
| 2381 | 2385 | local_irq_restore(flags); | |
| 2386 | } | ||
| 2382 | rq = task_rq_lock(p, &flags); | 2387 | rq = task_rq_lock(p, &flags); |
| 2383 | 2388 | ||
| 2384 | if (rq != orig_rq) | ||
| 2385 | update_rq_clock(rq); | ||
| 2386 | |||
| 2387 | WARN_ON(p->state != TASK_WAKING); | 2389 | WARN_ON(p->state != TASK_WAKING); |
| 2388 | cpu = task_cpu(p); | 2390 | cpu = task_cpu(p); |
| 2389 | 2391 | ||
| @@ -2440,6 +2442,17 @@ out_running: | |||
| 2440 | #ifdef CONFIG_SMP | 2442 | #ifdef CONFIG_SMP |
| 2441 | if (p->sched_class->task_wake_up) | 2443 | if (p->sched_class->task_wake_up) |
| 2442 | p->sched_class->task_wake_up(rq, p); | 2444 | p->sched_class->task_wake_up(rq, p); |
| 2445 | |||
| 2446 | if (unlikely(rq->idle_stamp)) { | ||
| 2447 | u64 delta = rq->clock - rq->idle_stamp; | ||
| 2448 | u64 max = 2*sysctl_sched_migration_cost; | ||
| 2449 | |||
| 2450 | if (delta > max) | ||
| 2451 | rq->avg_idle = max; | ||
| 2452 | else | ||
| 2453 | update_avg(&rq->avg_idle, delta); | ||
| 2454 | rq->idle_stamp = 0; | ||
| 2455 | } | ||
| 2443 | #endif | 2456 | #endif |
| 2444 | out: | 2457 | out: |
| 2445 | task_rq_unlock(rq, &flags); | 2458 | task_rq_unlock(rq, &flags); |
| @@ -2545,6 +2558,7 @@ static void __sched_fork(struct task_struct *p) | |||
| 2545 | void sched_fork(struct task_struct *p, int clone_flags) | 2558 | void sched_fork(struct task_struct *p, int clone_flags) |
| 2546 | { | 2559 | { |
| 2547 | int cpu = get_cpu(); | 2560 | int cpu = get_cpu(); |
| 2561 | unsigned long flags; | ||
| 2548 | 2562 | ||
| 2549 | __sched_fork(p); | 2563 | __sched_fork(p); |
| 2550 | 2564 | ||
| @@ -2581,7 +2595,10 @@ void sched_fork(struct task_struct *p, int clone_flags) | |||
| 2581 | #ifdef CONFIG_SMP | 2595 | #ifdef CONFIG_SMP |
| 2582 | cpu = p->sched_class->select_task_rq(p, SD_BALANCE_FORK, 0); | 2596 | cpu = p->sched_class->select_task_rq(p, SD_BALANCE_FORK, 0); |
| 2583 | #endif | 2597 | #endif |
| 2598 | local_irq_save(flags); | ||
| 2599 | update_rq_clock(cpu_rq(cpu)); | ||
| 2584 | set_task_cpu(p, cpu); | 2600 | set_task_cpu(p, cpu); |
| 2601 | local_irq_restore(flags); | ||
| 2585 | 2602 | ||
| 2586 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) | 2603 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) |
| 2587 | if (likely(sched_info_on())) | 2604 | if (likely(sched_info_on())) |
| @@ -2848,14 +2865,14 @@ context_switch(struct rq *rq, struct task_struct *prev, | |||
| 2848 | */ | 2865 | */ |
| 2849 | arch_start_context_switch(prev); | 2866 | arch_start_context_switch(prev); |
| 2850 | 2867 | ||
| 2851 | if (unlikely(!mm)) { | 2868 | if (likely(!mm)) { |
| 2852 | next->active_mm = oldmm; | 2869 | next->active_mm = oldmm; |
| 2853 | atomic_inc(&oldmm->mm_count); | 2870 | atomic_inc(&oldmm->mm_count); |
| 2854 | enter_lazy_tlb(oldmm, next); | 2871 | enter_lazy_tlb(oldmm, next); |
| 2855 | } else | 2872 | } else |
| 2856 | switch_mm(oldmm, mm, next); | 2873 | switch_mm(oldmm, mm, next); |
| 2857 | 2874 | ||
| 2858 | if (unlikely(!prev->mm)) { | 2875 | if (likely(!prev->mm)) { |
| 2859 | prev->active_mm = NULL; | 2876 | prev->active_mm = NULL; |
| 2860 | rq->prev_mm = oldmm; | 2877 | rq->prev_mm = oldmm; |
| 2861 | } | 2878 | } |
| @@ -3018,15 +3035,6 @@ static void calc_load_account_active(struct rq *this_rq) | |||
| 3018 | } | 3035 | } |
| 3019 | 3036 | ||
| 3020 | /* | 3037 | /* |
| 3021 | * Externally visible per-cpu scheduler statistics: | ||
| 3022 | * cpu_nr_migrations(cpu) - number of migrations into that cpu | ||
| 3023 | */ | ||
| 3024 | u64 cpu_nr_migrations(int cpu) | ||
| 3025 | { | ||
| 3026 | return cpu_rq(cpu)->nr_migrations_in; | ||
| 3027 | } | ||
| 3028 | |||
| 3029 | /* | ||
| 3030 | * Update rq->cpu_load[] statistics. This function is usually called every | 3038 | * Update rq->cpu_load[] statistics. This function is usually called every |
| 3031 | * scheduler tick (TICK_NSEC). | 3039 | * scheduler tick (TICK_NSEC). |
| 3032 | */ | 3040 | */ |
| @@ -4126,7 +4134,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, | |||
| 4126 | unsigned long flags; | 4134 | unsigned long flags; |
| 4127 | struct cpumask *cpus = __get_cpu_var(load_balance_tmpmask); | 4135 | struct cpumask *cpus = __get_cpu_var(load_balance_tmpmask); |
| 4128 | 4136 | ||
| 4129 | cpumask_setall(cpus); | 4137 | cpumask_copy(cpus, cpu_online_mask); |
| 4130 | 4138 | ||
| 4131 | /* | 4139 | /* |
| 4132 | * When power savings policy is enabled for the parent domain, idle | 4140 | * When power savings policy is enabled for the parent domain, idle |
| @@ -4289,7 +4297,7 @@ load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd) | |||
| 4289 | int all_pinned = 0; | 4297 | int all_pinned = 0; |
| 4290 | struct cpumask *cpus = __get_cpu_var(load_balance_tmpmask); | 4298 | struct cpumask *cpus = __get_cpu_var(load_balance_tmpmask); |
| 4291 | 4299 | ||
| 4292 | cpumask_setall(cpus); | 4300 | cpumask_copy(cpus, cpu_online_mask); |
| 4293 | 4301 | ||
| 4294 | /* | 4302 | /* |
| 4295 | * When power savings policy is enabled for the parent domain, idle | 4303 | * When power savings policy is enabled for the parent domain, idle |
| @@ -4429,6 +4437,11 @@ static void idle_balance(int this_cpu, struct rq *this_rq) | |||
| 4429 | int pulled_task = 0; | 4437 | int pulled_task = 0; |
| 4430 | unsigned long next_balance = jiffies + HZ; | 4438 | unsigned long next_balance = jiffies + HZ; |
| 4431 | 4439 | ||
| 4440 | this_rq->idle_stamp = this_rq->clock; | ||
| 4441 | |||
| 4442 | if (this_rq->avg_idle < sysctl_sched_migration_cost) | ||
| 4443 | return; | ||
| 4444 | |||
| 4432 | for_each_domain(this_cpu, sd) { | 4445 | for_each_domain(this_cpu, sd) { |
| 4433 | unsigned long interval; | 4446 | unsigned long interval; |
| 4434 | 4447 | ||
| @@ -4443,8 +4456,10 @@ static void idle_balance(int this_cpu, struct rq *this_rq) | |||
| 4443 | interval = msecs_to_jiffies(sd->balance_interval); | 4456 | interval = msecs_to_jiffies(sd->balance_interval); |
| 4444 | if (time_after(next_balance, sd->last_balance + interval)) | 4457 | if (time_after(next_balance, sd->last_balance + interval)) |
| 4445 | next_balance = sd->last_balance + interval; | 4458 | next_balance = sd->last_balance + interval; |
| 4446 | if (pulled_task) | 4459 | if (pulled_task) { |
| 4460 | this_rq->idle_stamp = 0; | ||
| 4447 | break; | 4461 | break; |
| 4462 | } | ||
| 4448 | } | 4463 | } |
| 4449 | if (pulled_task || time_after(jiffies, this_rq->next_balance)) { | 4464 | if (pulled_task || time_after(jiffies, this_rq->next_balance)) { |
| 4450 | /* | 4465 | /* |
| @@ -5046,8 +5061,13 @@ static void account_guest_time(struct task_struct *p, cputime_t cputime, | |||
| 5046 | p->gtime = cputime_add(p->gtime, cputime); | 5061 | p->gtime = cputime_add(p->gtime, cputime); |
| 5047 | 5062 | ||
| 5048 | /* Add guest time to cpustat. */ | 5063 | /* Add guest time to cpustat. */ |
| 5049 | cpustat->user = cputime64_add(cpustat->user, tmp); | 5064 | if (TASK_NICE(p) > 0) { |
| 5050 | cpustat->guest = cputime64_add(cpustat->guest, tmp); | 5065 | cpustat->nice = cputime64_add(cpustat->nice, tmp); |
| 5066 | cpustat->guest_nice = cputime64_add(cpustat->guest_nice, tmp); | ||
| 5067 | } else { | ||
| 5068 | cpustat->user = cputime64_add(cpustat->user, tmp); | ||
| 5069 | cpustat->guest = cputime64_add(cpustat->guest, tmp); | ||
| 5070 | } | ||
| 5051 | } | 5071 | } |
| 5052 | 5072 | ||
| 5053 | /* | 5073 | /* |
| @@ -5162,60 +5182,86 @@ void account_idle_ticks(unsigned long ticks) | |||
| 5162 | * Use precise platform statistics if available: | 5182 | * Use precise platform statistics if available: |
| 5163 | */ | 5183 | */ |
| 5164 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 5184 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
| 5165 | cputime_t task_utime(struct task_struct *p) | 5185 | void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st) |
| 5166 | { | 5186 | { |
| 5167 | return p->utime; | 5187 | *ut = p->utime; |
| 5188 | *st = p->stime; | ||
| 5168 | } | 5189 | } |
| 5169 | 5190 | ||
| 5170 | cputime_t task_stime(struct task_struct *p) | 5191 | void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st) |
| 5171 | { | 5192 | { |
| 5172 | return p->stime; | 5193 | struct task_cputime cputime; |
| 5194 | |||
| 5195 | thread_group_cputime(p, &cputime); | ||
| 5196 | |||
| 5197 | *ut = cputime.utime; | ||
| 5198 | *st = cputime.stime; | ||
| 5173 | } | 5199 | } |
| 5174 | #else | 5200 | #else |
| 5175 | cputime_t task_utime(struct task_struct *p) | 5201 | |
| 5202 | #ifndef nsecs_to_cputime | ||
| 5203 | # define nsecs_to_cputime(__nsecs) nsecs_to_jiffies(__nsecs) | ||
| 5204 | #endif | ||
| 5205 | |||
| 5206 | void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | ||
| 5176 | { | 5207 | { |
| 5177 | clock_t utime = cputime_to_clock_t(p->utime), | 5208 | cputime_t rtime, utime = p->utime, total = cputime_add(utime, p->stime); |
| 5178 | total = utime + cputime_to_clock_t(p->stime); | ||
| 5179 | u64 temp; | ||
| 5180 | 5209 | ||
| 5181 | /* | 5210 | /* |
| 5182 | * Use CFS's precise accounting: | 5211 | * Use CFS's precise accounting: |
| 5183 | */ | 5212 | */ |
| 5184 | temp = (u64)nsec_to_clock_t(p->se.sum_exec_runtime); | 5213 | rtime = nsecs_to_cputime(p->se.sum_exec_runtime); |
| 5185 | 5214 | ||
| 5186 | if (total) { | 5215 | if (total) { |
| 5187 | temp *= utime; | 5216 | u64 temp; |
| 5217 | |||
| 5218 | temp = (u64)(rtime * utime); | ||
| 5188 | do_div(temp, total); | 5219 | do_div(temp, total); |
| 5189 | } | 5220 | utime = (cputime_t)temp; |
| 5190 | utime = (clock_t)temp; | 5221 | } else |
| 5222 | utime = rtime; | ||
| 5223 | |||
| 5224 | /* | ||
| 5225 | * Compare with previous values, to keep monotonicity: | ||
| 5226 | */ | ||
| 5227 | p->prev_utime = max(p->prev_utime, utime); | ||
| 5228 | p->prev_stime = max(p->prev_stime, cputime_sub(rtime, p->prev_utime)); | ||
| 5191 | 5229 | ||
| 5192 | p->prev_utime = max(p->prev_utime, clock_t_to_cputime(utime)); | 5230 | *ut = p->prev_utime; |
| 5193 | return p->prev_utime; | 5231 | *st = p->prev_stime; |
| 5194 | } | 5232 | } |
| 5195 | 5233 | ||
| 5196 | cputime_t task_stime(struct task_struct *p) | 5234 | /* |
| 5235 | * Must be called with siglock held. | ||
| 5236 | */ | ||
| 5237 | void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | ||
| 5197 | { | 5238 | { |
| 5198 | clock_t stime; | 5239 | struct signal_struct *sig = p->signal; |
| 5240 | struct task_cputime cputime; | ||
| 5241 | cputime_t rtime, utime, total; | ||
| 5199 | 5242 | ||
| 5200 | /* | 5243 | thread_group_cputime(p, &cputime); |
| 5201 | * Use CFS's precise accounting. (we subtract utime from | ||
| 5202 | * the total, to make sure the total observed by userspace | ||
| 5203 | * grows monotonically - apps rely on that): | ||
| 5204 | */ | ||
| 5205 | stime = nsec_to_clock_t(p->se.sum_exec_runtime) - | ||
| 5206 | cputime_to_clock_t(task_utime(p)); | ||
| 5207 | 5244 | ||
| 5208 | if (stime >= 0) | 5245 | total = cputime_add(cputime.utime, cputime.stime); |
| 5209 | p->prev_stime = max(p->prev_stime, clock_t_to_cputime(stime)); | 5246 | rtime = nsecs_to_cputime(cputime.sum_exec_runtime); |
| 5210 | 5247 | ||
| 5211 | return p->prev_stime; | 5248 | if (total) { |
| 5212 | } | 5249 | u64 temp; |
| 5213 | #endif | ||
| 5214 | 5250 | ||
| 5215 | inline cputime_t task_gtime(struct task_struct *p) | 5251 | temp = (u64)(rtime * cputime.utime); |
| 5216 | { | 5252 | do_div(temp, total); |
| 5217 | return p->gtime; | 5253 | utime = (cputime_t)temp; |
| 5254 | } else | ||
| 5255 | utime = rtime; | ||
| 5256 | |||
| 5257 | sig->prev_utime = max(sig->prev_utime, utime); | ||
| 5258 | sig->prev_stime = max(sig->prev_stime, | ||
| 5259 | cputime_sub(rtime, sig->prev_utime)); | ||
| 5260 | |||
| 5261 | *ut = sig->prev_utime; | ||
| 5262 | *st = sig->prev_stime; | ||
| 5218 | } | 5263 | } |
| 5264 | #endif | ||
| 5219 | 5265 | ||
| 5220 | /* | 5266 | /* |
| 5221 | * This function gets called by the timer code, with HZ frequency. | 5267 | * This function gets called by the timer code, with HZ frequency. |
| @@ -6175,22 +6221,14 @@ __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio) | |||
| 6175 | BUG_ON(p->se.on_rq); | 6221 | BUG_ON(p->se.on_rq); |
| 6176 | 6222 | ||
| 6177 | p->policy = policy; | 6223 | p->policy = policy; |
| 6178 | switch (p->policy) { | ||
| 6179 | case SCHED_NORMAL: | ||
| 6180 | case SCHED_BATCH: | ||
| 6181 | case SCHED_IDLE: | ||
| 6182 | p->sched_class = &fair_sched_class; | ||
| 6183 | break; | ||
| 6184 | case SCHED_FIFO: | ||
| 6185 | case SCHED_RR: | ||
| 6186 | p->sched_class = &rt_sched_class; | ||
| 6187 | break; | ||
| 6188 | } | ||
| 6189 | |||
| 6190 | p->rt_priority = prio; | 6224 | p->rt_priority = prio; |
| 6191 | p->normal_prio = normal_prio(p); | 6225 | p->normal_prio = normal_prio(p); |
| 6192 | /* we are holding p->pi_lock already */ | 6226 | /* we are holding p->pi_lock already */ |
| 6193 | p->prio = rt_mutex_getprio(p); | 6227 | p->prio = rt_mutex_getprio(p); |
| 6228 | if (rt_prio(p->prio)) | ||
| 6229 | p->sched_class = &rt_sched_class; | ||
| 6230 | else | ||
| 6231 | p->sched_class = &fair_sched_class; | ||
| 6194 | set_load_weight(p); | 6232 | set_load_weight(p); |
| 6195 | } | 6233 | } |
| 6196 | 6234 | ||
| @@ -6935,7 +6973,7 @@ void show_state_filter(unsigned long state_filter) | |||
| 6935 | /* | 6973 | /* |
| 6936 | * Only show locks if all tasks are dumped: | 6974 | * Only show locks if all tasks are dumped: |
| 6937 | */ | 6975 | */ |
| 6938 | if (state_filter == -1) | 6976 | if (!state_filter) |
| 6939 | debug_show_all_locks(); | 6977 | debug_show_all_locks(); |
| 6940 | } | 6978 | } |
| 6941 | 6979 | ||
| @@ -7740,6 +7778,16 @@ early_initcall(migration_init); | |||
| 7740 | 7778 | ||
| 7741 | #ifdef CONFIG_SCHED_DEBUG | 7779 | #ifdef CONFIG_SCHED_DEBUG |
| 7742 | 7780 | ||
| 7781 | static __read_mostly int sched_domain_debug_enabled; | ||
| 7782 | |||
| 7783 | static int __init sched_domain_debug_setup(char *str) | ||
| 7784 | { | ||
| 7785 | sched_domain_debug_enabled = 1; | ||
| 7786 | |||
| 7787 | return 0; | ||
| 7788 | } | ||
| 7789 | early_param("sched_debug", sched_domain_debug_setup); | ||
| 7790 | |||
| 7743 | static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level, | 7791 | static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level, |
| 7744 | struct cpumask *groupmask) | 7792 | struct cpumask *groupmask) |
| 7745 | { | 7793 | { |
| @@ -7826,6 +7874,9 @@ static void sched_domain_debug(struct sched_domain *sd, int cpu) | |||
| 7826 | cpumask_var_t groupmask; | 7874 | cpumask_var_t groupmask; |
| 7827 | int level = 0; | 7875 | int level = 0; |
| 7828 | 7876 | ||
| 7877 | if (!sched_domain_debug_enabled) | ||
| 7878 | return; | ||
| 7879 | |||
| 7829 | if (!sd) { | 7880 | if (!sd) { |
| 7830 | printk(KERN_DEBUG "CPU%d attaching NULL sched-domain.\n", cpu); | 7881 | printk(KERN_DEBUG "CPU%d attaching NULL sched-domain.\n", cpu); |
| 7831 | return; | 7882 | return; |
| @@ -7905,6 +7956,8 @@ sd_parent_degenerate(struct sched_domain *sd, struct sched_domain *parent) | |||
| 7905 | 7956 | ||
| 7906 | static void free_rootdomain(struct root_domain *rd) | 7957 | static void free_rootdomain(struct root_domain *rd) |
| 7907 | { | 7958 | { |
| 7959 | synchronize_sched(); | ||
| 7960 | |||
| 7908 | cpupri_cleanup(&rd->cpupri); | 7961 | cpupri_cleanup(&rd->cpupri); |
| 7909 | 7962 | ||
| 7910 | free_cpumask_var(rd->rto_mask); | 7963 | free_cpumask_var(rd->rto_mask); |
| @@ -8045,6 +8098,7 @@ static cpumask_var_t cpu_isolated_map; | |||
| 8045 | /* Setup the mask of cpus configured for isolated domains */ | 8098 | /* Setup the mask of cpus configured for isolated domains */ |
| 8046 | static int __init isolated_cpu_setup(char *str) | 8099 | static int __init isolated_cpu_setup(char *str) |
| 8047 | { | 8100 | { |
| 8101 | alloc_bootmem_cpumask_var(&cpu_isolated_map); | ||
| 8048 | cpulist_parse(str, cpu_isolated_map); | 8102 | cpulist_parse(str, cpu_isolated_map); |
| 8049 | return 1; | 8103 | return 1; |
| 8050 | } | 8104 | } |
| @@ -8881,7 +8935,7 @@ static int build_sched_domains(const struct cpumask *cpu_map) | |||
| 8881 | return __build_sched_domains(cpu_map, NULL); | 8935 | return __build_sched_domains(cpu_map, NULL); |
| 8882 | } | 8936 | } |
| 8883 | 8937 | ||
| 8884 | static struct cpumask *doms_cur; /* current sched domains */ | 8938 | static cpumask_var_t *doms_cur; /* current sched domains */ |
| 8885 | static int ndoms_cur; /* number of sched domains in 'doms_cur' */ | 8939 | static int ndoms_cur; /* number of sched domains in 'doms_cur' */ |
| 8886 | static struct sched_domain_attr *dattr_cur; | 8940 | static struct sched_domain_attr *dattr_cur; |
| 8887 | /* attribues of custom domains in 'doms_cur' */ | 8941 | /* attribues of custom domains in 'doms_cur' */ |
| @@ -8903,6 +8957,31 @@ int __attribute__((weak)) arch_update_cpu_topology(void) | |||
| 8903 | return 0; | 8957 | return 0; |
| 8904 | } | 8958 | } |
| 8905 | 8959 | ||
| 8960 | cpumask_var_t *alloc_sched_domains(unsigned int ndoms) | ||
| 8961 | { | ||
| 8962 | int i; | ||
| 8963 | cpumask_var_t *doms; | ||
| 8964 | |||
| 8965 | doms = kmalloc(sizeof(*doms) * ndoms, GFP_KERNEL); | ||
| 8966 | if (!doms) | ||
| 8967 | return NULL; | ||
| 8968 | for (i = 0; i < ndoms; i++) { | ||
| 8969 | if (!alloc_cpumask_var(&doms[i], GFP_KERNEL)) { | ||
| 8970 | free_sched_domains(doms, i); | ||
| 8971 | return NULL; | ||
| 8972 | } | ||
| 8973 | } | ||
| 8974 | return doms; | ||
| 8975 | } | ||
| 8976 | |||
| 8977 | void free_sched_domains(cpumask_var_t doms[], unsigned int ndoms) | ||
| 8978 | { | ||
| 8979 | unsigned int i; | ||
| 8980 | for (i = 0; i < ndoms; i++) | ||
| 8981 | free_cpumask_var(doms[i]); | ||
| 8982 | kfree(doms); | ||
| 8983 | } | ||
| 8984 | |||
| 8906 | /* | 8985 | /* |
| 8907 | * Set up scheduler domains and groups. Callers must hold the hotplug lock. | 8986 | * Set up scheduler domains and groups. Callers must hold the hotplug lock. |
| 8908 | * For now this just excludes isolated cpus, but could be used to | 8987 | * For now this just excludes isolated cpus, but could be used to |
| @@ -8914,12 +8993,12 @@ static int arch_init_sched_domains(const struct cpumask *cpu_map) | |||
| 8914 | 8993 | ||
| 8915 | arch_update_cpu_topology(); | 8994 | arch_update_cpu_topology(); |
| 8916 | ndoms_cur = 1; | 8995 | ndoms_cur = 1; |
| 8917 | doms_cur = kmalloc(cpumask_size(), GFP_KERNEL); | 8996 | doms_cur = alloc_sched_domains(ndoms_cur); |
| 8918 | if (!doms_cur) | 8997 | if (!doms_cur) |
| 8919 | doms_cur = fallback_doms; | 8998 | doms_cur = &fallback_doms; |
| 8920 | cpumask_andnot(doms_cur, cpu_map, cpu_isolated_map); | 8999 | cpumask_andnot(doms_cur[0], cpu_map, cpu_isolated_map); |
| 8921 | dattr_cur = NULL; | 9000 | dattr_cur = NULL; |
| 8922 | err = build_sched_domains(doms_cur); | 9001 | err = build_sched_domains(doms_cur[0]); |
| 8923 | register_sched_domain_sysctl(); | 9002 | register_sched_domain_sysctl(); |
| 8924 | 9003 | ||
| 8925 | return err; | 9004 | return err; |
| @@ -8969,19 +9048,19 @@ static int dattrs_equal(struct sched_domain_attr *cur, int idx_cur, | |||
| 8969 | * doms_new[] to the current sched domain partitioning, doms_cur[]. | 9048 | * doms_new[] to the current sched domain partitioning, doms_cur[]. |
| 8970 | * It destroys each deleted domain and builds each new domain. | 9049 | * It destroys each deleted domain and builds each new domain. |
| 8971 | * | 9050 | * |
| 8972 | * 'doms_new' is an array of cpumask's of length 'ndoms_new'. | 9051 | * 'doms_new' is an array of cpumask_var_t's of length 'ndoms_new'. |
| 8973 | * The masks don't intersect (don't overlap.) We should setup one | 9052 | * The masks don't intersect (don't overlap.) We should setup one |
| 8974 | * sched domain for each mask. CPUs not in any of the cpumasks will | 9053 | * sched domain for each mask. CPUs not in any of the cpumasks will |
| 8975 | * not be load balanced. If the same cpumask appears both in the | 9054 | * not be load balanced. If the same cpumask appears both in the |
| 8976 | * current 'doms_cur' domains and in the new 'doms_new', we can leave | 9055 | * current 'doms_cur' domains and in the new 'doms_new', we can leave |
| 8977 | * it as it is. | 9056 | * it as it is. |
| 8978 | * | 9057 | * |
| 8979 | * The passed in 'doms_new' should be kmalloc'd. This routine takes | 9058 | * The passed in 'doms_new' should be allocated using |
| 8980 | * ownership of it and will kfree it when done with it. If the caller | 9059 | * alloc_sched_domains. This routine takes ownership of it and will |
| 8981 | * failed the kmalloc call, then it can pass in doms_new == NULL && | 9060 | * free_sched_domains it when done with it. If the caller failed the |
| 8982 | * ndoms_new == 1, and partition_sched_domains() will fallback to | 9061 | * alloc call, then it can pass in doms_new == NULL && ndoms_new == 1, |
| 8983 | * the single partition 'fallback_doms', it also forces the domains | 9062 | * and partition_sched_domains() will fallback to the single partition |
| 8984 | * to be rebuilt. | 9063 | * 'fallback_doms', it also forces the domains to be rebuilt. |
| 8985 | * | 9064 | * |
| 8986 | * If doms_new == NULL it will be replaced with cpu_online_mask. | 9065 | * If doms_new == NULL it will be replaced with cpu_online_mask. |
| 8987 | * ndoms_new == 0 is a special case for destroying existing domains, | 9066 | * ndoms_new == 0 is a special case for destroying existing domains, |
| @@ -8989,8 +9068,7 @@ static int dattrs_equal(struct sched_domain_attr *cur, int idx_cur, | |||
| 8989 | * | 9068 | * |
| 8990 | * Call with hotplug lock held | 9069 | * Call with hotplug lock held |
| 8991 | */ | 9070 | */ |
| 8992 | /* FIXME: Change to struct cpumask *doms_new[] */ | 9071 | void partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[], |
| 8993 | void partition_sched_domains(int ndoms_new, struct cpumask *doms_new, | ||
| 8994 | struct sched_domain_attr *dattr_new) | 9072 | struct sched_domain_attr *dattr_new) |
| 8995 | { | 9073 | { |
| 8996 | int i, j, n; | 9074 | int i, j, n; |
| @@ -9009,40 +9087,40 @@ void partition_sched_domains(int ndoms_new, struct cpumask *doms_new, | |||
| 9009 | /* Destroy deleted domains */ | 9087 | /* Destroy deleted domains */ |
| 9010 | for (i = 0; i < ndoms_cur; i++) { | 9088 | for (i = 0; i < ndoms_cur; i++) { |
| 9011 | for (j = 0; j < n && !new_topology; j++) { | 9089 | for (j = 0; j < n && !new_topology; j++) { |
| 9012 | if (cpumask_equal(&doms_cur[i], &doms_new[j]) | 9090 | if (cpumask_equal(doms_cur[i], doms_new[j]) |
| 9013 | && dattrs_equal(dattr_cur, i, dattr_new, j)) | 9091 | && dattrs_equal(dattr_cur, i, dattr_new, j)) |
| 9014 | goto match1; | 9092 | goto match1; |
| 9015 | } | 9093 | } |
| 9016 | /* no match - a current sched domain not in new doms_new[] */ | 9094 | /* no match - a current sched domain not in new doms_new[] */ |
| 9017 | detach_destroy_domains(doms_cur + i); | 9095 | detach_destroy_domains(doms_cur[i]); |
| 9018 | match1: | 9096 | match1: |
| 9019 | ; | 9097 | ; |
| 9020 | } | 9098 | } |
| 9021 | 9099 | ||
| 9022 | if (doms_new == NULL) { | 9100 | if (doms_new == NULL) { |
| 9023 | ndoms_cur = 0; | 9101 | ndoms_cur = 0; |
| 9024 | doms_new = fallback_doms; | 9102 | doms_new = &fallback_doms; |
| 9025 | cpumask_andnot(&doms_new[0], cpu_online_mask, cpu_isolated_map); | 9103 | cpumask_andnot(doms_new[0], cpu_online_mask, cpu_isolated_map); |
| 9026 | WARN_ON_ONCE(dattr_new); | 9104 | WARN_ON_ONCE(dattr_new); |
| 9027 | } | 9105 | } |
| 9028 | 9106 | ||
| 9029 | /* Build new domains */ | 9107 | /* Build new domains */ |
| 9030 | for (i = 0; i < ndoms_new; i++) { | 9108 | for (i = 0; i < ndoms_new; i++) { |
| 9031 | for (j = 0; j < ndoms_cur && !new_topology; j++) { | 9109 | for (j = 0; j < ndoms_cur && !new_topology; j++) { |
| 9032 | if (cpumask_equal(&doms_new[i], &doms_cur[j]) | 9110 | if (cpumask_equal(doms_new[i], doms_cur[j]) |
| 9033 | && dattrs_equal(dattr_new, i, dattr_cur, j)) | 9111 | && dattrs_equal(dattr_new, i, dattr_cur, j)) |
| 9034 | goto match2; | 9112 | goto match2; |
| 9035 | } | 9113 | } |
| 9036 | /* no match - add a new doms_new */ | 9114 | /* no match - add a new doms_new */ |
| 9037 | __build_sched_domains(doms_new + i, | 9115 | __build_sched_domains(doms_new[i], |
| 9038 | dattr_new ? dattr_new + i : NULL); | 9116 | dattr_new ? dattr_new + i : NULL); |
| 9039 | match2: | 9117 | match2: |
| 9040 | ; | 9118 | ; |
| 9041 | } | 9119 | } |
| 9042 | 9120 | ||
| 9043 | /* Remember the new sched domains */ | 9121 | /* Remember the new sched domains */ |
| 9044 | if (doms_cur != fallback_doms) | 9122 | if (doms_cur != &fallback_doms) |
| 9045 | kfree(doms_cur); | 9123 | free_sched_domains(doms_cur, ndoms_cur); |
| 9046 | kfree(dattr_cur); /* kfree(NULL) is safe */ | 9124 | kfree(dattr_cur); /* kfree(NULL) is safe */ |
| 9047 | doms_cur = doms_new; | 9125 | doms_cur = doms_new; |
| 9048 | dattr_cur = dattr_new; | 9126 | dattr_cur = dattr_new; |
| @@ -9364,10 +9442,6 @@ void __init sched_init(void) | |||
| 9364 | #ifdef CONFIG_CPUMASK_OFFSTACK | 9442 | #ifdef CONFIG_CPUMASK_OFFSTACK |
| 9365 | alloc_size += num_possible_cpus() * cpumask_size(); | 9443 | alloc_size += num_possible_cpus() * cpumask_size(); |
| 9366 | #endif | 9444 | #endif |
| 9367 | /* | ||
| 9368 | * As sched_init() is called before page_alloc is setup, | ||
| 9369 | * we use alloc_bootmem(). | ||
| 9370 | */ | ||
| 9371 | if (alloc_size) { | 9445 | if (alloc_size) { |
| 9372 | ptr = (unsigned long)kzalloc(alloc_size, GFP_NOWAIT); | 9446 | ptr = (unsigned long)kzalloc(alloc_size, GFP_NOWAIT); |
| 9373 | 9447 | ||
| @@ -9522,6 +9596,8 @@ void __init sched_init(void) | |||
| 9522 | rq->cpu = i; | 9596 | rq->cpu = i; |
| 9523 | rq->online = 0; | 9597 | rq->online = 0; |
| 9524 | rq->migration_thread = NULL; | 9598 | rq->migration_thread = NULL; |
| 9599 | rq->idle_stamp = 0; | ||
| 9600 | rq->avg_idle = 2*sysctl_sched_migration_cost; | ||
| 9525 | INIT_LIST_HEAD(&rq->migration_queue); | 9601 | INIT_LIST_HEAD(&rq->migration_queue); |
| 9526 | rq_attach_root(rq, &def_root_domain); | 9602 | rq_attach_root(rq, &def_root_domain); |
| 9527 | #endif | 9603 | #endif |
| @@ -9571,7 +9647,9 @@ void __init sched_init(void) | |||
| 9571 | zalloc_cpumask_var(&nohz.cpu_mask, GFP_NOWAIT); | 9647 | zalloc_cpumask_var(&nohz.cpu_mask, GFP_NOWAIT); |
| 9572 | alloc_cpumask_var(&nohz.ilb_grp_nohz_mask, GFP_NOWAIT); | 9648 | alloc_cpumask_var(&nohz.ilb_grp_nohz_mask, GFP_NOWAIT); |
| 9573 | #endif | 9649 | #endif |
| 9574 | zalloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT); | 9650 | /* May be allocated at isolcpus cmdline parse time */ |
| 9651 | if (cpu_isolated_map == NULL) | ||
| 9652 | zalloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT); | ||
| 9575 | #endif /* SMP */ | 9653 | #endif /* SMP */ |
| 9576 | 9654 | ||
| 9577 | perf_event_init(); | 9655 | perf_event_init(); |
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c index efb84409bc43..6988cf08f705 100644 --- a/kernel/sched_debug.c +++ b/kernel/sched_debug.c | |||
| @@ -285,12 +285,16 @@ static void print_cpu(struct seq_file *m, int cpu) | |||
| 285 | 285 | ||
| 286 | #ifdef CONFIG_SCHEDSTATS | 286 | #ifdef CONFIG_SCHEDSTATS |
| 287 | #define P(n) SEQ_printf(m, " .%-30s: %d\n", #n, rq->n); | 287 | #define P(n) SEQ_printf(m, " .%-30s: %d\n", #n, rq->n); |
| 288 | #define P64(n) SEQ_printf(m, " .%-30s: %Ld\n", #n, rq->n); | ||
| 288 | 289 | ||
| 289 | P(yld_count); | 290 | P(yld_count); |
| 290 | 291 | ||
| 291 | P(sched_switch); | 292 | P(sched_switch); |
| 292 | P(sched_count); | 293 | P(sched_count); |
| 293 | P(sched_goidle); | 294 | P(sched_goidle); |
| 295 | #ifdef CONFIG_SMP | ||
| 296 | P64(avg_idle); | ||
| 297 | #endif | ||
| 294 | 298 | ||
| 295 | P(ttwu_count); | 299 | P(ttwu_count); |
| 296 | P(ttwu_local); | 300 | P(ttwu_local); |
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 37087a7fac22..f61837ad336d 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
| @@ -1345,6 +1345,37 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) | |||
| 1345 | } | 1345 | } |
| 1346 | 1346 | ||
| 1347 | /* | 1347 | /* |
| 1348 | * Try and locate an idle CPU in the sched_domain. | ||
| 1349 | */ | ||
| 1350 | static int | ||
| 1351 | select_idle_sibling(struct task_struct *p, struct sched_domain *sd, int target) | ||
| 1352 | { | ||
| 1353 | int cpu = smp_processor_id(); | ||
| 1354 | int prev_cpu = task_cpu(p); | ||
| 1355 | int i; | ||
| 1356 | |||
| 1357 | /* | ||
| 1358 | * If this domain spans both cpu and prev_cpu (see the SD_WAKE_AFFINE | ||
| 1359 | * test in select_task_rq_fair) and the prev_cpu is idle then that's | ||
| 1360 | * always a better target than the current cpu. | ||
| 1361 | */ | ||
| 1362 | if (target == cpu && !cpu_rq(prev_cpu)->cfs.nr_running) | ||
| 1363 | return prev_cpu; | ||
| 1364 | |||
| 1365 | /* | ||
| 1366 | * Otherwise, iterate the domain and find an elegible idle cpu. | ||
| 1367 | */ | ||
| 1368 | for_each_cpu_and(i, sched_domain_span(sd), &p->cpus_allowed) { | ||
| 1369 | if (!cpu_rq(i)->cfs.nr_running) { | ||
| 1370 | target = i; | ||
| 1371 | break; | ||
| 1372 | } | ||
| 1373 | } | ||
| 1374 | |||
| 1375 | return target; | ||
| 1376 | } | ||
| 1377 | |||
| 1378 | /* | ||
| 1348 | * sched_balance_self: balance the current task (running on cpu) in domains | 1379 | * sched_balance_self: balance the current task (running on cpu) in domains |
| 1349 | * that have the 'flag' flag set. In practice, this is SD_BALANCE_FORK and | 1380 | * that have the 'flag' flag set. In practice, this is SD_BALANCE_FORK and |
| 1350 | * SD_BALANCE_EXEC. | 1381 | * SD_BALANCE_EXEC. |
| @@ -1398,11 +1429,35 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag | |||
| 1398 | want_sd = 0; | 1429 | want_sd = 0; |
| 1399 | } | 1430 | } |
| 1400 | 1431 | ||
| 1401 | if (want_affine && (tmp->flags & SD_WAKE_AFFINE) && | 1432 | /* |
| 1402 | cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) { | 1433 | * While iterating the domains looking for a spanning |
| 1434 | * WAKE_AFFINE domain, adjust the affine target to any idle cpu | ||
| 1435 | * in cache sharing domains along the way. | ||
| 1436 | */ | ||
| 1437 | if (want_affine) { | ||
| 1438 | int target = -1; | ||
| 1403 | 1439 | ||
| 1404 | affine_sd = tmp; | 1440 | /* |
| 1405 | want_affine = 0; | 1441 | * If both cpu and prev_cpu are part of this domain, |
| 1442 | * cpu is a valid SD_WAKE_AFFINE target. | ||
| 1443 | */ | ||
| 1444 | if (cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) | ||
| 1445 | target = cpu; | ||
| 1446 | |||
| 1447 | /* | ||
| 1448 | * If there's an idle sibling in this domain, make that | ||
| 1449 | * the wake_affine target instead of the current cpu. | ||
| 1450 | */ | ||
| 1451 | if (tmp->flags & SD_PREFER_SIBLING) | ||
| 1452 | target = select_idle_sibling(p, tmp, target); | ||
| 1453 | |||
| 1454 | if (target >= 0) { | ||
| 1455 | if (tmp->flags & SD_WAKE_AFFINE) { | ||
| 1456 | affine_sd = tmp; | ||
| 1457 | want_affine = 0; | ||
| 1458 | } | ||
| 1459 | cpu = target; | ||
| 1460 | } | ||
| 1406 | } | 1461 | } |
| 1407 | 1462 | ||
| 1408 | if (!want_sd && !want_affine) | 1463 | if (!want_sd && !want_affine) |
| @@ -1679,7 +1734,7 @@ static struct task_struct *pick_next_task_fair(struct rq *rq) | |||
| 1679 | struct cfs_rq *cfs_rq = &rq->cfs; | 1734 | struct cfs_rq *cfs_rq = &rq->cfs; |
| 1680 | struct sched_entity *se; | 1735 | struct sched_entity *se; |
| 1681 | 1736 | ||
| 1682 | if (unlikely(!cfs_rq->nr_running)) | 1737 | if (!cfs_rq->nr_running) |
| 1683 | return NULL; | 1738 | return NULL; |
| 1684 | 1739 | ||
| 1685 | do { | 1740 | do { |
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index a4d790cddb19..5c5fef378415 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c | |||
| @@ -1153,29 +1153,12 @@ static struct task_struct *pick_next_highest_task_rt(struct rq *rq, int cpu) | |||
| 1153 | 1153 | ||
| 1154 | static DEFINE_PER_CPU(cpumask_var_t, local_cpu_mask); | 1154 | static DEFINE_PER_CPU(cpumask_var_t, local_cpu_mask); |
| 1155 | 1155 | ||
| 1156 | static inline int pick_optimal_cpu(int this_cpu, | ||
| 1157 | const struct cpumask *mask) | ||
| 1158 | { | ||
| 1159 | int first; | ||
| 1160 | |||
| 1161 | /* "this_cpu" is cheaper to preempt than a remote processor */ | ||
| 1162 | if ((this_cpu != -1) && cpumask_test_cpu(this_cpu, mask)) | ||
| 1163 | return this_cpu; | ||
| 1164 | |||
| 1165 | first = cpumask_first(mask); | ||
| 1166 | if (first < nr_cpu_ids) | ||
| 1167 | return first; | ||
| 1168 | |||
| 1169 | return -1; | ||
| 1170 | } | ||
| 1171 | |||
| 1172 | static int find_lowest_rq(struct task_struct *task) | 1156 | static int find_lowest_rq(struct task_struct *task) |
| 1173 | { | 1157 | { |
| 1174 | struct sched_domain *sd; | 1158 | struct sched_domain *sd; |
| 1175 | struct cpumask *lowest_mask = __get_cpu_var(local_cpu_mask); | 1159 | struct cpumask *lowest_mask = __get_cpu_var(local_cpu_mask); |
| 1176 | int this_cpu = smp_processor_id(); | 1160 | int this_cpu = smp_processor_id(); |
| 1177 | int cpu = task_cpu(task); | 1161 | int cpu = task_cpu(task); |
| 1178 | cpumask_var_t domain_mask; | ||
| 1179 | 1162 | ||
| 1180 | if (task->rt.nr_cpus_allowed == 1) | 1163 | if (task->rt.nr_cpus_allowed == 1) |
| 1181 | return -1; /* No other targets possible */ | 1164 | return -1; /* No other targets possible */ |
| @@ -1198,28 +1181,26 @@ static int find_lowest_rq(struct task_struct *task) | |||
| 1198 | * Otherwise, we consult the sched_domains span maps to figure | 1181 | * Otherwise, we consult the sched_domains span maps to figure |
| 1199 | * out which cpu is logically closest to our hot cache data. | 1182 | * out which cpu is logically closest to our hot cache data. |
| 1200 | */ | 1183 | */ |
| 1201 | if (this_cpu == cpu) | 1184 | if (!cpumask_test_cpu(this_cpu, lowest_mask)) |
| 1202 | this_cpu = -1; /* Skip this_cpu opt if the same */ | 1185 | this_cpu = -1; /* Skip this_cpu opt if not among lowest */ |
| 1203 | |||
| 1204 | if (alloc_cpumask_var(&domain_mask, GFP_ATOMIC)) { | ||
| 1205 | for_each_domain(cpu, sd) { | ||
| 1206 | if (sd->flags & SD_WAKE_AFFINE) { | ||
| 1207 | int best_cpu; | ||
| 1208 | 1186 | ||
| 1209 | cpumask_and(domain_mask, | 1187 | for_each_domain(cpu, sd) { |
| 1210 | sched_domain_span(sd), | 1188 | if (sd->flags & SD_WAKE_AFFINE) { |
| 1211 | lowest_mask); | 1189 | int best_cpu; |
| 1212 | 1190 | ||
| 1213 | best_cpu = pick_optimal_cpu(this_cpu, | 1191 | /* |
| 1214 | domain_mask); | 1192 | * "this_cpu" is cheaper to preempt than a |
| 1215 | 1193 | * remote processor. | |
| 1216 | if (best_cpu != -1) { | 1194 | */ |
| 1217 | free_cpumask_var(domain_mask); | 1195 | if (this_cpu != -1 && |
| 1218 | return best_cpu; | 1196 | cpumask_test_cpu(this_cpu, sched_domain_span(sd))) |
| 1219 | } | 1197 | return this_cpu; |
| 1220 | } | 1198 | |
| 1199 | best_cpu = cpumask_first_and(lowest_mask, | ||
| 1200 | sched_domain_span(sd)); | ||
| 1201 | if (best_cpu < nr_cpu_ids) | ||
| 1202 | return best_cpu; | ||
| 1221 | } | 1203 | } |
| 1222 | free_cpumask_var(domain_mask); | ||
| 1223 | } | 1204 | } |
| 1224 | 1205 | ||
| 1225 | /* | 1206 | /* |
| @@ -1227,7 +1208,13 @@ static int find_lowest_rq(struct task_struct *task) | |||
| 1227 | * just give the caller *something* to work with from the compatible | 1208 | * just give the caller *something* to work with from the compatible |
| 1228 | * locations. | 1209 | * locations. |
| 1229 | */ | 1210 | */ |
| 1230 | return pick_optimal_cpu(this_cpu, lowest_mask); | 1211 | if (this_cpu != -1) |
| 1212 | return this_cpu; | ||
| 1213 | |||
| 1214 | cpu = cpumask_any(lowest_mask); | ||
| 1215 | if (cpu < nr_cpu_ids) | ||
| 1216 | return cpu; | ||
| 1217 | return -1; | ||
| 1231 | } | 1218 | } |
| 1232 | 1219 | ||
| 1233 | /* Will lock the rq it finds */ | 1220 | /* Will lock the rq it finds */ |
diff --git a/kernel/sys.c b/kernel/sys.c index ce17760d9c51..9968c5fb55b9 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
| @@ -911,16 +911,15 @@ change_okay: | |||
| 911 | 911 | ||
| 912 | void do_sys_times(struct tms *tms) | 912 | void do_sys_times(struct tms *tms) |
| 913 | { | 913 | { |
| 914 | struct task_cputime cputime; | 914 | cputime_t tgutime, tgstime, cutime, cstime; |
| 915 | cputime_t cutime, cstime; | ||
| 916 | 915 | ||
| 917 | thread_group_cputime(current, &cputime); | ||
| 918 | spin_lock_irq(¤t->sighand->siglock); | 916 | spin_lock_irq(¤t->sighand->siglock); |
| 917 | thread_group_times(current, &tgutime, &tgstime); | ||
| 919 | cutime = current->signal->cutime; | 918 | cutime = current->signal->cutime; |
| 920 | cstime = current->signal->cstime; | 919 | cstime = current->signal->cstime; |
| 921 | spin_unlock_irq(¤t->sighand->siglock); | 920 | spin_unlock_irq(¤t->sighand->siglock); |
| 922 | tms->tms_utime = cputime_to_clock_t(cputime.utime); | 921 | tms->tms_utime = cputime_to_clock_t(tgutime); |
| 923 | tms->tms_stime = cputime_to_clock_t(cputime.stime); | 922 | tms->tms_stime = cputime_to_clock_t(tgstime); |
| 924 | tms->tms_cutime = cputime_to_clock_t(cutime); | 923 | tms->tms_cutime = cputime_to_clock_t(cutime); |
| 925 | tms->tms_cstime = cputime_to_clock_t(cstime); | 924 | tms->tms_cstime = cputime_to_clock_t(cstime); |
| 926 | } | 925 | } |
| @@ -1338,16 +1337,14 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | |||
| 1338 | { | 1337 | { |
| 1339 | struct task_struct *t; | 1338 | struct task_struct *t; |
| 1340 | unsigned long flags; | 1339 | unsigned long flags; |
| 1341 | cputime_t utime, stime; | 1340 | cputime_t tgutime, tgstime, utime, stime; |
| 1342 | struct task_cputime cputime; | ||
| 1343 | unsigned long maxrss = 0; | 1341 | unsigned long maxrss = 0; |
| 1344 | 1342 | ||
| 1345 | memset((char *) r, 0, sizeof *r); | 1343 | memset((char *) r, 0, sizeof *r); |
| 1346 | utime = stime = cputime_zero; | 1344 | utime = stime = cputime_zero; |
| 1347 | 1345 | ||
| 1348 | if (who == RUSAGE_THREAD) { | 1346 | if (who == RUSAGE_THREAD) { |
| 1349 | utime = task_utime(current); | 1347 | task_times(current, &utime, &stime); |
| 1350 | stime = task_stime(current); | ||
| 1351 | accumulate_thread_rusage(p, r); | 1348 | accumulate_thread_rusage(p, r); |
| 1352 | maxrss = p->signal->maxrss; | 1349 | maxrss = p->signal->maxrss; |
| 1353 | goto out; | 1350 | goto out; |
| @@ -1373,9 +1370,9 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | |||
| 1373 | break; | 1370 | break; |
| 1374 | 1371 | ||
| 1375 | case RUSAGE_SELF: | 1372 | case RUSAGE_SELF: |
| 1376 | thread_group_cputime(p, &cputime); | 1373 | thread_group_times(p, &tgutime, &tgstime); |
| 1377 | utime = cputime_add(utime, cputime.utime); | 1374 | utime = cputime_add(utime, tgutime); |
| 1378 | stime = cputime_add(stime, cputime.stime); | 1375 | stime = cputime_add(stime, tgstime); |
| 1379 | r->ru_nvcsw += p->signal->nvcsw; | 1376 | r->ru_nvcsw += p->signal->nvcsw; |
| 1380 | r->ru_nivcsw += p->signal->nivcsw; | 1377 | r->ru_nivcsw += p->signal->nivcsw; |
| 1381 | r->ru_minflt += p->signal->min_flt; | 1378 | r->ru_minflt += p->signal->min_flt; |
diff --git a/kernel/time.c b/kernel/time.c index 2e2e469a7fec..804798005d19 100644 --- a/kernel/time.c +++ b/kernel/time.c | |||
| @@ -662,6 +662,36 @@ u64 nsec_to_clock_t(u64 x) | |||
| 662 | #endif | 662 | #endif |
| 663 | } | 663 | } |
| 664 | 664 | ||
| 665 | /** | ||
| 666 | * nsecs_to_jiffies - Convert nsecs in u64 to jiffies | ||
| 667 | * | ||
| 668 | * @n: nsecs in u64 | ||
| 669 | * | ||
| 670 | * Unlike {m,u}secs_to_jiffies, type of input is not unsigned int but u64. | ||
| 671 | * And this doesn't return MAX_JIFFY_OFFSET since this function is designed | ||
| 672 | * for scheduler, not for use in device drivers to calculate timeout value. | ||
| 673 | * | ||
| 674 | * note: | ||
| 675 | * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512) | ||
| 676 | * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years | ||
| 677 | */ | ||
| 678 | unsigned long nsecs_to_jiffies(u64 n) | ||
| 679 | { | ||
| 680 | #if (NSEC_PER_SEC % HZ) == 0 | ||
| 681 | /* Common case, HZ = 100, 128, 200, 250, 256, 500, 512, 1000 etc. */ | ||
| 682 | return div_u64(n, NSEC_PER_SEC / HZ); | ||
| 683 | #elif (HZ % 512) == 0 | ||
| 684 | /* overflow after 292 years if HZ = 1024 */ | ||
| 685 | return div_u64(n * HZ / 512, NSEC_PER_SEC / 512); | ||
| 686 | #else | ||
| 687 | /* | ||
| 688 | * Generic case - optimized for cases where HZ is a multiple of 3. | ||
| 689 | * overflow after 64.99 years, exact for HZ = 60, 72, 90, 120 etc. | ||
| 690 | */ | ||
| 691 | return div_u64(n * 9, (9ull * NSEC_PER_SEC + HZ / 2) / HZ); | ||
| 692 | #endif | ||
| 693 | } | ||
| 694 | |||
| 665 | #if (BITS_PER_LONG < 64) | 695 | #if (BITS_PER_LONG < 64) |
| 666 | u64 get_jiffies_64(void) | 696 | u64 get_jiffies_64(void) |
| 667 | { | 697 | { |
