aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/futex.c42
-rw-r--r--kernel/futex_compat.c3
-rw-r--r--kernel/hrtimer.c2
-rw-r--r--kernel/time.c1
-rw-r--r--kernel/time/tick-sched.c2
-rw-r--r--kernel/time/timekeeping.c6
-rw-r--r--kernel/time/timer_list.c2
7 files changed, 45 insertions, 13 deletions
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 */
724static int futex_wake(u32 __user *uaddr, struct rw_semaphore *fshared, 727static 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,
1156static long futex_wait_restart(struct restart_block *restart); 1167static long futex_wait_restart(struct restart_block *restart);
1157 1168
1158static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, 1169static 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 = &current->mm->mmap_sem; 1339 fshared = &current->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)));
47static unsigned long total_sleep_time; /* seconds */ 47static unsigned long total_sleep_time; /* seconds */
48 48
49static struct timespec xtime_cache __attribute__ ((aligned (16))); 49static struct timespec xtime_cache __attribute__ ((aligned (16)));
50static inline void update_xtime_cache(u64 nsec) 50void 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);