Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 20 Feb 2013 01:47:58 +0000 (17:47 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 20 Feb 2013 01:47:58 +0000 (17:47 -0800)
Pull irq core changes from Ingo Molnar:
 "The biggest changes are the IRQ-work and printk changes from Frederic
  Weisbecker, which prepare the code for 'full dynticks' (the ability to
  stop or slow down the periodic tick arbitrarily, not just in idle time
  as today):

   - Don't stop tick with irq works pending.  This fix is generally
     useful and concerns archs that can't raise self IPIs.

   - Flush irq works before CPU offlining.

   - Introduce "lazy" irq works that can wait for the next tick to be
     executed, unless it's stopped.

   - Implement klogd wake up using irq work.  This removes the ad-hoc
     printk_tick()/printk_needs_cpu() hooks and make it working even in
     dynticks mode.

   - Cleanups and fixes."

* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  genirq: Export enable/disable_percpu_irq()
  arch Kconfig: Remove references to IRQ_PER_CPU
  irq_work: Remove return value from the irq_work_queue() function
  genirq: Avoid deadlock in spurious handling
  printk: Wake up klogd using irq_work
  irq_work: Make self-IPIs optable
  irq_work: Warn if there's still work on cpu_down
  irq_work: Flush work on CPU_DYING
  irq_work: Don't stop the tick with pending works
  nohz: Add API to check tick state
  irq_work: Remove CONFIG_HAVE_IRQ_WORK
  irq_work: Fix racy check on work pending flag
  irq_work: Fix racy IRQ_WORK_BUSY flag setting

1  2 
arch/sparc/Kconfig
arch/x86/Kconfig
init/Kconfig
kernel/printk.c

diff --combined arch/sparc/Kconfig
index cb9c333d74e84b0dbd8d97ce067231431046f0f5,ed937ae72df3e58cc7b7c4ea3bda6c756307f1d2..9bff3db17c8c8ad66952ec3d0d557e2f5433e311
@@@ -23,7 -23,6 +23,6 @@@ config SPAR
        select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
        select RTC_CLASS
        select RTC_DRV_M48T59
-       select HAVE_IRQ_WORK
        select HAVE_DMA_ATTRS
        select HAVE_DMA_API_DEBUG
        select HAVE_ARCH_JUMP_LABEL
@@@ -61,7 -60,6 +60,7 @@@ config SPARC6
        select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_SYSCALL_WRAPPERS
 +      select HAVE_ARCH_TRANSPARENT_HUGEPAGE
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_SYSCALL_TRACEPOINTS
diff --combined arch/x86/Kconfig
index 225543bf45a5ca551f9609b18cf8711f729f71e7,5d3d61f40b31688c71d8c42b8edde4d0232554cf..36b05ed0bb3cd3b53857e62f74e00db1a6a068ac
@@@ -28,7 -28,6 +28,6 @@@ config X8
        select HAVE_OPROFILE
        select HAVE_PCSPKR_PLATFORM
        select HAVE_PERF_EVENTS
-       select HAVE_IRQ_WORK
        select HAVE_IOREMAP_PROT
        select HAVE_KPROBES
        select HAVE_MEMBLOCK
@@@ -2138,7 -2137,6 +2137,7 @@@ config OLPC_XO1_RT
  config OLPC_XO1_SCI
        bool "OLPC XO-1 SCI extras"
        depends on OLPC && OLPC_XO1_PM
 +      depends on INPUT=y
        select POWER_SUPPLY
        select GPIO_CS5535
        select MFD_CORE
diff --combined init/Kconfig
index b023334df142aeb44ba05b8374aeaa13c3983d3a,a98e1acc122de8fc84912ab805e19fa0f395cfdd..dcb68ac42b78eb1b9205bbfa0727abf9a502f649
@@@ -20,12 -20,8 +20,8 @@@ config CONSTRUCTOR
        bool
        depends on !UML
  
- config HAVE_IRQ_WORK
-       bool
  config IRQ_WORK
        bool
-       depends on HAVE_IRQ_WORK
  
  config BUILDTIME_EXTABLE_SORT
        bool
@@@ -453,7 -449,7 +449,7 @@@ config TREE_RC
  
  config TREE_PREEMPT_RCU
        bool "Preemptible tree-based hierarchical RCU"
 -      depends on PREEMPT && SMP
 +      depends on PREEMPT
        help
          This option selects the RCU implementation that is
          designed for very large SMP systems with hundreds or
          is also required.  It also scales down nicely to
          smaller systems.
  
 +        Select this option if you are unsure.
 +
  config TINY_RCU
        bool "UP-only small-memory-footprint RCU"
        depends on !PREEMPT && !SMP
@@@ -488,14 -482,6 +484,14 @@@ config PREEMPT_RC
          This option enables preemptible-RCU code that is common between
          the TREE_PREEMPT_RCU and TINY_PREEMPT_RCU implementations.
  
 +config RCU_STALL_COMMON
 +      def_bool ( TREE_RCU || TREE_PREEMPT_RCU || RCU_TRACE )
 +      help
 +        This option enables RCU CPU stall code that is common between
 +        the TINY and TREE variants of RCU.  The purpose is to allow
 +        the tiny variants to disable RCU CPU stall warnings, while
 +        making these warnings mandatory for the tree variants.
 +
  config CONTEXT_TRACKING
         bool
  
@@@ -1273,6 -1259,7 +1269,7 @@@ config HOTPLU
  config PRINTK
        default y
        bool "Enable support for printk" if EXPERT
+       select IRQ_WORK
        help
          This option enables normal printk support. Removing it
          eliminates most of the message strings from the kernel image
diff --combined kernel/printk.c
index 267ce780abe8dd0c18b3c6f1d93f3974b75697ed,0b31715f335a7a8ba1a846fe3b93fe71d97cd8d7..f24633afa46a5e7c8c3ae9010548fc95c122d825
@@@ -42,6 -42,7 +42,7 @@@
  #include <linux/notifier.h>
  #include <linux/rculist.h>
  #include <linux/poll.h>
+ #include <linux/irq_work.h>
  
  #include <asm/uaccess.h>
  
@@@ -87,6 -88,12 +88,6 @@@ static DEFINE_SEMAPHORE(console_sem)
  struct console *console_drivers;
  EXPORT_SYMBOL_GPL(console_drivers);
  
 -#ifdef CONFIG_LOCKDEP
 -static struct lockdep_map console_lock_dep_map = {
 -      .name = "console_lock"
 -};
 -#endif
 -
  /*
   * This is used for debugging the mess that is the VT code by
   * keeping track if we have the console semaphore held. It's
@@@ -1918,6 -1925,7 +1919,6 @@@ void console_lock(void
                return;
        console_locked = 1;
        console_may_schedule = 1;
 -      mutex_acquire(&console_lock_dep_map, 0, 0, _RET_IP_);
  }
  EXPORT_SYMBOL(console_lock);
  
@@@ -1939,6 -1947,7 +1940,6 @@@ int console_trylock(void
        }
        console_locked = 1;
        console_may_schedule = 0;
 -      mutex_acquire(&console_lock_dep_map, 0, 1, _RET_IP_);
        return 1;
  }
  EXPORT_SYMBOL(console_trylock);
@@@ -1959,30 -1968,32 +1960,32 @@@ int is_console_locked(void
  static DEFINE_PER_CPU(int, printk_pending);
  static DEFINE_PER_CPU(char [PRINTK_BUF_SIZE], printk_sched_buf);
  
void printk_tick(void)
static void wake_up_klogd_work_func(struct irq_work *irq_work)
  {
-       if (__this_cpu_read(printk_pending)) {
-               int pending = __this_cpu_xchg(printk_pending, 0);
-               if (pending & PRINTK_PENDING_SCHED) {
-                       char *buf = __get_cpu_var(printk_sched_buf);
-                       printk(KERN_WARNING "[sched_delayed] %s", buf);
-               }
-               if (pending & PRINTK_PENDING_WAKEUP)
-                       wake_up_interruptible(&log_wait);
+       int pending = __this_cpu_xchg(printk_pending, 0);
+       if (pending & PRINTK_PENDING_SCHED) {
+               char *buf = __get_cpu_var(printk_sched_buf);
+               printk(KERN_WARNING "[sched_delayed] %s", buf);
        }
- }
  
- int printk_needs_cpu(int cpu)
- {
-       if (cpu_is_offline(cpu))
-               printk_tick();
-       return __this_cpu_read(printk_pending);
+       if (pending & PRINTK_PENDING_WAKEUP)
+               wake_up_interruptible(&log_wait);
  }
  
+ static DEFINE_PER_CPU(struct irq_work, wake_up_klogd_work) = {
+       .func = wake_up_klogd_work_func,
+       .flags = IRQ_WORK_LAZY,
+ };
  void wake_up_klogd(void)
  {
-       if (waitqueue_active(&log_wait))
+       preempt_disable();
+       if (waitqueue_active(&log_wait)) {
                this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP);
+               irq_work_queue(&__get_cpu_var(wake_up_klogd_work));
+       }
+       preempt_enable();
  }
  
  static void console_cont_flush(char *text, size_t size)
@@@ -2099,6 -2110,7 +2102,6 @@@ skip
                local_irq_restore(flags);
        }
        console_locked = 0;
 -      mutex_release(&console_lock_dep_map, 1, _RET_IP_);
  
        /* Release the exclusive_console once it is used */
        if (unlikely(exclusive_console))
@@@ -2462,6 -2474,7 +2465,7 @@@ int printk_sched(const char *fmt, ...
        va_end(args);
  
        __this_cpu_or(printk_pending, PRINTK_PENDING_SCHED);
+       irq_work_queue(&__get_cpu_var(wake_up_klogd_work));
        local_irq_restore(flags);
  
        return r;