OSDN Git Service

Merge branch 'locking/core' into x86/core, to prepare for dependent patch
authorIngo Molnar <mingo@kernel.org>
Wed, 3 Jun 2015 08:07:35 +0000 (10:07 +0200)
committerIngo Molnar <mingo@kernel.org>
Wed, 3 Jun 2015 08:07:35 +0000 (10:07 +0200)
Signed-off-by: Ingo Molnar <mingo@kernel.org>
1  2 
arch/x86/Kconfig
arch/x86/include/asm/paravirt_types.h
arch/x86/kernel/paravirt_patch_64.c
kernel/locking/rtmutex.c

diff --combined arch/x86/Kconfig
@@@ -100,7 -100,7 +100,7 @@@ config X8
        select IRQ_FORCED_THREADING
        select HAVE_BPF_JIT if X86_64
        select HAVE_ARCH_TRANSPARENT_HUGEPAGE
 -      select HAVE_ARCH_HUGE_VMAP if X86_64 || (X86_32 && X86_PAE)
 +      select HAVE_ARCH_HUGE_VMAP if X86_64 || X86_PAE
        select ARCH_HAS_SG_CHAIN
        select CLKEVT_I8253
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select MODULES_USE_ELF_RELA if X86_64
        select CLONE_BACKWARDS if X86_32
        select ARCH_USE_BUILTIN_BSWAP
-       select ARCH_USE_QUEUE_RWLOCK
+       select ARCH_USE_QUEUED_SPINLOCKS
+       select ARCH_USE_QUEUED_RWLOCKS
        select OLD_SIGSUSPEND3 if X86_32 || IA32_EMULATION
        select OLD_SIGACTION if X86_32
        select COMPAT_OLD_SIGACTION if IA32_EMULATION
@@@ -341,7 -342,7 +342,7 @@@ config X86_FEATURE_NAME
  
  config X86_X2APIC
        bool "Support x2apic"
 -      depends on X86_LOCAL_APIC && X86_64 && IRQ_REMAP
 +      depends on X86_LOCAL_APIC && X86_64 && (IRQ_REMAP || HYPERVISOR_GUEST)
        ---help---
          This enables x2apic support on CPUs that have this feature.
  
@@@ -441,7 -442,6 +442,7 @@@ config X86_U
        depends on X86_EXTENDED_PLATFORM
        depends on NUMA
        depends on X86_X2APIC
 +      depends on PCI
        ---help---
          This option is needed in order to support SGI Ultraviolet systems.
          If you don't have one of these, you should say N here.
@@@ -467,6 -467,7 +468,6 @@@ config X86_INTEL_C
        select X86_REBOOTFIXUPS
        select OF
        select OF_EARLY_FLATTREE
 -      select IRQ_DOMAIN
        ---help---
          Select for the Intel CE media processor (CE4100) SOC.
          This option compiles in support for the CE4100 SOC for settop
@@@ -666,7 -667,7 +667,7 @@@ config PARAVIRT_DEBU
  config PARAVIRT_SPINLOCKS
        bool "Paravirtualization layer for spinlocks"
        depends on PARAVIRT && SMP
-       select UNINLINE_SPIN_UNLOCK
+       select UNINLINE_SPIN_UNLOCK if !QUEUED_SPINLOCKS
        ---help---
          Paravirtualized spinlocks allow a pvops backend to replace the
          spinlock implementation with something virtualization-friendly
@@@ -851,12 -852,11 +852,12 @@@ config NR_CPU
        default "1" if !SMP
        default "8192" if MAXSMP
        default "32" if SMP && X86_BIGSMP
 -      default "8" if SMP
 +      default "8" if SMP && X86_32
 +      default "64" if SMP
        ---help---
          This allows you to specify the maximum number of CPUs which this
          kernel will support.  If CPUMASK_OFFSTACK is enabled, the maximum
 -        supported value is 4096, otherwise the maximum value is 512.  The
 +        supported value is 8192, otherwise the maximum value is 512.  The
          minimum value which makes sense is 2.
  
          This is purely to save memory - each supported CPU adds
@@@ -915,12 -915,12 +916,12 @@@ config X86_UP_IOAPI
  config X86_LOCAL_APIC
        def_bool y
        depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC || PCI_MSI
 -      select GENERIC_IRQ_LEGACY_ALLOC_HWIRQ
 +      select IRQ_DOMAIN_HIERARCHY
 +      select PCI_MSI_IRQ_DOMAIN if PCI_MSI
  
  config X86_IO_APIC
        def_bool y
        depends on X86_LOCAL_APIC || X86_UP_IOAPIC
 -      select IRQ_DOMAIN
  
  config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
        bool "Reroute for broken boot IRQs"
@@@ -160,14 -160,13 +160,14 @@@ struct pv_cpu_ops 
        u64 (*read_pmc)(int counter);
        unsigned long long (*read_tscp)(unsigned int *aux);
  
 +#ifdef CONFIG_X86_32
        /*
         * Atomically enable interrupts and return to userspace.  This
 -       * is only ever used to return to 32-bit processes; in a
 -       * 64-bit kernel, it's used for 32-on-64 compat processes, but
 -       * never native 64-bit processes.  (Jump, not call.)
 +       * is only used in 32-bit kernels.  64-bit kernels use
 +       * usergs_sysret32 instead.
         */
        void (*irq_enable_sysexit)(void);
 +#endif
  
        /*
         * Switch to usermode gs and return to 64-bit usermode using
@@@ -334,9 -333,19 +334,19 @@@ struct arch_spinlock
  typedef u16 __ticket_t;
  #endif
  
+ struct qspinlock;
  struct pv_lock_ops {
+ #ifdef CONFIG_QUEUED_SPINLOCKS
+       void (*queued_spin_lock_slowpath)(struct qspinlock *lock, u32 val);
+       struct paravirt_callee_save queued_spin_unlock;
+       void (*wait)(u8 *ptr, u8 val);
+       void (*kick)(int cpu);
+ #else /* !CONFIG_QUEUED_SPINLOCKS */
        struct paravirt_callee_save lock_spinning;
        void (*unlock_kick)(struct arch_spinlock *lock, __ticket_t ticket);
+ #endif /* !CONFIG_QUEUED_SPINLOCKS */
  };
  
  /* This contains all the paravirt structures: we get a convenient
@@@ -21,6 -21,10 +21,10 @@@ DEF_NATIVE(pv_cpu_ops, swapgs, "swapgs"
  DEF_NATIVE(, mov32, "mov %edi, %eax");
  DEF_NATIVE(, mov64, "mov %rdi, %rax");
  
+ #if defined(CONFIG_PARAVIRT_SPINLOCKS) && defined(CONFIG_QUEUED_SPINLOCKS)
+ DEF_NATIVE(pv_lock_ops, queued_spin_unlock, "movb $0, (%rdi)");
+ #endif
  unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len)
  {
        return paravirt_patch_insns(insnbuf, len,
@@@ -33,6 -37,8 +37,8 @@@ unsigned paravirt_patch_ident_64(void *
                                    start__mov64, end__mov64);
  }
  
+ extern bool pv_is_native_spin_unlock(void);
  unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
                      unsigned long addr, unsigned len)
  {
@@@ -49,6 -55,7 +55,6 @@@
                PATCH_SITE(pv_irq_ops, save_fl);
                PATCH_SITE(pv_irq_ops, irq_enable);
                PATCH_SITE(pv_irq_ops, irq_disable);
 -              PATCH_SITE(pv_cpu_ops, irq_enable_sysexit);
                PATCH_SITE(pv_cpu_ops, usergs_sysret32);
                PATCH_SITE(pv_cpu_ops, usergs_sysret64);
                PATCH_SITE(pv_cpu_ops, swapgs);
                PATCH_SITE(pv_cpu_ops, clts);
                PATCH_SITE(pv_mmu_ops, flush_tlb_single);
                PATCH_SITE(pv_cpu_ops, wbinvd);
-       patch_site:
-               ret = paravirt_patch_insns(ibuf, len, start, end);
-               break;
+ #if defined(CONFIG_PARAVIRT_SPINLOCKS) && defined(CONFIG_QUEUED_SPINLOCKS)
+               case PARAVIRT_PATCH(pv_lock_ops.queued_spin_unlock):
+                       if (pv_is_native_spin_unlock()) {
+                               start = start_pv_lock_ops_queued_spin_unlock;
+                               end   = end_pv_lock_ops_queued_spin_unlock;
+                               goto patch_site;
+                       }
+ #endif
  
        default:
                ret = paravirt_patch_default(type, clobbers, ibuf, addr, len);
                break;
+ patch_site:
+               ret = paravirt_patch_insns(ibuf, len, start, end);
+               break;
        }
  #undef PATCH_SITE
        return ret;
diff --combined kernel/locking/rtmutex.c
@@@ -70,10 -70,10 +70,10 @@@ static void fixup_rt_mutex_waiters(stru
  }
  
  /*
-  * We can speed up the acquire/release, if the architecture
-  * supports cmpxchg and if there's no debugging state to be set up
+  * We can speed up the acquire/release, if there's no debugging state to be
+  * set up.
   */
- #if defined(__HAVE_ARCH_CMPXCHG) && !defined(CONFIG_DEBUG_RT_MUTEXES)
+ #ifndef CONFIG_DEBUG_RT_MUTEXES
  # define rt_mutex_cmpxchg(l,c,n)      (cmpxchg(&l->owner, c, n) == c)
  static inline void mark_rt_mutex_waiters(struct rt_mutex *lock)
  {
@@@ -265,17 -265,15 +265,17 @@@ struct task_struct *rt_mutex_get_top_ta
  }
  
  /*
 - * Called by sched_setscheduler() to check whether the priority change
 - * is overruled by a possible priority boosting.
 + * Called by sched_setscheduler() to get the priority which will be
 + * effective after the change.
   */
 -int rt_mutex_check_prio(struct task_struct *task, int newprio)
 +int rt_mutex_get_effective_prio(struct task_struct *task, int newprio)
  {
        if (!task_has_pi_waiters(task))
 -              return 0;
 +              return newprio;
  
 -      return task_top_pi_waiter(task)->task->prio <= newprio;
 +      if (task_top_pi_waiter(task)->task->prio <= newprio)
 +              return task_top_pi_waiter(task)->task->prio;
 +      return newprio;
  }
  
  /*
@@@ -1443,10 -1441,17 +1443,17 @@@ EXPORT_SYMBOL_GPL(rt_mutex_timed_lock)
   *
   * @lock:     the rt_mutex to be locked
   *
+  * This function can only be called in thread context. It's safe to
+  * call it from atomic regions, but not from hard interrupt or soft
+  * interrupt context.
+  *
   * Returns 1 on success and 0 on contention
   */
  int __sched rt_mutex_trylock(struct rt_mutex *lock)
  {
+       if (WARN_ON(in_irq() || in_nmi() || in_serving_softirq()))
+               return 0;
        return rt_mutex_fasttrylock(lock, rt_mutex_slowtrylock);
  }
  EXPORT_SYMBOL_GPL(rt_mutex_trylock);