diff options
-rw-r--r-- | arch/alpha/kernel/osf_sys.c | 13 | ||||
-rw-r--r-- | arch/x86/kernel/apm_32.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/tile/tilegx.c | 4 | ||||
-rw-r--r-- | include/linux/jiffies.h | 9 | ||||
-rw-r--r-- | include/linux/tick.h | 25 | ||||
-rw-r--r-- | kernel/sched/core.c | 2 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 72 | ||||
-rw-r--r-- | kernel/time/time.c | 10 |
8 files changed, 62 insertions, 75 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 36dc91ace83a..6cc08166ff00 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -1138,6 +1138,7 @@ SYSCALL_DEFINE2(osf_getrusage, int, who, struct rusage32 __user *, ru) | |||
1138 | { | 1138 | { |
1139 | struct rusage32 r; | 1139 | struct rusage32 r; |
1140 | cputime_t utime, stime; | 1140 | cputime_t utime, stime; |
1141 | unsigned long utime_jiffies, stime_jiffies; | ||
1141 | 1142 | ||
1142 | if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN) | 1143 | if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN) |
1143 | return -EINVAL; | 1144 | return -EINVAL; |
@@ -1146,14 +1147,18 @@ SYSCALL_DEFINE2(osf_getrusage, int, who, struct rusage32 __user *, ru) | |||
1146 | switch (who) { | 1147 | switch (who) { |
1147 | case RUSAGE_SELF: | 1148 | case RUSAGE_SELF: |
1148 | task_cputime(current, &utime, &stime); | 1149 | task_cputime(current, &utime, &stime); |
1149 | jiffies_to_timeval32(utime, &r.ru_utime); | 1150 | utime_jiffies = cputime_to_jiffies(utime); |
1150 | jiffies_to_timeval32(stime, &r.ru_stime); | 1151 | stime_jiffies = cputime_to_jiffies(stime); |
1152 | jiffies_to_timeval32(utime_jiffies, &r.ru_utime); | ||
1153 | jiffies_to_timeval32(stime_jiffies, &r.ru_stime); | ||
1151 | r.ru_minflt = current->min_flt; | 1154 | r.ru_minflt = current->min_flt; |
1152 | r.ru_majflt = current->maj_flt; | 1155 | r.ru_majflt = current->maj_flt; |
1153 | break; | 1156 | break; |
1154 | case RUSAGE_CHILDREN: | 1157 | case RUSAGE_CHILDREN: |
1155 | jiffies_to_timeval32(current->signal->cutime, &r.ru_utime); | 1158 | utime_jiffies = cputime_to_jiffies(current->signal->cutime); |
1156 | jiffies_to_timeval32(current->signal->cstime, &r.ru_stime); | 1159 | stime_jiffies = cputime_to_jiffies(current->signal->cstime); |
1160 | jiffies_to_timeval32(utime_jiffies, &r.ru_utime); | ||
1161 | jiffies_to_timeval32(stime_jiffies, &r.ru_stime); | ||
1157 | r.ru_minflt = current->signal->cmin_flt; | 1162 | r.ru_minflt = current->signal->cmin_flt; |
1158 | r.ru_majflt = current->signal->cmaj_flt; | 1163 | r.ru_majflt = current->signal->cmaj_flt; |
1159 | break; | 1164 | break; |
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 927ec9235947..052c9c3026cc 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c | |||
@@ -919,7 +919,7 @@ recalc: | |||
919 | } else if (jiffies_since_last_check > idle_period) { | 919 | } else if (jiffies_since_last_check > idle_period) { |
920 | unsigned int idle_percentage; | 920 | unsigned int idle_percentage; |
921 | 921 | ||
922 | idle_percentage = stime - last_stime; | 922 | idle_percentage = cputime_to_jiffies(stime - last_stime); |
923 | idle_percentage *= 100; | 923 | idle_percentage *= 100; |
924 | idle_percentage /= jiffies_since_last_check; | 924 | idle_percentage /= jiffies_since_last_check; |
925 | use_apm_idle = (idle_percentage > idle_threshold); | 925 | use_apm_idle = (idle_percentage > idle_threshold); |
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c index a3f7610002aa..0a15acc075b3 100644 --- a/drivers/net/ethernet/tile/tilegx.c +++ b/drivers/net/ethernet/tile/tilegx.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/tcp.h> | 40 | #include <linux/tcp.h> |
41 | #include <linux/net_tstamp.h> | 41 | #include <linux/net_tstamp.h> |
42 | #include <linux/ptp_clock_kernel.h> | 42 | #include <linux/ptp_clock_kernel.h> |
43 | #include <linux/tick.h> | ||
43 | 44 | ||
44 | #include <asm/checksum.h> | 45 | #include <asm/checksum.h> |
45 | #include <asm/homecache.h> | 46 | #include <asm/homecache.h> |
@@ -2273,7 +2274,8 @@ static int __init tile_net_init_module(void) | |||
2273 | tile_net_dev_init(name, mac); | 2274 | tile_net_dev_init(name, mac); |
2274 | 2275 | ||
2275 | if (!network_cpus_init()) | 2276 | if (!network_cpus_init()) |
2276 | network_cpus_map = *cpu_online_mask; | 2277 | cpumask_and(&network_cpus_map, housekeeping_cpumask(), |
2278 | cpu_online_mask); | ||
2277 | 2279 | ||
2278 | return 0; | 2280 | return 0; |
2279 | } | 2281 | } |
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h index 1ba48a18c1d7..9ea50da73513 100644 --- a/include/linux/jiffies.h +++ b/include/linux/jiffies.h | |||
@@ -363,18 +363,11 @@ static __always_inline unsigned long msecs_to_jiffies(const unsigned int m) | |||
363 | } | 363 | } |
364 | 364 | ||
365 | extern unsigned long __usecs_to_jiffies(const unsigned int u); | 365 | extern unsigned long __usecs_to_jiffies(const unsigned int u); |
366 | #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ) | 366 | #if !(USEC_PER_SEC % HZ) |
367 | static inline unsigned long _usecs_to_jiffies(const unsigned int u) | 367 | static inline unsigned long _usecs_to_jiffies(const unsigned int u) |
368 | { | 368 | { |
369 | return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ); | 369 | return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ); |
370 | } | 370 | } |
371 | #elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC) | ||
372 | static inline unsigned long _usecs_to_jiffies(const unsigned int u) | ||
373 | { | ||
374 | return u * (HZ / USEC_PER_SEC); | ||
375 | } | ||
376 | static inline unsigned long _usecs_to_jiffies(const unsigned int u) | ||
377 | { | ||
378 | #else | 371 | #else |
379 | static inline unsigned long _usecs_to_jiffies(const unsigned int u) | 372 | static inline unsigned long _usecs_to_jiffies(const unsigned int u) |
380 | { | 373 | { |
diff --git a/include/linux/tick.h b/include/linux/tick.h index edbfc9a5293e..48d901f83f92 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h | |||
@@ -147,22 +147,29 @@ static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) | |||
147 | cpumask_or(mask, mask, tick_nohz_full_mask); | 147 | cpumask_or(mask, mask, tick_nohz_full_mask); |
148 | } | 148 | } |
149 | 149 | ||
150 | extern void __tick_nohz_full_check(void); | ||
151 | extern void tick_nohz_full_kick(void); | 150 | extern void tick_nohz_full_kick(void); |
152 | extern void tick_nohz_full_kick_cpu(int cpu); | 151 | extern void tick_nohz_full_kick_cpu(int cpu); |
153 | extern void tick_nohz_full_kick_all(void); | 152 | extern void tick_nohz_full_kick_all(void); |
154 | extern void __tick_nohz_task_switch(struct task_struct *tsk); | 153 | extern void __tick_nohz_task_switch(void); |
155 | #else | 154 | #else |
156 | static inline bool tick_nohz_full_enabled(void) { return false; } | 155 | static inline bool tick_nohz_full_enabled(void) { return false; } |
157 | static inline bool tick_nohz_full_cpu(int cpu) { return false; } | 156 | static inline bool tick_nohz_full_cpu(int cpu) { return false; } |
158 | static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { } | 157 | static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { } |
159 | static inline void __tick_nohz_full_check(void) { } | ||
160 | static inline void tick_nohz_full_kick_cpu(int cpu) { } | 158 | static inline void tick_nohz_full_kick_cpu(int cpu) { } |
161 | static inline void tick_nohz_full_kick(void) { } | 159 | static inline void tick_nohz_full_kick(void) { } |
162 | static inline void tick_nohz_full_kick_all(void) { } | 160 | static inline void tick_nohz_full_kick_all(void) { } |
163 | static inline void __tick_nohz_task_switch(struct task_struct *tsk) { } | 161 | static inline void __tick_nohz_task_switch(void) { } |
164 | #endif | 162 | #endif |
165 | 163 | ||
164 | static inline const struct cpumask *housekeeping_cpumask(void) | ||
165 | { | ||
166 | #ifdef CONFIG_NO_HZ_FULL | ||
167 | if (tick_nohz_full_enabled()) | ||
168 | return housekeeping_mask; | ||
169 | #endif | ||
170 | return cpu_possible_mask; | ||
171 | } | ||
172 | |||
166 | static inline bool is_housekeeping_cpu(int cpu) | 173 | static inline bool is_housekeeping_cpu(int cpu) |
167 | { | 174 | { |
168 | #ifdef CONFIG_NO_HZ_FULL | 175 | #ifdef CONFIG_NO_HZ_FULL |
@@ -181,16 +188,10 @@ static inline void housekeeping_affine(struct task_struct *t) | |||
181 | #endif | 188 | #endif |
182 | } | 189 | } |
183 | 190 | ||
184 | static inline void tick_nohz_full_check(void) | 191 | static inline void tick_nohz_task_switch(void) |
185 | { | ||
186 | if (tick_nohz_full_enabled()) | ||
187 | __tick_nohz_full_check(); | ||
188 | } | ||
189 | |||
190 | static inline void tick_nohz_task_switch(struct task_struct *tsk) | ||
191 | { | 192 | { |
192 | if (tick_nohz_full_enabled()) | 193 | if (tick_nohz_full_enabled()) |
193 | __tick_nohz_task_switch(tsk); | 194 | __tick_nohz_task_switch(); |
194 | } | 195 | } |
195 | 196 | ||
196 | #endif | 197 | #endif |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 7819725e9da8..8b864ecee0e1 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -2543,7 +2543,7 @@ static struct rq *finish_task_switch(struct task_struct *prev) | |||
2543 | put_task_struct(prev); | 2543 | put_task_struct(prev); |
2544 | } | 2544 | } |
2545 | 2545 | ||
2546 | tick_nohz_task_switch(current); | 2546 | tick_nohz_task_switch(); |
2547 | return rq; | 2547 | return rq; |
2548 | } | 2548 | } |
2549 | 2549 | ||
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index c792429e98c6..3319e16f31e5 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -197,27 +197,9 @@ static bool can_stop_full_tick(void) | |||
197 | return true; | 197 | return true; |
198 | } | 198 | } |
199 | 199 | ||
200 | static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now); | ||
201 | |||
202 | /* | ||
203 | * Re-evaluate the need for the tick on the current CPU | ||
204 | * and restart it if necessary. | ||
205 | */ | ||
206 | void __tick_nohz_full_check(void) | ||
207 | { | ||
208 | struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched); | ||
209 | |||
210 | if (tick_nohz_full_cpu(smp_processor_id())) { | ||
211 | if (ts->tick_stopped && !is_idle_task(current)) { | ||
212 | if (!can_stop_full_tick()) | ||
213 | tick_nohz_restart_sched_tick(ts, ktime_get()); | ||
214 | } | ||
215 | } | ||
216 | } | ||
217 | |||
218 | static void nohz_full_kick_work_func(struct irq_work *work) | 200 | static void nohz_full_kick_work_func(struct irq_work *work) |
219 | { | 201 | { |
220 | __tick_nohz_full_check(); | 202 | /* Empty, the tick restart happens on tick_nohz_irq_exit() */ |
221 | } | 203 | } |
222 | 204 | ||
223 | static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) = { | 205 | static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) = { |
@@ -252,7 +234,7 @@ void tick_nohz_full_kick_cpu(int cpu) | |||
252 | 234 | ||
253 | static void nohz_full_kick_ipi(void *info) | 235 | static void nohz_full_kick_ipi(void *info) |
254 | { | 236 | { |
255 | __tick_nohz_full_check(); | 237 | /* Empty, the tick restart happens on tick_nohz_irq_exit() */ |
256 | } | 238 | } |
257 | 239 | ||
258 | /* | 240 | /* |
@@ -276,7 +258,7 @@ void tick_nohz_full_kick_all(void) | |||
276 | * It might need the tick due to per task/process properties: | 258 | * It might need the tick due to per task/process properties: |
277 | * perf events, posix cpu timers, ... | 259 | * perf events, posix cpu timers, ... |
278 | */ | 260 | */ |
279 | void __tick_nohz_task_switch(struct task_struct *tsk) | 261 | void __tick_nohz_task_switch(void) |
280 | { | 262 | { |
281 | unsigned long flags; | 263 | unsigned long flags; |
282 | 264 | ||
@@ -705,21 +687,38 @@ out: | |||
705 | return tick; | 687 | return tick; |
706 | } | 688 | } |
707 | 689 | ||
708 | static void tick_nohz_full_stop_tick(struct tick_sched *ts) | 690 | static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now) |
691 | { | ||
692 | /* Update jiffies first */ | ||
693 | tick_do_update_jiffies64(now); | ||
694 | update_cpu_load_nohz(); | ||
695 | |||
696 | calc_load_exit_idle(); | ||
697 | touch_softlockup_watchdog(); | ||
698 | /* | ||
699 | * Cancel the scheduled timer and restore the tick | ||
700 | */ | ||
701 | ts->tick_stopped = 0; | ||
702 | ts->idle_exittime = now; | ||
703 | |||
704 | tick_nohz_restart(ts, now); | ||
705 | } | ||
706 | |||
707 | static void tick_nohz_full_update_tick(struct tick_sched *ts) | ||
709 | { | 708 | { |
710 | #ifdef CONFIG_NO_HZ_FULL | 709 | #ifdef CONFIG_NO_HZ_FULL |
711 | int cpu = smp_processor_id(); | 710 | int cpu = smp_processor_id(); |
712 | 711 | ||
713 | if (!tick_nohz_full_cpu(cpu) || is_idle_task(current)) | 712 | if (!tick_nohz_full_cpu(cpu)) |
714 | return; | 713 | return; |
715 | 714 | ||
716 | if (!ts->tick_stopped && ts->nohz_mode == NOHZ_MODE_INACTIVE) | 715 | if (!ts->tick_stopped && ts->nohz_mode == NOHZ_MODE_INACTIVE) |
717 | return; | 716 | return; |
718 | 717 | ||
719 | if (!can_stop_full_tick()) | 718 | if (can_stop_full_tick()) |
720 | return; | 719 | tick_nohz_stop_sched_tick(ts, ktime_get(), cpu); |
721 | 720 | else if (ts->tick_stopped) | |
722 | tick_nohz_stop_sched_tick(ts, ktime_get(), cpu); | 721 | tick_nohz_restart_sched_tick(ts, ktime_get()); |
723 | #endif | 722 | #endif |
724 | } | 723 | } |
725 | 724 | ||
@@ -849,7 +848,7 @@ void tick_nohz_irq_exit(void) | |||
849 | if (ts->inidle) | 848 | if (ts->inidle) |
850 | __tick_nohz_idle_enter(ts); | 849 | __tick_nohz_idle_enter(ts); |
851 | else | 850 | else |
852 | tick_nohz_full_stop_tick(ts); | 851 | tick_nohz_full_update_tick(ts); |
853 | } | 852 | } |
854 | 853 | ||
855 | /** | 854 | /** |
@@ -864,23 +863,6 @@ ktime_t tick_nohz_get_sleep_length(void) | |||
864 | return ts->sleep_length; | 863 | return ts->sleep_length; |
865 | } | 864 | } |
866 | 865 | ||
867 | static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now) | ||
868 | { | ||
869 | /* Update jiffies first */ | ||
870 | tick_do_update_jiffies64(now); | ||
871 | update_cpu_load_nohz(); | ||
872 | |||
873 | calc_load_exit_idle(); | ||
874 | touch_softlockup_watchdog(); | ||
875 | /* | ||
876 | * Cancel the scheduled timer and restore the tick | ||
877 | */ | ||
878 | ts->tick_stopped = 0; | ||
879 | ts->idle_exittime = now; | ||
880 | |||
881 | tick_nohz_restart(ts, now); | ||
882 | } | ||
883 | |||
884 | static void tick_nohz_account_idle_ticks(struct tick_sched *ts) | 866 | static void tick_nohz_account_idle_ticks(struct tick_sched *ts) |
885 | { | 867 | { |
886 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE | 868 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
diff --git a/kernel/time/time.c b/kernel/time/time.c index 85d5bb1d67eb..ad1bf23e6eb7 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c | |||
@@ -268,10 +268,14 @@ EXPORT_SYMBOL(jiffies_to_msecs); | |||
268 | 268 | ||
269 | unsigned int jiffies_to_usecs(const unsigned long j) | 269 | unsigned int jiffies_to_usecs(const unsigned long j) |
270 | { | 270 | { |
271 | #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ) | 271 | /* |
272 | * Hz usually doesn't go much further MSEC_PER_SEC. | ||
273 | * jiffies_to_usecs() and usecs_to_jiffies() depend on that. | ||
274 | */ | ||
275 | BUILD_BUG_ON(HZ > USEC_PER_SEC); | ||
276 | |||
277 | #if !(USEC_PER_SEC % HZ) | ||
272 | return (USEC_PER_SEC / HZ) * j; | 278 | return (USEC_PER_SEC / HZ) * j; |
273 | #elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC) | ||
274 | return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC); | ||
275 | #else | 279 | #else |
276 | # if BITS_PER_LONG == 32 | 280 | # if BITS_PER_LONG == 32 |
277 | return (HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32; | 281 | return (HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32; |