git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
hwmon: (lm85) Clean up detect function
[safe/jmp/linux-2.6]
/
kernel
/
futex.c
diff --git
a/kernel/futex.c
b/kernel/futex.c
index
b911adc
..
fb65e82
100644
(file)
--- a/
kernel/futex.c
+++ b/
kernel/futex.c
@@
-150,7
+150,8
@@
static struct futex_hash_bucket *hash_futex(union futex_key *key)
*/
static inline int match_futex(union futex_key *key1, union futex_key *key2)
{
*/
static inline int match_futex(union futex_key *key1, union futex_key *key2)
{
- return (key1->both.word == key2->both.word
+ return (key1 && key2
+ && key1->both.word == key2->both.word
&& key1->both.ptr == key2->both.ptr
&& key1->both.offset == key2->both.offset);
}
&& key1->both.ptr == key2->both.ptr
&& key1->both.offset == key2->both.offset);
}
@@
-916,8
+917,8
@@
retry:
hb1 = hash_futex(&key1);
hb2 = hash_futex(&key2);
hb1 = hash_futex(&key1);
hb2 = hash_futex(&key2);
- double_lock_hb(hb1, hb2);
retry_private:
retry_private:
+ double_lock_hb(hb1, hb2);
op_ret = futex_atomic_op_inuser(op, uaddr2);
if (unlikely(op_ret < 0)) {
op_ret = futex_atomic_op_inuser(op, uaddr2);
if (unlikely(op_ret < 0)) {
@@
-1028,7
+1029,6
@@
static inline
void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key,
struct futex_hash_bucket *hb)
{
void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key,
struct futex_hash_bucket *hb)
{
- drop_futex_key_refs(&q->key);
get_futex_key_refs(key);
q->key = *key;
get_futex_key_refs(key);
q->key = *key;
@@
-1226,6
+1226,7
@@
retry_private:
*/
if (ret == 1) {
WARN_ON(pi_state);
*/
if (ret == 1) {
WARN_ON(pi_state);
+ drop_count++;
task_count++;
ret = get_futex_value_locked(&curval2, uaddr2);
if (!ret)
task_count++;
ret = get_futex_value_locked(&curval2, uaddr2);
if (!ret)
@@
-1304,6
+1305,7
@@
retry_private:
if (ret == 1) {
/* We got the lock. */
requeue_pi_wake_futex(this, &key2, hb2);
if (ret == 1) {
/* We got the lock. */
requeue_pi_wake_futex(this, &key2, hb2);
+ drop_count++;
continue;
} else if (ret) {
/* -EDEADLK */
continue;
} else if (ret) {
/* -EDEADLK */
@@
-1791,6
+1793,7
@@
static int futex_wait(u32 __user *uaddr, int fshared,
current->timer_slack_ns);
}
current->timer_slack_ns);
}
+retry:
/* Prepare to wait on uaddr. */
ret = futex_wait_setup(uaddr, val, fshared, &q, &hb);
if (ret)
/* Prepare to wait on uaddr. */
ret = futex_wait_setup(uaddr, val, fshared, &q, &hb);
if (ret)
@@
-1808,9
+1811,14
@@
static int futex_wait(u32 __user *uaddr, int fshared,
goto out_put_key;
/*
goto out_put_key;
/*
- * We expect signal_pending(current), but
another thread may
- *
have handled it for us already
.
+ * We expect signal_pending(current), but
we might be the
+ *
victim of a spurious wakeup as well
.
*/
*/
+ if (!signal_pending(current)) {
+ put_futex_key(fshared, &q.key);
+ goto retry;
+ }
+
ret = -ERESTARTSYS;
if (!abs_time)
goto out_put_key;
ret = -ERESTARTSYS;
if (!abs_time)
goto out_put_key;
@@
-2117,11
+2125,12
@@
int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
* Unqueue the futex_q and determine which it was.
*/
plist_del(&q->list, &q->list.plist);
* Unqueue the futex_q and determine which it was.
*/
plist_del(&q->list, &q->list.plist);
- drop_futex_key_refs(&q->key);
+ /* Handle spurious wakeups gracefully */
+ ret = -EWOULDBLOCK;
if (timeout && !timeout->task)
ret = -ETIMEDOUT;
if (timeout && !timeout->task)
ret = -ETIMEDOUT;
- else
+ else
if (signal_pending(current))
ret = -ERESTARTNOINTR;
}
return ret;
ret = -ERESTARTNOINTR;
}
return ret;