Merge branch 'core-locking-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 2 Jul 2013 23:07:52 +0000 (16:07 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 2 Jul 2013 23:07:52 +0000 (16:07 -0700)
Pull locking changes from Ingo Molnar:
 "Four miscellanous standalone fixes for futexes, rtmutexes and
  Kconfig.locks."

* 'core-locking-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  futex: Use freezable blocking call
  futex: Take hugepages into account when generating futex_key
  rtmutex: Document rt_mutex_adjust_prio_chain()
  locking: Fix copy/paste errors of "ARCH_INLINE_*_UNLOCK_BH"

include/linux/hugetlb.h
kernel/Kconfig.locks
kernel/futex.c
kernel/rtmutex.c
mm/hugetlb.c

index 6b4890fa57e7191574da1efe41eec956077d72ae..feaf0c7fb7d8715fc43257be5a0f4f89dc9668e0 100644 (file)
@@ -358,6 +358,17 @@ static inline int hstate_index(struct hstate *h)
        return h - hstates;
 }
 
+pgoff_t __basepage_index(struct page *page);
+
+/* Return page->index in PAGE_SIZE units */
+static inline pgoff_t basepage_index(struct page *page)
+{
+       if (!PageCompound(page))
+               return page->index;
+
+       return __basepage_index(page);
+}
+
 #else  /* CONFIG_HUGETLB_PAGE */
 struct hstate {};
 #define alloc_huge_page_node(h, nid) NULL
@@ -378,6 +389,11 @@ static inline unsigned int pages_per_huge_page(struct hstate *h)
 }
 #define hstate_index_to_shift(index) 0
 #define hstate_index(h) 0
+
+static inline pgoff_t basepage_index(struct page *page)
+{
+       return page->index;
+}
 #endif /* CONFIG_HUGETLB_PAGE */
 
 #endif /* _LINUX_HUGETLB_H */
index 44511d100eaa89f73c53f0e16828a9f03d7256ac..d2b32ac27a394095e87229030e010eb428ae7174 100644 (file)
@@ -138,7 +138,7 @@ config INLINE_SPIN_UNLOCK_BH
 
 config INLINE_SPIN_UNLOCK_IRQ
        def_bool y
-       depends on !PREEMPT || ARCH_INLINE_SPIN_UNLOCK_BH
+       depends on !PREEMPT || ARCH_INLINE_SPIN_UNLOCK_IRQ
 
 config INLINE_SPIN_UNLOCK_IRQRESTORE
        def_bool y
@@ -175,7 +175,7 @@ config INLINE_READ_UNLOCK_BH
 
 config INLINE_READ_UNLOCK_IRQ
        def_bool y
-       depends on !PREEMPT || ARCH_INLINE_READ_UNLOCK_BH
+       depends on !PREEMPT || ARCH_INLINE_READ_UNLOCK_IRQ
 
 config INLINE_READ_UNLOCK_IRQRESTORE
        def_bool y
@@ -212,7 +212,7 @@ config INLINE_WRITE_UNLOCK_BH
 
 config INLINE_WRITE_UNLOCK_IRQ
        def_bool y
-       depends on !PREEMPT || ARCH_INLINE_WRITE_UNLOCK_BH
+       depends on !PREEMPT || ARCH_INLINE_WRITE_UNLOCK_IRQ
 
 config INLINE_WRITE_UNLOCK_IRQRESTORE
        def_bool y
index b26dcfc02c9489b3ca00bfd076f2208bb4964366..c3a1a55a52141851630b91f2bff2aa789b508ace 100644 (file)
@@ -61,6 +61,8 @@
 #include <linux/nsproxy.h>
 #include <linux/ptrace.h>
 #include <linux/sched/rt.h>
+#include <linux/hugetlb.h>
+#include <linux/freezer.h>
 
 #include <asm/futex.h>
 
@@ -365,7 +367,7 @@ again:
        } else {
                key->both.offset |= FUT_OFF_INODE; /* inode-based key */
                key->shared.inode = page_head->mapping->host;
-               key->shared.pgoff = page_head->index;
+               key->shared.pgoff = basepage_index(page);
        }
 
        get_futex_key_refs(key);
@@ -1807,7 +1809,7 @@ static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q,
                 * is no timeout, or if it has yet to expire.
                 */
                if (!timeout || timeout->task)
-                       schedule();
+                       freezable_schedule();
        }
        __set_current_state(TASK_RUNNING);
 }
index 1e09308bf2a1e5f46c3f68d02bc4bcb346b42ec5..0dd6aec1cb6ad8bb41a44ba74f770ca4439fc022 100644 (file)
@@ -145,6 +145,19 @@ int max_lock_depth = 1024;
 /*
  * Adjust the priority chain. Also used for deadlock detection.
  * Decreases task's usage by one - may thus free the task.
+ *
+ * @task: the task owning the mutex (owner) for which a chain walk is probably
+ *       needed
+ * @deadlock_detect: do we have to carry out deadlock detection?
+ * @orig_lock: the mutex (can be NULL if we are walking the chain to recheck
+ *            things for a task that has just got its priority adjusted, and
+ *            is waiting on a mutex)
+ * @orig_waiter: rt_mutex_waiter struct for the task that has just donated
+ *              its priority to the mutex owner (can be NULL in the case
+ *              depicted above or if the top waiter is gone away and we are
+ *              actually deboosting the owner)
+ * @top_task: the current top waiter
+ *
  * Returns 0 or -EDEADLK.
  */
 static int rt_mutex_adjust_prio_chain(struct task_struct *task,
index e2bfbf73a551d0747fbea1b69200dd773e36754e..5cf99bf8cce2043fd0c4d162c16b83636837e450 100644 (file)
@@ -690,6 +690,23 @@ int PageHuge(struct page *page)
 }
 EXPORT_SYMBOL_GPL(PageHuge);
 
+pgoff_t __basepage_index(struct page *page)
+{
+       struct page *page_head = compound_head(page);
+       pgoff_t index = page_index(page_head);
+       unsigned long compound_idx;
+
+       if (!PageHuge(page_head))
+               return page_index(page);
+
+       if (compound_order(page_head) >= MAX_ORDER)
+               compound_idx = page_to_pfn(page) - page_to_pfn(page_head);
+       else
+               compound_idx = page - page_head;
+
+       return (index << compound_order(page_head)) + compound_idx;
+}
+
 static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid)
 {
        struct page *page;