diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-02-01 16:27:00 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-02-01 16:27:00 -0500 |
commit | 45f37e86f1ef95f002386d8a0ab508407cec9bf3 (patch) | |
tree | aeae54129b9a440b2d1d80a80d84070a91e83c9c | |
parent | e30ec4525d4731d828a754823a83a3d6b50bb230 (diff) | |
parent | aa7d93506cc26378be6964692cd0dd34cffaee25 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-sched
* git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-sched:
latencytop: Change Kconfig dependency.
futex: Add bitset conditional wait/wakeup functionality
futex: Remove warn on in return fixup path
x86: replace LOCK_PREFIX in futex.h
tick-sched: add more debug information
timekeeping: update xtime_cache when time(zone) changes
hrtimer: fix hrtimer_init_sleeper() users
-rw-r--r-- | arch/x86/Kconfig | 3 | ||||
-rw-r--r-- | include/asm-x86/futex.h | 6 | ||||
-rw-r--r-- | include/linux/futex.h | 10 | ||||
-rw-r--r-- | include/linux/thread_info.h | 1 | ||||
-rw-r--r-- | include/linux/tick.h | 4 | ||||
-rw-r--r-- | include/linux/time.h | 1 | ||||
-rw-r--r-- | kernel/futex.c | 42 | ||||
-rw-r--r-- | kernel/futex_compat.c | 3 | ||||
-rw-r--r-- | kernel/hrtimer.c | 2 | ||||
-rw-r--r-- | kernel/time.c | 1 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 2 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 6 | ||||
-rw-r--r-- | kernel/time/timer_list.c | 2 | ||||
-rw-r--r-- | lib/Kconfig.debug | 2 |
14 files changed, 68 insertions, 17 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 65b449134cf7..93e66678e158 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -44,6 +44,9 @@ config LOCKDEP_SUPPORT | |||
44 | config STACKTRACE_SUPPORT | 44 | config STACKTRACE_SUPPORT |
45 | def_bool y | 45 | def_bool y |
46 | 46 | ||
47 | config HAVE_LATENCYTOP_SUPPORT | ||
48 | def_bool y | ||
49 | |||
47 | config SEMAPHORE_SLEEPERS | 50 | config SEMAPHORE_SLEEPERS |
48 | def_bool y | 51 | def_bool y |
49 | 52 | ||
diff --git a/include/asm-x86/futex.h b/include/asm-x86/futex.h index 62828d63f1b1..9d919264923a 100644 --- a/include/asm-x86/futex.h +++ b/include/asm-x86/futex.h | |||
@@ -30,7 +30,7 @@ | |||
30 | "1: movl %2, %0\n \ | 30 | "1: movl %2, %0\n \ |
31 | movl %0, %3\n" \ | 31 | movl %0, %3\n" \ |
32 | insn "\n" \ | 32 | insn "\n" \ |
33 | "2: " LOCK_PREFIX "cmpxchgl %3, %2\n \ | 33 | "2: lock; cmpxchgl %3, %2\n \ |
34 | jnz 1b\n \ | 34 | jnz 1b\n \ |
35 | 3: .section .fixup,\"ax\"\n \ | 35 | 3: .section .fixup,\"ax\"\n \ |
36 | 4: mov %5, %1\n \ | 36 | 4: mov %5, %1\n \ |
@@ -72,7 +72,7 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr) | |||
72 | __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg); | 72 | __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg); |
73 | break; | 73 | break; |
74 | case FUTEX_OP_ADD: | 74 | case FUTEX_OP_ADD: |
75 | __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval, | 75 | __futex_atomic_op1("lock; xaddl %0, %2", ret, oldval, |
76 | uaddr, oparg); | 76 | uaddr, oparg); |
77 | break; | 77 | break; |
78 | case FUTEX_OP_OR: | 78 | case FUTEX_OP_OR: |
@@ -111,8 +111,8 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) | |||
111 | return -EFAULT; | 111 | return -EFAULT; |
112 | 112 | ||
113 | __asm__ __volatile__( | 113 | __asm__ __volatile__( |
114 | "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n" | ||
115 | 114 | ||
115 | "1: lock; cmpxchgl %3, %1 \n" | ||
116 | "2: .section .fixup, \"ax\" \n" | 116 | "2: .section .fixup, \"ax\" \n" |
117 | "3: mov %2, %0 \n" | 117 | "3: mov %2, %0 \n" |
118 | " jmp 2b \n" | 118 | " jmp 2b \n" |
diff --git a/include/linux/futex.h b/include/linux/futex.h index 1a15f8e237a7..90048fb28a38 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h | |||
@@ -21,6 +21,8 @@ union ktime; | |||
21 | #define FUTEX_LOCK_PI 6 | 21 | #define FUTEX_LOCK_PI 6 |
22 | #define FUTEX_UNLOCK_PI 7 | 22 | #define FUTEX_UNLOCK_PI 7 |
23 | #define FUTEX_TRYLOCK_PI 8 | 23 | #define FUTEX_TRYLOCK_PI 8 |
24 | #define FUTEX_WAIT_BITSET 9 | ||
25 | #define FUTEX_WAKE_BITSET 10 | ||
24 | 26 | ||
25 | #define FUTEX_PRIVATE_FLAG 128 | 27 | #define FUTEX_PRIVATE_FLAG 128 |
26 | #define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG | 28 | #define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG |
@@ -33,6 +35,8 @@ union ktime; | |||
33 | #define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) | 35 | #define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) |
34 | #define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG) | 36 | #define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG) |
35 | #define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG) | 37 | #define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG) |
38 | #define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITS | FUTEX_PRIVATE_FLAG) | ||
39 | #define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITS | FUTEX_PRIVATE_FLAG) | ||
36 | 40 | ||
37 | /* | 41 | /* |
38 | * Support for robust futexes: the kernel cleans up held futexes at | 42 | * Support for robust futexes: the kernel cleans up held futexes at |
@@ -111,6 +115,12 @@ struct robust_list_head { | |||
111 | */ | 115 | */ |
112 | #define ROBUST_LIST_LIMIT 2048 | 116 | #define ROBUST_LIST_LIMIT 2048 |
113 | 117 | ||
118 | /* | ||
119 | * bitset with all bits set for the FUTEX_xxx_BITSET OPs to request a | ||
120 | * match of any bit. | ||
121 | */ | ||
122 | #define FUTEX_BITSET_MATCH_ANY 0xffffffff | ||
123 | |||
114 | #ifdef __KERNEL__ | 124 | #ifdef __KERNEL__ |
115 | long do_futex(u32 __user *uaddr, int op, u32 val, union ktime *timeout, | 125 | long do_futex(u32 __user *uaddr, int op, u32 val, union ktime *timeout, |
116 | u32 __user *uaddr2, u32 val2, u32 val3); | 126 | u32 __user *uaddr2, u32 val2, u32 val3); |
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index dfbdfb9836f4..421323e5a2d6 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h | |||
@@ -23,6 +23,7 @@ struct restart_block { | |||
23 | u32 *uaddr; | 23 | u32 *uaddr; |
24 | u32 val; | 24 | u32 val; |
25 | u32 flags; | 25 | u32 flags; |
26 | u32 bitset; | ||
26 | u64 time; | 27 | u64 time; |
27 | } futex; | 28 | } futex; |
28 | }; | 29 | }; |
diff --git a/include/linux/tick.h b/include/linux/tick.h index 0fadf95debe1..a881c652f7e9 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h | |||
@@ -39,6 +39,8 @@ enum tick_nohz_mode { | |||
39 | * @idle_calls: Total number of idle calls | 39 | * @idle_calls: Total number of idle calls |
40 | * @idle_sleeps: Number of idle calls, where the sched tick was stopped | 40 | * @idle_sleeps: Number of idle calls, where the sched tick was stopped |
41 | * @idle_entrytime: Time when the idle call was entered | 41 | * @idle_entrytime: Time when the idle call was entered |
42 | * @idle_waketime: Time when the idle was interrupted | ||
43 | * @idle_exittime: Time when the idle state was left | ||
42 | * @idle_sleeptime: Sum of the time slept in idle with sched tick stopped | 44 | * @idle_sleeptime: Sum of the time slept in idle with sched tick stopped |
43 | * @sleep_length: Duration of the current idle sleep | 45 | * @sleep_length: Duration of the current idle sleep |
44 | */ | 46 | */ |
@@ -53,6 +55,8 @@ struct tick_sched { | |||
53 | unsigned long idle_sleeps; | 55 | unsigned long idle_sleeps; |
54 | int idle_active; | 56 | int idle_active; |
55 | ktime_t idle_entrytime; | 57 | ktime_t idle_entrytime; |
58 | ktime_t idle_waketime; | ||
59 | ktime_t idle_exittime; | ||
56 | ktime_t idle_sleeptime; | 60 | ktime_t idle_sleeptime; |
57 | ktime_t idle_lastupdate; | 61 | ktime_t idle_lastupdate; |
58 | ktime_t sleep_length; | 62 | ktime_t sleep_length; |
diff --git a/include/linux/time.h b/include/linux/time.h index b04136d60a2f..ceaab9fff155 100644 --- a/include/linux/time.h +++ b/include/linux/time.h | |||
@@ -122,6 +122,7 @@ extern void monotonic_to_bootbased(struct timespec *ts); | |||
122 | extern struct timespec timespec_trunc(struct timespec t, unsigned gran); | 122 | extern struct timespec timespec_trunc(struct timespec t, unsigned gran); |
123 | extern int timekeeping_is_continuous(void); | 123 | extern int timekeeping_is_continuous(void); |
124 | extern void update_wall_time(void); | 124 | extern void update_wall_time(void); |
125 | extern void update_xtime_cache(u64 nsec); | ||
125 | 126 | ||
126 | /** | 127 | /** |
127 | * timespec_to_ns - Convert timespec to nanoseconds | 128 | * timespec_to_ns - Convert timespec to nanoseconds |
diff --git a/kernel/futex.c b/kernel/futex.c index db9824de8bf0..a6baaec44b8f 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -109,6 +109,9 @@ struct futex_q { | |||
109 | /* Optional priority inheritance state: */ | 109 | /* Optional priority inheritance state: */ |
110 | struct futex_pi_state *pi_state; | 110 | struct futex_pi_state *pi_state; |
111 | struct task_struct *task; | 111 | struct task_struct *task; |
112 | |||
113 | /* Bitset for the optional bitmasked wakeup */ | ||
114 | u32 bitset; | ||
112 | }; | 115 | }; |
113 | 116 | ||
114 | /* | 117 | /* |
@@ -722,7 +725,7 @@ double_lock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2) | |||
722 | * to this virtual address: | 725 | * to this virtual address: |
723 | */ | 726 | */ |
724 | static int futex_wake(u32 __user *uaddr, struct rw_semaphore *fshared, | 727 | static int futex_wake(u32 __user *uaddr, struct rw_semaphore *fshared, |
725 | int nr_wake) | 728 | int nr_wake, u32 bitset) |
726 | { | 729 | { |
727 | struct futex_hash_bucket *hb; | 730 | struct futex_hash_bucket *hb; |
728 | struct futex_q *this, *next; | 731 | struct futex_q *this, *next; |
@@ -730,6 +733,9 @@ static int futex_wake(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
730 | union futex_key key; | 733 | union futex_key key; |
731 | int ret; | 734 | int ret; |
732 | 735 | ||
736 | if (!bitset) | ||
737 | return -EINVAL; | ||
738 | |||
733 | futex_lock_mm(fshared); | 739 | futex_lock_mm(fshared); |
734 | 740 | ||
735 | ret = get_futex_key(uaddr, fshared, &key); | 741 | ret = get_futex_key(uaddr, fshared, &key); |
@@ -746,6 +752,11 @@ static int futex_wake(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
746 | ret = -EINVAL; | 752 | ret = -EINVAL; |
747 | break; | 753 | break; |
748 | } | 754 | } |
755 | |||
756 | /* Check if one of the bits is set in both bitsets */ | ||
757 | if (!(this->bitset & bitset)) | ||
758 | continue; | ||
759 | |||
749 | wake_futex(this); | 760 | wake_futex(this); |
750 | if (++ret >= nr_wake) | 761 | if (++ret >= nr_wake) |
751 | break; | 762 | break; |
@@ -1156,7 +1167,7 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, | |||
1156 | static long futex_wait_restart(struct restart_block *restart); | 1167 | static long futex_wait_restart(struct restart_block *restart); |
1157 | 1168 | ||
1158 | static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, | 1169 | static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, |
1159 | u32 val, ktime_t *abs_time) | 1170 | u32 val, ktime_t *abs_time, u32 bitset) |
1160 | { | 1171 | { |
1161 | struct task_struct *curr = current; | 1172 | struct task_struct *curr = current; |
1162 | DECLARE_WAITQUEUE(wait, curr); | 1173 | DECLARE_WAITQUEUE(wait, curr); |
@@ -1167,7 +1178,11 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1167 | struct hrtimer_sleeper t; | 1178 | struct hrtimer_sleeper t; |
1168 | int rem = 0; | 1179 | int rem = 0; |
1169 | 1180 | ||
1181 | if (!bitset) | ||
1182 | return -EINVAL; | ||
1183 | |||
1170 | q.pi_state = NULL; | 1184 | q.pi_state = NULL; |
1185 | q.bitset = bitset; | ||
1171 | retry: | 1186 | retry: |
1172 | futex_lock_mm(fshared); | 1187 | futex_lock_mm(fshared); |
1173 | 1188 | ||
@@ -1252,6 +1267,8 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1252 | t.timer.expires = *abs_time; | 1267 | t.timer.expires = *abs_time; |
1253 | 1268 | ||
1254 | hrtimer_start(&t.timer, t.timer.expires, HRTIMER_MODE_ABS); | 1269 | hrtimer_start(&t.timer, t.timer.expires, HRTIMER_MODE_ABS); |
1270 | if (!hrtimer_active(&t.timer)) | ||
1271 | t.task = NULL; | ||
1255 | 1272 | ||
1256 | /* | 1273 | /* |
1257 | * the timer could have already expired, in which | 1274 | * the timer could have already expired, in which |
@@ -1293,6 +1310,7 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1293 | restart->futex.uaddr = (u32 *)uaddr; | 1310 | restart->futex.uaddr = (u32 *)uaddr; |
1294 | restart->futex.val = val; | 1311 | restart->futex.val = val; |
1295 | restart->futex.time = abs_time->tv64; | 1312 | restart->futex.time = abs_time->tv64; |
1313 | restart->futex.bitset = bitset; | ||
1296 | restart->futex.flags = 0; | 1314 | restart->futex.flags = 0; |
1297 | 1315 | ||
1298 | if (fshared) | 1316 | if (fshared) |
@@ -1319,7 +1337,8 @@ static long futex_wait_restart(struct restart_block *restart) | |||
1319 | restart->fn = do_no_restart_syscall; | 1337 | restart->fn = do_no_restart_syscall; |
1320 | if (restart->futex.flags & FLAGS_SHARED) | 1338 | if (restart->futex.flags & FLAGS_SHARED) |
1321 | fshared = ¤t->mm->mmap_sem; | 1339 | fshared = ¤t->mm->mmap_sem; |
1322 | return (long)futex_wait(uaddr, fshared, restart->futex.val, &t); | 1340 | return (long)futex_wait(uaddr, fshared, restart->futex.val, &t, |
1341 | restart->futex.bitset); | ||
1323 | } | 1342 | } |
1324 | 1343 | ||
1325 | 1344 | ||
@@ -1535,9 +1554,6 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1535 | owner = rt_mutex_owner(&q.pi_state->pi_mutex); | 1554 | owner = rt_mutex_owner(&q.pi_state->pi_mutex); |
1536 | res = fixup_pi_state_owner(uaddr, &q, owner); | 1555 | res = fixup_pi_state_owner(uaddr, &q, owner); |
1537 | 1556 | ||
1538 | WARN_ON(rt_mutex_owner(&q.pi_state->pi_mutex) != | ||
1539 | owner); | ||
1540 | |||
1541 | /* propagate -EFAULT, if the fixup failed */ | 1557 | /* propagate -EFAULT, if the fixup failed */ |
1542 | if (res) | 1558 | if (res) |
1543 | ret = res; | 1559 | ret = res; |
@@ -1943,7 +1959,8 @@ retry: | |||
1943 | * PI futexes happens in exit_pi_state(): | 1959 | * PI futexes happens in exit_pi_state(): |
1944 | */ | 1960 | */ |
1945 | if (!pi && (uval & FUTEX_WAITERS)) | 1961 | if (!pi && (uval & FUTEX_WAITERS)) |
1946 | futex_wake(uaddr, &curr->mm->mmap_sem, 1); | 1962 | futex_wake(uaddr, &curr->mm->mmap_sem, 1, |
1963 | FUTEX_BITSET_MATCH_ANY); | ||
1947 | } | 1964 | } |
1948 | return 0; | 1965 | return 0; |
1949 | } | 1966 | } |
@@ -2043,10 +2060,14 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, | |||
2043 | 2060 | ||
2044 | switch (cmd) { | 2061 | switch (cmd) { |
2045 | case FUTEX_WAIT: | 2062 | case FUTEX_WAIT: |
2046 | ret = futex_wait(uaddr, fshared, val, timeout); | 2063 | val3 = FUTEX_BITSET_MATCH_ANY; |
2064 | case FUTEX_WAIT_BITSET: | ||
2065 | ret = futex_wait(uaddr, fshared, val, timeout, val3); | ||
2047 | break; | 2066 | break; |
2048 | case FUTEX_WAKE: | 2067 | case FUTEX_WAKE: |
2049 | ret = futex_wake(uaddr, fshared, val); | 2068 | val3 = FUTEX_BITSET_MATCH_ANY; |
2069 | case FUTEX_WAKE_BITSET: | ||
2070 | ret = futex_wake(uaddr, fshared, val, val3); | ||
2050 | break; | 2071 | break; |
2051 | case FUTEX_FD: | 2072 | case FUTEX_FD: |
2052 | /* non-zero val means F_SETOWN(getpid()) & F_SETSIG(val) */ | 2073 | /* non-zero val means F_SETOWN(getpid()) & F_SETSIG(val) */ |
@@ -2086,7 +2107,8 @@ asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val, | |||
2086 | u32 val2 = 0; | 2107 | u32 val2 = 0; |
2087 | int cmd = op & FUTEX_CMD_MASK; | 2108 | int cmd = op & FUTEX_CMD_MASK; |
2088 | 2109 | ||
2089 | if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI)) { | 2110 | if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI || |
2111 | cmd == FUTEX_WAIT_BITSET)) { | ||
2090 | if (copy_from_user(&ts, utime, sizeof(ts)) != 0) | 2112 | if (copy_from_user(&ts, utime, sizeof(ts)) != 0) |
2091 | return -EFAULT; | 2113 | return -EFAULT; |
2092 | if (!timespec_valid(&ts)) | 2114 | if (!timespec_valid(&ts)) |
diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c index 0a43def6fee7..133d558db452 100644 --- a/kernel/futex_compat.c +++ b/kernel/futex_compat.c | |||
@@ -167,7 +167,8 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, | |||
167 | int val2 = 0; | 167 | int val2 = 0; |
168 | int cmd = op & FUTEX_CMD_MASK; | 168 | int cmd = op & FUTEX_CMD_MASK; |
169 | 169 | ||
170 | if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI)) { | 170 | if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI || |
171 | cmd == FUTEX_WAIT_BITSET)) { | ||
171 | if (get_compat_timespec(&ts, utime)) | 172 | if (get_compat_timespec(&ts, utime)) |
172 | return -EFAULT; | 173 | return -EFAULT; |
173 | if (!timespec_valid(&ts)) | 174 | if (!timespec_valid(&ts)) |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index bd5d6b5060bc..1069998fe25f 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -1315,6 +1315,8 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod | |||
1315 | 1315 | ||
1316 | } while (t->task && !signal_pending(current)); | 1316 | } while (t->task && !signal_pending(current)); |
1317 | 1317 | ||
1318 | __set_current_state(TASK_RUNNING); | ||
1319 | |||
1318 | return t->task == NULL; | 1320 | return t->task == NULL; |
1319 | } | 1321 | } |
1320 | 1322 | ||
diff --git a/kernel/time.c b/kernel/time.c index 09d3c45c4da7..4064c0566e77 100644 --- a/kernel/time.c +++ b/kernel/time.c | |||
@@ -129,6 +129,7 @@ static inline void warp_clock(void) | |||
129 | write_seqlock_irq(&xtime_lock); | 129 | write_seqlock_irq(&xtime_lock); |
130 | wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60; | 130 | wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60; |
131 | xtime.tv_sec += sys_tz.tz_minuteswest * 60; | 131 | xtime.tv_sec += sys_tz.tz_minuteswest * 60; |
132 | update_xtime_cache(0); | ||
132 | write_sequnlock_irq(&xtime_lock); | 133 | write_sequnlock_irq(&xtime_lock); |
133 | clock_was_set(); | 134 | clock_was_set(); |
134 | } | 135 | } |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 63f24b550695..88267f0a8471 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -137,6 +137,7 @@ void tick_nohz_update_jiffies(void) | |||
137 | 137 | ||
138 | cpu_clear(cpu, nohz_cpu_mask); | 138 | cpu_clear(cpu, nohz_cpu_mask); |
139 | now = ktime_get(); | 139 | now = ktime_get(); |
140 | ts->idle_waketime = now; | ||
140 | 141 | ||
141 | local_irq_save(flags); | 142 | local_irq_save(flags); |
142 | tick_do_update_jiffies64(now); | 143 | tick_do_update_jiffies64(now); |
@@ -400,6 +401,7 @@ void tick_nohz_restart_sched_tick(void) | |||
400 | * Cancel the scheduled timer and restore the tick | 401 | * Cancel the scheduled timer and restore the tick |
401 | */ | 402 | */ |
402 | ts->tick_stopped = 0; | 403 | ts->tick_stopped = 0; |
404 | ts->idle_exittime = now; | ||
403 | hrtimer_cancel(&ts->sched_timer); | 405 | hrtimer_cancel(&ts->sched_timer); |
404 | ts->sched_timer.expires = ts->idle_tick; | 406 | ts->sched_timer.expires = ts->idle_tick; |
405 | 407 | ||
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 092a2366b5a9..cd5dbc4579c9 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -47,7 +47,7 @@ struct timespec wall_to_monotonic __attribute__ ((aligned (16))); | |||
47 | static unsigned long total_sleep_time; /* seconds */ | 47 | static unsigned long total_sleep_time; /* seconds */ |
48 | 48 | ||
49 | static struct timespec xtime_cache __attribute__ ((aligned (16))); | 49 | static struct timespec xtime_cache __attribute__ ((aligned (16))); |
50 | static inline void update_xtime_cache(u64 nsec) | 50 | void update_xtime_cache(u64 nsec) |
51 | { | 51 | { |
52 | xtime_cache = xtime; | 52 | xtime_cache = xtime; |
53 | timespec_add_ns(&xtime_cache, nsec); | 53 | timespec_add_ns(&xtime_cache, nsec); |
@@ -145,6 +145,7 @@ int do_settimeofday(struct timespec *tv) | |||
145 | 145 | ||
146 | set_normalized_timespec(&xtime, sec, nsec); | 146 | set_normalized_timespec(&xtime, sec, nsec); |
147 | set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); | 147 | set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); |
148 | update_xtime_cache(0); | ||
148 | 149 | ||
149 | clock->error = 0; | 150 | clock->error = 0; |
150 | ntp_clear(); | 151 | ntp_clear(); |
@@ -252,8 +253,8 @@ void __init timekeeping_init(void) | |||
252 | xtime.tv_nsec = 0; | 253 | xtime.tv_nsec = 0; |
253 | set_normalized_timespec(&wall_to_monotonic, | 254 | set_normalized_timespec(&wall_to_monotonic, |
254 | -xtime.tv_sec, -xtime.tv_nsec); | 255 | -xtime.tv_sec, -xtime.tv_nsec); |
256 | update_xtime_cache(0); | ||
255 | total_sleep_time = 0; | 257 | total_sleep_time = 0; |
256 | |||
257 | write_sequnlock_irqrestore(&xtime_lock, flags); | 258 | write_sequnlock_irqrestore(&xtime_lock, flags); |
258 | } | 259 | } |
259 | 260 | ||
@@ -290,6 +291,7 @@ static int timekeeping_resume(struct sys_device *dev) | |||
290 | } | 291 | } |
291 | /* Make sure that we have the correct xtime reference */ | 292 | /* Make sure that we have the correct xtime reference */ |
292 | timespec_add_ns(&xtime, timekeeping_suspend_nsecs); | 293 | timespec_add_ns(&xtime, timekeeping_suspend_nsecs); |
294 | update_xtime_cache(0); | ||
293 | /* re-base the last cycle value */ | 295 | /* re-base the last cycle value */ |
294 | clock->cycle_last = clocksource_read(clock); | 296 | clock->cycle_last = clocksource_read(clock); |
295 | clock->error = 0; | 297 | clock->error = 0; |
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c index 12c5f4cb6b8c..d3d94c1a0fd2 100644 --- a/kernel/time/timer_list.c +++ b/kernel/time/timer_list.c | |||
@@ -166,6 +166,8 @@ static void print_cpu(struct seq_file *m, int cpu, u64 now) | |||
166 | P(idle_calls); | 166 | P(idle_calls); |
167 | P(idle_sleeps); | 167 | P(idle_sleeps); |
168 | P_ns(idle_entrytime); | 168 | P_ns(idle_entrytime); |
169 | P_ns(idle_waketime); | ||
170 | P_ns(idle_exittime); | ||
169 | P_ns(idle_sleeptime); | 171 | P_ns(idle_sleeptime); |
170 | P(last_jiffies); | 172 | P(last_jiffies); |
171 | P(next_jiffies); | 173 | P(next_jiffies); |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 89f4035b526c..0d8a5a4a789d 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -581,7 +581,7 @@ config LATENCYTOP | |||
581 | select STACKTRACE | 581 | select STACKTRACE |
582 | select SCHEDSTATS | 582 | select SCHEDSTATS |
583 | select SCHED_DEBUG | 583 | select SCHED_DEBUG |
584 | depends on X86 || X86_64 | 584 | depends on HAVE_LATENCYTOP_SUPPORT |
585 | help | 585 | help |
586 | Enable this option if you want to use the LatencyTOP tool | 586 | Enable this option if you want to use the LatencyTOP tool |
587 | to find out which userspace is blocking on what kernel operations. | 587 | to find out which userspace is blocking on what kernel operations. |