aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/futex.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/futex.c')
-rw-r--r--kernel/futex.c122
1 files changed, 86 insertions, 36 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index cf0c8e21d1ab..c2b2e0b83abf 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -415,15 +415,15 @@ out_unlock:
415 */ 415 */
416void exit_pi_state_list(struct task_struct *curr) 416void exit_pi_state_list(struct task_struct *curr)
417{ 417{
418 struct futex_hash_bucket *hb;
419 struct list_head *next, *head = &curr->pi_state_list; 418 struct list_head *next, *head = &curr->pi_state_list;
420 struct futex_pi_state *pi_state; 419 struct futex_pi_state *pi_state;
420 struct futex_hash_bucket *hb;
421 union futex_key key; 421 union futex_key key;
422 422
423 /* 423 /*
424 * We are a ZOMBIE and nobody can enqueue itself on 424 * We are a ZOMBIE and nobody can enqueue itself on
425 * pi_state_list anymore, but we have to be careful 425 * pi_state_list anymore, but we have to be careful
426 * versus waiters unqueueing themselfs 426 * versus waiters unqueueing themselves:
427 */ 427 */
428 spin_lock_irq(&curr->pi_lock); 428 spin_lock_irq(&curr->pi_lock);
429 while (!list_empty(head)) { 429 while (!list_empty(head)) {
@@ -431,21 +431,24 @@ void exit_pi_state_list(struct task_struct *curr)
431 next = head->next; 431 next = head->next;
432 pi_state = list_entry(next, struct futex_pi_state, list); 432 pi_state = list_entry(next, struct futex_pi_state, list);
433 key = pi_state->key; 433 key = pi_state->key;
434 hb = hash_futex(&key);
434 spin_unlock_irq(&curr->pi_lock); 435 spin_unlock_irq(&curr->pi_lock);
435 436
436 hb = hash_futex(&key);
437 spin_lock(&hb->lock); 437 spin_lock(&hb->lock);
438 438
439 spin_lock_irq(&curr->pi_lock); 439 spin_lock_irq(&curr->pi_lock);
440 /*
441 * We dropped the pi-lock, so re-check whether this
442 * task still owns the PI-state:
443 */
440 if (head->next != next) { 444 if (head->next != next) {
441 spin_unlock(&hb->lock); 445 spin_unlock(&hb->lock);
442 continue; 446 continue;
443 } 447 }
444 448
445 list_del_init(&pi_state->list);
446
447 WARN_ON(pi_state->owner != curr); 449 WARN_ON(pi_state->owner != curr);
448 450 WARN_ON(list_empty(&pi_state->list));
451 list_del_init(&pi_state->list);
449 pi_state->owner = NULL; 452 pi_state->owner = NULL;
450 spin_unlock_irq(&curr->pi_lock); 453 spin_unlock_irq(&curr->pi_lock);
451 454
@@ -470,7 +473,7 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, struct futex_q *me)
470 head = &hb->chain; 473 head = &hb->chain;
471 474
472 list_for_each_entry_safe(this, next, head, list) { 475 list_for_each_entry_safe(this, next, head, list) {
473 if (match_futex (&this->key, &me->key)) { 476 if (match_futex(&this->key, &me->key)) {
474 /* 477 /*
475 * Another waiter already exists - bump up 478 * Another waiter already exists - bump up
476 * the refcount and return its pi_state: 479 * the refcount and return its pi_state:
@@ -482,6 +485,8 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, struct futex_q *me)
482 if (unlikely(!pi_state)) 485 if (unlikely(!pi_state))
483 return -EINVAL; 486 return -EINVAL;
484 487
488 WARN_ON(!atomic_read(&pi_state->refcount));
489
485 atomic_inc(&pi_state->refcount); 490 atomic_inc(&pi_state->refcount);
486 me->pi_state = pi_state; 491 me->pi_state = pi_state;
487 492
@@ -490,10 +495,13 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, struct futex_q *me)
490 } 495 }
491 496
492 /* 497 /*
493 * We are the first waiter - try to look up the real owner and 498 * We are the first waiter - try to look up the real owner and attach
494 * attach the new pi_state to it: 499 * the new pi_state to it, but bail out when the owner died bit is set
500 * and TID = 0:
495 */ 501 */
496 pid = uval & FUTEX_TID_MASK; 502 pid = uval & FUTEX_TID_MASK;
503 if (!pid && (uval & FUTEX_OWNER_DIED))
504 return -ESRCH;
497 p = futex_find_get_task(pid); 505 p = futex_find_get_task(pid);
498 if (!p) 506 if (!p)
499 return -ESRCH; 507 return -ESRCH;
@@ -510,6 +518,7 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, struct futex_q *me)
510 pi_state->key = me->key; 518 pi_state->key = me->key;
511 519
512 spin_lock_irq(&p->pi_lock); 520 spin_lock_irq(&p->pi_lock);
521 WARN_ON(!list_empty(&pi_state->list));
513 list_add(&pi_state->list, &p->pi_state_list); 522 list_add(&pi_state->list, &p->pi_state_list);
514 pi_state->owner = p; 523 pi_state->owner = p;
515 spin_unlock_irq(&p->pi_lock); 524 spin_unlock_irq(&p->pi_lock);
@@ -573,20 +582,29 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
573 * kept enabled while there is PI state around. We must also 582 * kept enabled while there is PI state around. We must also
574 * preserve the owner died bit.) 583 * preserve the owner died bit.)
575 */ 584 */
576 newval = (uval & FUTEX_OWNER_DIED) | FUTEX_WAITERS | new_owner->pid; 585 if (!(uval & FUTEX_OWNER_DIED)) {
586 newval = FUTEX_WAITERS | new_owner->pid;
577 587
578 inc_preempt_count(); 588 inc_preempt_count();
579 curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); 589 curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval);
580 dec_preempt_count(); 590 dec_preempt_count();
591 if (curval == -EFAULT)
592 return -EFAULT;
593 if (curval != uval)
594 return -EINVAL;
595 }
581 596
582 if (curval == -EFAULT) 597 spin_lock_irq(&pi_state->owner->pi_lock);
583 return -EFAULT; 598 WARN_ON(list_empty(&pi_state->list));
584 if (curval != uval) 599 list_del_init(&pi_state->list);
585 return -EINVAL; 600 spin_unlock_irq(&pi_state->owner->pi_lock);
586 601
587 list_del_init(&pi_state->owner->pi_state_list); 602 spin_lock_irq(&new_owner->pi_lock);
603 WARN_ON(!list_empty(&pi_state->list));
588 list_add(&pi_state->list, &new_owner->pi_state_list); 604 list_add(&pi_state->list, &new_owner->pi_state_list);
589 pi_state->owner = new_owner; 605 pi_state->owner = new_owner;
606 spin_unlock_irq(&new_owner->pi_lock);
607
590 rt_mutex_unlock(&pi_state->pi_mutex); 608 rt_mutex_unlock(&pi_state->pi_mutex);
591 609
592 return 0; 610 return 0;
@@ -930,6 +948,7 @@ static int unqueue_me(struct futex_q *q)
930 /* In the common case we don't take the spinlock, which is nice. */ 948 /* In the common case we don't take the spinlock, which is nice. */
931 retry: 949 retry:
932 lock_ptr = q->lock_ptr; 950 lock_ptr = q->lock_ptr;
951 barrier();
933 if (lock_ptr != 0) { 952 if (lock_ptr != 0) {
934 spin_lock(lock_ptr); 953 spin_lock(lock_ptr);
935 /* 954 /*
@@ -1236,6 +1255,7 @@ static int do_futex_lock_pi(u32 __user *uaddr, int detect, int trylock,
1236 /* Owner died? */ 1255 /* Owner died? */
1237 if (q.pi_state->owner != NULL) { 1256 if (q.pi_state->owner != NULL) {
1238 spin_lock_irq(&q.pi_state->owner->pi_lock); 1257 spin_lock_irq(&q.pi_state->owner->pi_lock);
1258 WARN_ON(list_empty(&q.pi_state->list));
1239 list_del_init(&q.pi_state->list); 1259 list_del_init(&q.pi_state->list);
1240 spin_unlock_irq(&q.pi_state->owner->pi_lock); 1260 spin_unlock_irq(&q.pi_state->owner->pi_lock);
1241 } else 1261 } else
@@ -1244,6 +1264,7 @@ static int do_futex_lock_pi(u32 __user *uaddr, int detect, int trylock,
1244 q.pi_state->owner = current; 1264 q.pi_state->owner = current;
1245 1265
1246 spin_lock_irq(&current->pi_lock); 1266 spin_lock_irq(&current->pi_lock);
1267 WARN_ON(!list_empty(&q.pi_state->list));
1247 list_add(&q.pi_state->list, &current->pi_state_list); 1268 list_add(&q.pi_state->list, &current->pi_state_list);
1248 spin_unlock_irq(&current->pi_lock); 1269 spin_unlock_irq(&current->pi_lock);
1249 1270
@@ -1427,9 +1448,11 @@ retry_locked:
1427 * again. If it succeeds then we can return without waking 1448 * again. If it succeeds then we can return without waking
1428 * anyone else up: 1449 * anyone else up:
1429 */ 1450 */
1430 inc_preempt_count(); 1451 if (!(uval & FUTEX_OWNER_DIED)) {
1431 uval = futex_atomic_cmpxchg_inatomic(uaddr, current->pid, 0); 1452 inc_preempt_count();
1432 dec_preempt_count(); 1453 uval = futex_atomic_cmpxchg_inatomic(uaddr, current->pid, 0);
1454 dec_preempt_count();
1455 }
1433 1456
1434 if (unlikely(uval == -EFAULT)) 1457 if (unlikely(uval == -EFAULT))
1435 goto pi_faulted; 1458 goto pi_faulted;
@@ -1462,9 +1485,11 @@ retry_locked:
1462 /* 1485 /*
1463 * No waiters - kernel unlocks the futex: 1486 * No waiters - kernel unlocks the futex:
1464 */ 1487 */
1465 ret = unlock_futex_pi(uaddr, uval); 1488 if (!(uval & FUTEX_OWNER_DIED)) {
1466 if (ret == -EFAULT) 1489 ret = unlock_futex_pi(uaddr, uval);
1467 goto pi_faulted; 1490 if (ret == -EFAULT)
1491 goto pi_faulted;
1492 }
1468 1493
1469out_unlock: 1494out_unlock:
1470 spin_unlock(&hb->lock); 1495 spin_unlock(&hb->lock);
@@ -1683,9 +1708,9 @@ err_unlock:
1683 * Process a futex-list entry, check whether it's owned by the 1708 * Process a futex-list entry, check whether it's owned by the
1684 * dying task, and do notification if so: 1709 * dying task, and do notification if so:
1685 */ 1710 */
1686int handle_futex_death(u32 __user *uaddr, struct task_struct *curr) 1711int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi)
1687{ 1712{
1688 u32 uval, nval; 1713 u32 uval, nval, mval;
1689 1714
1690retry: 1715retry:
1691 if (get_user(uval, uaddr)) 1716 if (get_user(uval, uaddr))
@@ -1702,21 +1727,45 @@ retry:
1702 * thread-death.) The rest of the cleanup is done in 1727 * thread-death.) The rest of the cleanup is done in
1703 * userspace. 1728 * userspace.
1704 */ 1729 */
1705 nval = futex_atomic_cmpxchg_inatomic(uaddr, uval, 1730 mval = (uval & FUTEX_WAITERS) | FUTEX_OWNER_DIED;
1706 uval | FUTEX_OWNER_DIED); 1731 nval = futex_atomic_cmpxchg_inatomic(uaddr, uval, mval);
1732
1707 if (nval == -EFAULT) 1733 if (nval == -EFAULT)
1708 return -1; 1734 return -1;
1709 1735
1710 if (nval != uval) 1736 if (nval != uval)
1711 goto retry; 1737 goto retry;
1712 1738
1713 if (uval & FUTEX_WAITERS) 1739 /*
1714 futex_wake(uaddr, 1); 1740 * Wake robust non-PI futexes here. The wakeup of
1741 * PI futexes happens in exit_pi_state():
1742 */
1743 if (!pi) {
1744 if (uval & FUTEX_WAITERS)
1745 futex_wake(uaddr, 1);
1746 }
1715 } 1747 }
1716 return 0; 1748 return 0;
1717} 1749}
1718 1750
1719/* 1751/*
1752 * Fetch a robust-list pointer. Bit 0 signals PI futexes:
1753 */
1754static inline int fetch_robust_entry(struct robust_list __user **entry,
1755 struct robust_list __user **head, int *pi)
1756{
1757 unsigned long uentry;
1758
1759 if (get_user(uentry, (unsigned long *)head))
1760 return -EFAULT;
1761
1762 *entry = (void *)(uentry & ~1UL);
1763 *pi = uentry & 1;
1764
1765 return 0;
1766}
1767
1768/*
1720 * Walk curr->robust_list (very carefully, it's a userspace list!) 1769 * Walk curr->robust_list (very carefully, it's a userspace list!)
1721 * and mark any locks found there dead, and notify any waiters. 1770 * and mark any locks found there dead, and notify any waiters.
1722 * 1771 *
@@ -1726,14 +1775,14 @@ void exit_robust_list(struct task_struct *curr)
1726{ 1775{
1727 struct robust_list_head __user *head = curr->robust_list; 1776 struct robust_list_head __user *head = curr->robust_list;
1728 struct robust_list __user *entry, *pending; 1777 struct robust_list __user *entry, *pending;
1729 unsigned int limit = ROBUST_LIST_LIMIT; 1778 unsigned int limit = ROBUST_LIST_LIMIT, pi, pip;
1730 unsigned long futex_offset; 1779 unsigned long futex_offset;
1731 1780
1732 /* 1781 /*
1733 * Fetch the list head (which was registered earlier, via 1782 * Fetch the list head (which was registered earlier, via
1734 * sys_set_robust_list()): 1783 * sys_set_robust_list()):
1735 */ 1784 */
1736 if (get_user(entry, &head->list.next)) 1785 if (fetch_robust_entry(&entry, &head->list.next, &pi))
1737 return; 1786 return;
1738 /* 1787 /*
1739 * Fetch the relative futex offset: 1788 * Fetch the relative futex offset:
@@ -1744,10 +1793,11 @@ void exit_robust_list(struct task_struct *curr)
1744 * Fetch any possibly pending lock-add first, and handle it 1793 * Fetch any possibly pending lock-add first, and handle it
1745 * if it exists: 1794 * if it exists:
1746 */ 1795 */
1747 if (get_user(pending, &head->list_op_pending)) 1796 if (fetch_robust_entry(&pending, &head->list_op_pending, &pip))
1748 return; 1797 return;
1798
1749 if (pending) 1799 if (pending)
1750 handle_futex_death((void *)pending + futex_offset, curr); 1800 handle_futex_death((void *)pending + futex_offset, curr, pip);
1751 1801
1752 while (entry != &head->list) { 1802 while (entry != &head->list) {
1753 /* 1803 /*
@@ -1756,12 +1806,12 @@ void exit_robust_list(struct task_struct *curr)
1756 */ 1806 */
1757 if (entry != pending) 1807 if (entry != pending)
1758 if (handle_futex_death((void *)entry + futex_offset, 1808 if (handle_futex_death((void *)entry + futex_offset,
1759 curr)) 1809 curr, pi))
1760 return; 1810 return;
1761 /* 1811 /*
1762 * Fetch the next entry in the list: 1812 * Fetch the next entry in the list:
1763 */ 1813 */
1764 if (get_user(entry, &entry->next)) 1814 if (fetch_robust_entry(&entry, &entry->next, &pi))
1765 return; 1815 return;
1766 /* 1816 /*
1767 * Avoid excessively long or circular lists: 1817 * Avoid excessively long or circular lists: