Merge branch 'core-locking-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 20 Mar 2012 00:11:15 +0000 (17:11 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 20 Mar 2012 00:11:15 +0000 (17:11 -0700)
Pull core/locking changes for v3.4 from Ingo Molnar

* 'core-locking-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  futex: Simplify return logic
  futex: Cover all PI opcodes with cmpxchg enabled check

1  2 
kernel/futex.c

diff --combined kernel/futex.c
index 1614be20173dcb19ef45e65fa25d07f8d3c65194,2364c99dd982c4f6cc2cd6e91877147a6921e4d2..72efa1e4359af576a9cb96ed0ffb40461bd6ef1a
@@@ -314,29 -314,17 +314,29 @@@ again
  #endif
  
        lock_page(page_head);
 +
 +      /*
 +       * If page_head->mapping is NULL, then it cannot be a PageAnon
 +       * page; but it might be the ZERO_PAGE or in the gate area or
 +       * in a special mapping (all cases which we are happy to fail);
 +       * or it may have been a good file page when get_user_pages_fast
 +       * found it, but truncated or holepunched or subjected to
 +       * invalidate_complete_page2 before we got the page lock (also
 +       * cases which we are happy to fail).  And we hold a reference,
 +       * so refcount care in invalidate_complete_page's remove_mapping
 +       * prevents drop_caches from setting mapping to NULL beneath us.
 +       *
 +       * The case we do have to guard against is when memory pressure made
 +       * shmem_writepage move it from filecache to swapcache beneath us:
 +       * an unlikely race, but we do need to retry for page_head->mapping.
 +       */
        if (!page_head->mapping) {
 +              int shmem_swizzled = PageSwapCache(page_head);
                unlock_page(page_head);
                put_page(page_head);
 -              /*
 -              * ZERO_PAGE pages don't have a mapping. Avoid a busy loop
 -              * trying to find one. RW mapping would have COW'd (and thus
 -              * have a mapping) so this page is RO and won't ever change.
 -              */
 -              if ((page_head == ZERO_PAGE(address)))
 -                      return -EFAULT;
 -              goto again;
 +              if (shmem_swizzled)
 +                      goto again;
 +              return -EFAULT;
        }
  
        /*
@@@ -2628,7 -2616,7 +2628,7 @@@ void exit_robust_list(struct task_struc
  long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
                u32 __user *uaddr2, u32 val2, u32 val3)
  {
-       int ret = -ENOSYS, cmd = op & FUTEX_CMD_MASK;
+       int cmd = op & FUTEX_CMD_MASK;
        unsigned int flags = 0;
  
        if (!(op & FUTEX_PRIVATE_FLAG))
                        return -ENOSYS;
        }
  
+       switch (cmd) {
+       case FUTEX_LOCK_PI:
+       case FUTEX_UNLOCK_PI:
+       case FUTEX_TRYLOCK_PI:
+       case FUTEX_WAIT_REQUEUE_PI:
+       case FUTEX_CMP_REQUEUE_PI:
+               if (!futex_cmpxchg_enabled)
+                       return -ENOSYS;
+       }
        switch (cmd) {
        case FUTEX_WAIT:
                val3 = FUTEX_BITSET_MATCH_ANY;
        case FUTEX_WAIT_BITSET:
-               ret = futex_wait(uaddr, flags, val, timeout, val3);
-               break;
+               return futex_wait(uaddr, flags, val, timeout, val3);
        case FUTEX_WAKE:
                val3 = FUTEX_BITSET_MATCH_ANY;
        case FUTEX_WAKE_BITSET:
-               ret = futex_wake(uaddr, flags, val, val3);
-               break;
+               return futex_wake(uaddr, flags, val, val3);
        case FUTEX_REQUEUE:
-               ret = futex_requeue(uaddr, flags, uaddr2, val, val2, NULL, 0);
-               break;
+               return futex_requeue(uaddr, flags, uaddr2, val, val2, NULL, 0);
        case FUTEX_CMP_REQUEUE:
-               ret = futex_requeue(uaddr, flags, uaddr2, val, val2, &val3, 0);
-               break;
+               return futex_requeue(uaddr, flags, uaddr2, val, val2, &val3, 0);
        case FUTEX_WAKE_OP:
-               ret = futex_wake_op(uaddr, flags, uaddr2, val, val2, val3);
-               break;
+               return futex_wake_op(uaddr, flags, uaddr2, val, val2, val3);
        case FUTEX_LOCK_PI:
-               if (futex_cmpxchg_enabled)
-                       ret = futex_lock_pi(uaddr, flags, val, timeout, 0);
-               break;
+               return futex_lock_pi(uaddr, flags, val, timeout, 0);
        case FUTEX_UNLOCK_PI:
-               if (futex_cmpxchg_enabled)
-                       ret = futex_unlock_pi(uaddr, flags);
-               break;
+               return futex_unlock_pi(uaddr, flags);
        case FUTEX_TRYLOCK_PI:
-               if (futex_cmpxchg_enabled)
-                       ret = futex_lock_pi(uaddr, flags, 0, timeout, 1);
-               break;
+               return futex_lock_pi(uaddr, flags, 0, timeout, 1);
        case FUTEX_WAIT_REQUEUE_PI:
                val3 = FUTEX_BITSET_MATCH_ANY;
-               ret = futex_wait_requeue_pi(uaddr, flags, val, timeout, val3,
-                                           uaddr2);
-               break;
+               return futex_wait_requeue_pi(uaddr, flags, val, timeout, val3,
+                                            uaddr2);
        case FUTEX_CMP_REQUEUE_PI:
-               ret = futex_requeue(uaddr, flags, uaddr2, val, val2, &val3, 1);
-               break;
-       default:
-               ret = -ENOSYS;
+               return futex_requeue(uaddr, flags, uaddr2, val, val2, &val3, 1);
        }
-       return ret;
+       return -ENOSYS;
  }