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

+68 -17
+3
arch/x86/Kconfig
··· 44 44 config STACKTRACE_SUPPORT 45 45 def_bool y 46 46 47 + config HAVE_LATENCYTOP_SUPPORT 48 + def_bool y 49 + 47 50 config SEMAPHORE_SLEEPERS 48 51 def_bool y 49 52
+3 -3
include/asm-x86/futex.h
··· 30 30 "1: movl %2, %0\n \ 31 31 movl %0, %3\n" \ 32 32 insn "\n" \ 33 - "2: " LOCK_PREFIX "cmpxchgl %3, %2\n \ 33 + "2: lock; cmpxchgl %3, %2\n \ 34 34 jnz 1b\n \ 35 35 3: .section .fixup,\"ax\"\n \ 36 36 4: mov %5, %1\n \ ··· 72 72 __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg); 73 73 break; 74 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 76 uaddr, oparg); 77 77 break; 78 78 case FUTEX_OP_OR: ··· 111 111 return -EFAULT; 112 112 113 113 __asm__ __volatile__( 114 - "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n" 115 114 115 + "1: lock; cmpxchgl %3, %1 \n" 116 116 "2: .section .fixup, \"ax\" \n" 117 117 "3: mov %2, %0 \n" 118 118 " jmp 2b \n"
+10
include/linux/futex.h
··· 21 21 #define FUTEX_LOCK_PI 6 22 22 #define FUTEX_UNLOCK_PI 7 23 23 #define FUTEX_TRYLOCK_PI 8 24 + #define FUTEX_WAIT_BITSET 9 25 + #define FUTEX_WAKE_BITSET 10 24 26 25 27 #define FUTEX_PRIVATE_FLAG 128 26 28 #define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG ··· 35 33 #define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) 36 34 #define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG) 37 35 #define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG) 36 + #define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITS | FUTEX_PRIVATE_FLAG) 37 + #define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITS | FUTEX_PRIVATE_FLAG) 38 38 39 39 /* 40 40 * Support for robust futexes: the kernel cleans up held futexes at ··· 114 110 * (Not worth introducing an rlimit for it) 115 111 */ 116 112 #define ROBUST_LIST_LIMIT 2048 113 + 114 + /* 115 + * bitset with all bits set for the FUTEX_xxx_BITSET OPs to request a 116 + * match of any bit. 117 + */ 118 + #define FUTEX_BITSET_MATCH_ANY 0xffffffff 117 119 118 120 #ifdef __KERNEL__ 119 121 long do_futex(u32 __user *uaddr, int op, u32 val, union ktime *timeout,
+1
include/linux/thread_info.h
··· 23 23 u32 *uaddr; 24 24 u32 val; 25 25 u32 flags; 26 + u32 bitset; 26 27 u64 time; 27 28 } futex; 28 29 };
+4
include/linux/tick.h
··· 39 39 * @idle_calls: Total number of idle calls 40 40 * @idle_sleeps: Number of idle calls, where the sched tick was stopped 41 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 44 * @idle_sleeptime: Sum of the time slept in idle with sched tick stopped 43 45 * @sleep_length: Duration of the current idle sleep 44 46 */ ··· 55 53 unsigned long idle_sleeps; 56 54 int idle_active; 57 55 ktime_t idle_entrytime; 56 + ktime_t idle_waketime; 57 + ktime_t idle_exittime; 58 58 ktime_t idle_sleeptime; 59 59 ktime_t idle_lastupdate; 60 60 ktime_t sleep_length;
+1
include/linux/time.h
··· 122 122 extern struct timespec timespec_trunc(struct timespec t, unsigned gran); 123 123 extern int timekeeping_is_continuous(void); 124 124 extern void update_wall_time(void); 125 + extern void update_xtime_cache(u64 nsec); 125 126 126 127 /** 127 128 * timespec_to_ns - Convert timespec to nanoseconds
+32 -10
kernel/futex.c
··· 109 109 /* Optional priority inheritance state: */ 110 110 struct futex_pi_state *pi_state; 111 111 struct task_struct *task; 112 + 113 + /* Bitset for the optional bitmasked wakeup */ 114 + u32 bitset; 112 115 }; 113 116 114 117 /* ··· 725 722 * to this virtual address: 726 723 */ 727 724 static int futex_wake(u32 __user *uaddr, struct rw_semaphore *fshared, 728 - int nr_wake) 725 + int nr_wake, u32 bitset) 729 726 { 730 727 struct futex_hash_bucket *hb; 731 728 struct futex_q *this, *next; 732 729 struct plist_head *head; 733 730 union futex_key key; 734 731 int ret; 732 + 733 + if (!bitset) 734 + return -EINVAL; 735 735 736 736 futex_lock_mm(fshared); 737 737 ··· 752 746 ret = -EINVAL; 753 747 break; 754 748 } 749 + 750 + /* Check if one of the bits is set in both bitsets */ 751 + if (!(this->bitset & bitset)) 752 + continue; 753 + 755 754 wake_futex(this); 756 755 if (++ret >= nr_wake) 757 756 break; ··· 1167 1156 static long futex_wait_restart(struct restart_block *restart); 1168 1157 1169 1158 static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, 1170 - u32 val, ktime_t *abs_time) 1159 + u32 val, ktime_t *abs_time, u32 bitset) 1171 1160 { 1172 1161 struct task_struct *curr = current; 1173 1162 DECLARE_WAITQUEUE(wait, curr); ··· 1178 1167 struct hrtimer_sleeper t; 1179 1168 int rem = 0; 1180 1169 1170 + if (!bitset) 1171 + return -EINVAL; 1172 + 1181 1173 q.pi_state = NULL; 1174 + q.bitset = bitset; 1182 1175 retry: 1183 1176 futex_lock_mm(fshared); 1184 1177 ··· 1267 1252 t.timer.expires = *abs_time; 1268 1253 1269 1254 hrtimer_start(&t.timer, t.timer.expires, HRTIMER_MODE_ABS); 1255 + if (!hrtimer_active(&t.timer)) 1256 + t.task = NULL; 1270 1257 1271 1258 /* 1272 1259 * the timer could have already expired, in which ··· 1310 1293 restart->futex.uaddr = (u32 *)uaddr; 1311 1294 restart->futex.val = val; 1312 1295 restart->futex.time = abs_time->tv64; 1296 + restart->futex.bitset = bitset; 1313 1297 restart->futex.flags = 0; 1314 1298 1315 1299 if (fshared) ··· 1337 1319 restart->fn = do_no_restart_syscall; 1338 1320 if (restart->futex.flags & FLAGS_SHARED) 1339 1321 fshared = &current->mm->mmap_sem; 1340 - return (long)futex_wait(uaddr, fshared, restart->futex.val, &t); 1322 + return (long)futex_wait(uaddr, fshared, restart->futex.val, &t, 1323 + restart->futex.bitset); 1341 1324 } 1342 1325 1343 1326 ··· 1553 1534 1554 1535 owner = rt_mutex_owner(&q.pi_state->pi_mutex); 1555 1536 res = fixup_pi_state_owner(uaddr, &q, owner); 1556 - 1557 - WARN_ON(rt_mutex_owner(&q.pi_state->pi_mutex) != 1558 - owner); 1559 1537 1560 1538 /* propagate -EFAULT, if the fixup failed */ 1561 1539 if (res) ··· 1959 1943 * PI futexes happens in exit_pi_state(): 1960 1944 */ 1961 1945 if (!pi && (uval & FUTEX_WAITERS)) 1962 - futex_wake(uaddr, &curr->mm->mmap_sem, 1); 1946 + futex_wake(uaddr, &curr->mm->mmap_sem, 1, 1947 + FUTEX_BITSET_MATCH_ANY); 1963 1948 } 1964 1949 return 0; 1965 1950 } ··· 2060 2043 2061 2044 switch (cmd) { 2062 2045 case FUTEX_WAIT: 2063 - ret = futex_wait(uaddr, fshared, val, timeout); 2046 + val3 = FUTEX_BITSET_MATCH_ANY; 2047 + case FUTEX_WAIT_BITSET: 2048 + ret = futex_wait(uaddr, fshared, val, timeout, val3); 2064 2049 break; 2065 2050 case FUTEX_WAKE: 2066 - ret = futex_wake(uaddr, fshared, val); 2051 + val3 = FUTEX_BITSET_MATCH_ANY; 2052 + case FUTEX_WAKE_BITSET: 2053 + ret = futex_wake(uaddr, fshared, val, val3); 2067 2054 break; 2068 2055 case FUTEX_FD: 2069 2056 /* non-zero val means F_SETOWN(getpid()) & F_SETSIG(val) */ ··· 2107 2086 u32 val2 = 0; 2108 2087 int cmd = op & FUTEX_CMD_MASK; 2109 2088 2110 - if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI)) { 2089 + if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI || 2090 + cmd == FUTEX_WAIT_BITSET)) { 2111 2091 if (copy_from_user(&ts, utime, sizeof(ts)) != 0) 2112 2092 return -EFAULT; 2113 2093 if (!timespec_valid(&ts))
+2 -1
kernel/futex_compat.c
··· 167 167 int val2 = 0; 168 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 172 if (get_compat_timespec(&ts, utime)) 172 173 return -EFAULT; 173 174 if (!timespec_valid(&ts))
+2
kernel/hrtimer.c
··· 1315 1315 1316 1316 } while (t->task && !signal_pending(current)); 1317 1317 1318 + __set_current_state(TASK_RUNNING); 1319 + 1318 1320 return t->task == NULL; 1319 1321 } 1320 1322
+1
kernel/time.c
··· 129 129 write_seqlock_irq(&xtime_lock); 130 130 wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60; 131 131 xtime.tv_sec += sys_tz.tz_minuteswest * 60; 132 + update_xtime_cache(0); 132 133 write_sequnlock_irq(&xtime_lock); 133 134 clock_was_set(); 134 135 }
+2
kernel/time/tick-sched.c
··· 137 137 138 138 cpu_clear(cpu, nohz_cpu_mask); 139 139 now = ktime_get(); 140 + ts->idle_waketime = now; 140 141 141 142 local_irq_save(flags); 142 143 tick_do_update_jiffies64(now); ··· 401 400 * Cancel the scheduled timer and restore the tick 402 401 */ 403 402 ts->tick_stopped = 0; 403 + ts->idle_exittime = now; 404 404 hrtimer_cancel(&ts->sched_timer); 405 405 ts->sched_timer.expires = ts->idle_tick; 406 406
+4 -2
kernel/time/timekeeping.c
··· 47 47 static unsigned long total_sleep_time; /* seconds */ 48 48 49 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 52 xtime_cache = xtime; 53 53 timespec_add_ns(&xtime_cache, nsec); ··· 145 145 146 146 set_normalized_timespec(&xtime, sec, nsec); 147 147 set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); 148 + update_xtime_cache(0); 148 149 149 150 clock->error = 0; 150 151 ntp_clear(); ··· 253 252 xtime.tv_nsec = 0; 254 253 set_normalized_timespec(&wall_to_monotonic, 255 254 -xtime.tv_sec, -xtime.tv_nsec); 255 + update_xtime_cache(0); 256 256 total_sleep_time = 0; 257 - 258 257 write_sequnlock_irqrestore(&xtime_lock, flags); 259 258 } 260 259 ··· 291 290 } 292 291 /* Make sure that we have the correct xtime reference */ 293 292 timespec_add_ns(&xtime, timekeeping_suspend_nsecs); 293 + update_xtime_cache(0); 294 294 /* re-base the last cycle value */ 295 295 clock->cycle_last = clocksource_read(clock); 296 296 clock->error = 0;
+2
kernel/time/timer_list.c
··· 166 166 P(idle_calls); 167 167 P(idle_sleeps); 168 168 P_ns(idle_entrytime); 169 + P_ns(idle_waketime); 170 + P_ns(idle_exittime); 169 171 P_ns(idle_sleeptime); 170 172 P(last_jiffies); 171 173 P(next_jiffies);
+1 -1
lib/Kconfig.debug
··· 581 581 select STACKTRACE 582 582 select SCHEDSTATS 583 583 select SCHED_DEBUG 584 - depends on X86 || X86_64 584 + depends on HAVE_LATENCYTOP_SUPPORT 585 585 help 586 586 Enable this option if you want to use the LatencyTOP tool 587 587 to find out which userspace is blocking on what kernel operations.