1. 31 1月, 2014 2 次提交
  2. 15 11月, 2013 2 次提交
  3. 25 10月, 2013 2 次提交
  4. 01 10月, 2013 1 次提交
    • B
      x86/boot: Further compress CPUs bootup message · a17bce4d
      Borislav Petkov 提交于
      Turn it into (for example):
      
      [    0.073380] x86: Booting SMP configuration:
      [    0.074005] .... node   #0, CPUs:          #1   #2   #3   #4   #5   #6   #7
      [    0.603005] .... node   #1, CPUs:     #8   #9  #10  #11  #12  #13  #14  #15
      [    1.200005] .... node   #2, CPUs:    #16  #17  #18  #19  #20  #21  #22  #23
      [    1.796005] .... node   #3, CPUs:    #24  #25  #26  #27  #28  #29  #30  #31
      [    2.393005] .... node   #4, CPUs:    #32  #33  #34  #35  #36  #37  #38  #39
      [    2.996005] .... node   #5, CPUs:    #40  #41  #42  #43  #44  #45  #46  #47
      [    3.600005] .... node   #6, CPUs:    #48  #49  #50  #51  #52  #53  #54  #55
      [    4.202005] .... node   #7, CPUs:    #56  #57  #58  #59  #60  #61  #62  #63
      [    4.811005] .... node   #8, CPUs:    #64  #65  #66  #67  #68  #69  #70  #71
      [    5.421006] .... node   #9, CPUs:    #72  #73  #74  #75  #76  #77  #78  #79
      [    6.032005] .... node  #10, CPUs:    #80  #81  #82  #83  #84  #85  #86  #87
      [    6.648006] .... node  #11, CPUs:    #88  #89  #90  #91  #92  #93  #94  #95
      [    7.262005] .... node  #12, CPUs:    #96  #97  #98  #99 #100 #101 #102 #103
      [    7.865005] .... node  #13, CPUs:   #104 #105 #106 #107 #108 #109 #110 #111
      [    8.466005] .... node  #14, CPUs:   #112 #113 #114 #115 #116 #117 #118 #119
      [    9.073006] .... node  #15, CPUs:   #120 #121 #122 #123 #124 #125 #126 #127
      [    9.679901] x86: Booted up 16 nodes, 128 CPUs
      
      and drop useless elements.
      
      Change num_digits() to hpa's division-avoiding, cell-phone-typed
      version which he went at great lengths and pains to submit on a
      Saturday evening.
      Signed-off-by: NBorislav Petkov <bp@suse.de>
      Cc: huawei.libin@huawei.com
      Cc: wangyijing@huawei.com
      Cc: fenghua.yu@intel.com
      Cc: guohanjun@huawei.com
      Cc: paul.gortmaker@windriver.com
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Link: http://lkml.kernel.org/r/20130930095624.GB16383@pd.tnicSigned-off-by: NIngo Molnar <mingo@kernel.org>
      a17bce4d
  5. 12 9月, 2013 2 次提交
  6. 19 8月, 2013 1 次提交
  7. 31 7月, 2013 1 次提交
  8. 15 7月, 2013 1 次提交
    • P
      kernel: delete __cpuinit usage from all core kernel files · 0db0628d
      Paul Gortmaker 提交于
      The __cpuinit type of throwaway sections might have made sense
      some time ago when RAM was more constrained, but now the savings
      do not offset the cost and complications.  For example, the fix in
      commit 5e427ec2 ("x86: Fix bit corruption at CPU resume time")
      is a good example of the nasty type of bugs that can be created
      with improper use of the various __init prefixes.
      
      After a discussion on LKML[1] it was decided that cpuinit should go
      the way of devinit and be phased out.  Once all the users are gone,
      we can then finally remove the macros themselves from linux/init.h.
      
      This removes all the uses of the __cpuinit macros from C files in
      the core kernel directories (kernel, init, lib, mm, and include)
      that don't really have a specific maintainer.
      
      [1] https://lkml.org/lkml/2013/5/20/589Signed-off-by: NPaul Gortmaker <paul.gortmaker@windriver.com>
      0db0628d
  9. 01 5月, 2013 2 次提交
  10. 22 2月, 2013 1 次提交
    • S
      smp: make smp_call_function_many() use logic similar to smp_call_function_single() · 9a46ad6d
      Shaohua Li 提交于
      I'm testing swapout workload in a two-socket Xeon machine.  The workload
      has 10 threads, each thread sequentially accesses separate memory
      region.  TLB flush overhead is very big in the workload.  For each page,
      page reclaim need move it from active lru list and then unmap it.  Both
      need a TLB flush.  And this is a multthread workload, TLB flush happens
      in 10 CPUs.  In X86, TLB flush uses generic smp_call)function.  So this
      workload stress smp_call_function_many heavily.
      
      Without patch, perf shows:
      +  24.49%  [k] generic_smp_call_function_interrupt
      -  21.72%  [k] _raw_spin_lock
         - _raw_spin_lock
            + 79.80% __page_check_address
            + 6.42% generic_smp_call_function_interrupt
            + 3.31% get_swap_page
            + 2.37% free_pcppages_bulk
            + 1.75% handle_pte_fault
            + 1.54% put_super
            + 1.41% grab_super_passive
            + 1.36% __swap_duplicate
            + 0.68% blk_flush_plug_list
            + 0.62% swap_info_get
      +   6.55%  [k] flush_tlb_func
      +   6.46%  [k] smp_call_function_many
      +   5.09%  [k] call_function_interrupt
      +   4.75%  [k] default_send_IPI_mask_sequence_phys
      +   2.18%  [k] find_next_bit
      
      swapout throughput is around 1300M/s.
      
      With the patch, perf shows:
      -  27.23%  [k] _raw_spin_lock
         - _raw_spin_lock
            + 80.53% __page_check_address
            + 8.39% generic_smp_call_function_single_interrupt
            + 2.44% get_swap_page
            + 1.76% free_pcppages_bulk
            + 1.40% handle_pte_fault
            + 1.15% __swap_duplicate
            + 1.05% put_super
            + 0.98% grab_super_passive
            + 0.86% blk_flush_plug_list
            + 0.57% swap_info_get
      +   8.25%  [k] default_send_IPI_mask_sequence_phys
      +   7.55%  [k] call_function_interrupt
      +   7.47%  [k] smp_call_function_many
      +   7.25%  [k] flush_tlb_func
      +   3.81%  [k] _raw_spin_lock_irqsave
      +   3.78%  [k] generic_smp_call_function_single_interrupt
      
      swapout throughput is around 1400M/s.  So there is around a 7%
      improvement, and total cpu utilization doesn't change.
      
      Without the patch, cfd_data is shared by all CPUs.
      generic_smp_call_function_interrupt does read/write cfd_data several times
      which will create a lot of cache ping-pong.  With the patch, the data
      becomes per-cpu.  The ping-pong is avoided.  And from the perf data, this
      doesn't make call_single_queue lock contend.
      
      Next step is to remove generic_smp_call_function_interrupt() from arch
      code.
      Signed-off-by: NShaohua Li <shli@fusionio.com>
      Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
      Cc: Ingo Molnar <mingo@elte.hu>
      Cc: Steven Rostedt <rostedt@goodmis.org>
      Cc: Jens Axboe <axboe@kernel.dk>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      9a46ad6d
  11. 28 1月, 2013 1 次提交
    • W
      smp: Fix SMP function call empty cpu mask race · f44310b9
      Wang YanQing 提交于
      I get the following warning every day with v3.7, once or
      twice a day:
      
        [ 2235.186027] WARNING: at /mnt/sda7/kernel/linux/arch/x86/kernel/apic/ipi.c:109 default_send_IPI_mask_logical+0x2f/0xb8()
      
      As explained by Linus as well:
      
       |
       | Once we've done the "list_add_rcu()" to add it to the
       | queue, we can have (another) IPI to the target CPU that can
       | now see it and clear the mask.
       |
       | So by the time we get to actually send the IPI, the mask might
       | have been cleared by another IPI.
       |
      
      This patch also fixes a system hang problem, if the data->cpumask
      gets cleared after passing this point:
      
              if (WARN_ONCE(!mask, "empty IPI mask"))
                      return;
      
      then the problem in commit 83d349f3 ("x86: don't send an IPI to
      the empty set of CPU's") will happen again.
      Signed-off-by: NWang YanQing <udknight@gmail.com>
      Acked-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Acked-by: NJan Beulich <jbeulich@suse.com>
      Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Cc: peterz@infradead.org
      Cc: mina86@mina86.org
      Cc: srivatsa.bhat@linux.vnet.ibm.com
      Cc: <stable@kernel.org>
      Link: http://lkml.kernel.org/r/20130126075357.GA3205@udknight
      [ Tidied up the changelog and the comment in the code. ]
      Signed-off-by: NIngo Molnar <mingo@kernel.org>
      f44310b9
  12. 05 6月, 2012 1 次提交
  13. 08 5月, 2012 1 次提交
  14. 04 5月, 2012 1 次提交
  15. 29 3月, 2012 2 次提交
    • G
      smp: add func to IPI cpus based on parameter func · b3a7e98e
      Gilad Ben-Yossef 提交于
      Add the on_each_cpu_cond() function that wraps on_each_cpu_mask() and
      calculates the cpumask of cpus to IPI by calling a function supplied as a
      parameter in order to determine whether to IPI each specific cpu.
      
      The function works around allocation failure of cpumask variable in
      CONFIG_CPUMASK_OFFSTACK=y by itereating over cpus sending an IPI a time
      via smp_call_function_single().
      
      The function is useful since it allows to seperate the specific code that
      decided in each case whether to IPI a specific cpu for a specific request
      from the common boilerplate code of handling creating the mask, handling
      failures etc.
      
      [akpm@linux-foundation.org: s/gfpflags/gfp_flags/]
      [akpm@linux-foundation.org: avoid double-evaluation of `info' (per Michal), parenthesise evaluation of `cond_func']
      [akpm@linux-foundation.org: s/CPU/CPUs, use all 80 cols in comment]
      Signed-off-by: NGilad Ben-Yossef <gilad@benyossef.com>
      Cc: Chris Metcalf <cmetcalf@tilera.com>
      Cc: Christoph Lameter <cl@linux-foundation.org>
      Acked-by: NPeter Zijlstra <a.p.zijlstra@chello.nl>
      Cc: Frederic Weisbecker <fweisbec@gmail.com>
      Cc: Russell King <linux@arm.linux.org.uk>
      Cc: Pekka Enberg <penberg@kernel.org>
      Cc: Matt Mackall <mpm@selenic.com>
      Cc: Sasha Levin <levinsasha928@gmail.com>
      Cc: Rik van Riel <riel@redhat.com>
      Cc: Andi Kleen <andi@firstfloor.org>
      Cc: Alexander Viro <viro@zeniv.linux.org.uk>
      Cc: Avi Kivity <avi@redhat.com>
      Acked-by: NMichal Nazarewicz <mina86@mina86.org>
      Cc: Kosaki Motohiro <kosaki.motohiro@gmail.com>
      Cc: Milton Miller <miltonm@bga.com>
      Reviewed-by: N"Srivatsa S. Bhat" <srivatsa.bhat@linux.vnet.ibm.com>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      b3a7e98e
    • G
      smp: introduce a generic on_each_cpu_mask() function · 3fc498f1
      Gilad Ben-Yossef 提交于
      We have lots of infrastructure in place to partition multi-core systems
      such that we have a group of CPUs that are dedicated to specific task:
      cgroups, scheduler and interrupt affinity, and cpuisol= boot parameter.
      Still, kernel code will at times interrupt all CPUs in the system via IPIs
      for various needs.  These IPIs are useful and cannot be avoided
      altogether, but in certain cases it is possible to interrupt only specific
      CPUs that have useful work to do and not the entire system.
      
      This patch set, inspired by discussions with Peter Zijlstra and Frederic
      Weisbecker when testing the nohz task patch set, is a first stab at trying
      to explore doing this by locating the places where such global IPI calls
      are being made and turning the global IPI into an IPI for a specific group
      of CPUs.  The purpose of the patch set is to get feedback if this is the
      right way to go for dealing with this issue and indeed, if the issue is
      even worth dealing with at all.  Based on the feedback from this patch set
      I plan to offer further patches that address similar issue in other code
      paths.
      
      This patch creates an on_each_cpu_mask() and on_each_cpu_cond()
      infrastructure API (the former derived from existing arch specific
      versions in Tile and Arm) and uses them to turn several global IPI
      invocation to per CPU group invocations.
      
      Core kernel:
      
      on_each_cpu_mask() calls a function on processors specified by cpumask,
      which may or may not include the local processor.
      
      You must not call this function with disabled interrupts or from a
      hardware interrupt handler or from a bottom half handler.
      
      arch/arm:
      
      Note that the generic version is a little different then the Arm one:
      
      1. It has the mask as first parameter
      2. It calls the function on the calling CPU with interrupts disabled,
         but this should be OK since the function is called on the other CPUs
         with interrupts disabled anyway.
      
      arch/tile:
      
      The API is the same as the tile private one, but the generic version
      also calls the function on the with interrupts disabled in UP case
      
      This is OK since the function is called on the other CPUs
      with interrupts disabled.
      Signed-off-by: NGilad Ben-Yossef <gilad@benyossef.com>
      Reviewed-by: NChristoph Lameter <cl@linux.com>
      Acked-by: NChris Metcalf <cmetcalf@tilera.com>
      Acked-by: NPeter Zijlstra <a.p.zijlstra@chello.nl>
      Cc: Frederic Weisbecker <fweisbec@gmail.com>
      Cc: Russell King <linux@arm.linux.org.uk>
      Cc: Pekka Enberg <penberg@kernel.org>
      Cc: Matt Mackall <mpm@selenic.com>
      Cc: Rik van Riel <riel@redhat.com>
      Cc: Andi Kleen <andi@firstfloor.org>
      Cc: Sasha Levin <levinsasha928@gmail.com>
      Cc: Mel Gorman <mel@csn.ul.ie>
      Cc: Alexander Viro <viro@zeniv.linux.org.uk>
      Cc: Avi Kivity <avi@redhat.com>
      Acked-by: NMichal Nazarewicz <mina86@mina86.org>
      Cc: Kosaki Motohiro <kosaki.motohiro@gmail.com>
      Cc: Milton Miller <miltonm@bga.com>
      Cc: Russell King <linux@arm.linux.org.uk>
      Acked-by: NPeter Zijlstra <a.p.zijlstra@chello.nl>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      3fc498f1
  16. 31 10月, 2011 1 次提交
  17. 17 6月, 2011 1 次提交
  18. 23 3月, 2011 1 次提交
  19. 18 3月, 2011 4 次提交
    • M
      smp_call_function_interrupt: use typedef and %pf · c8def554
      Milton Miller 提交于
      Use the newly added smp_call_func_t in smp_call_function_interrupt for
      the func variable, and make the comment above the WARN more assertive
      and explicit.  Also, func is a function pointer and does not need an
      offset, so use %pf not %pS.
      Signed-off-by: NMilton Miller <miltonm@bga.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      c8def554
    • M
      smp_call_function_many: handle concurrent clearing of mask · 723aae25
      Milton Miller 提交于
      Mike Galbraith reported finding a lockup ("perma-spin bug") where the
      cpumask passed to smp_call_function_many was cleared by other cpu(s)
      while a cpu was preparing its call_data block, resulting in no cpu to
      clear the last ref and unlock the block.
      
      Having cpus clear their bit asynchronously could be useful on a mask of
      cpus that might have a translation context, or cpus that need a push to
      complete an rcu window.
      
      Instead of adding a BUG_ON and requiring yet another cpumask copy, just
      detect the race and handle it.
      
      Note: arch_send_call_function_ipi_mask must still handle an empty
      cpumask because the data block is globally visible before the that arch
      callback is made.  And (obviously) there are no guarantees to which cpus
      are notified if the mask is changed during the call; only cpus that were
      online and had their mask bit set during the whole call are guaranteed
      to be called.
      Reported-by: NMike Galbraith <efault@gmx.de>
      Reported-by: NJan Beulich <JBeulich@novell.com>
      Acked-by: NJan Beulich <jbeulich@novell.com>
      Cc: stable@kernel.org
      Signed-off-by: NMilton Miller <miltonm@bga.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      723aae25
    • M
      call_function_many: add missing ordering · 45a57919
      Milton Miller 提交于
      Paul McKenney's review pointed out two problems with the barriers in the
      2.6.38 update to the smp call function many code.
      
      First, a barrier that would force the func and info members of data to
      be visible before their consumption in the interrupt handler was
      missing.  This can be solved by adding a smp_wmb between setting the
      func and info members and setting setting the cpumask; this will pair
      with the existing and required smp_rmb ordering the cpumask read before
      the read of refs.  This placement avoids the need a second smp_rmb in
      the interrupt handler which would be executed on each of the N cpus
      executing the call request.  (I was thinking this barrier was present
      but was not).
      
      Second, the previous write to refs (establishing the zero that we the
      interrupt handler was testing from all cpus) was performed by a third
      party cpu.  This would invoke transitivity which, as a recient or
      concurrent addition to memory-barriers.txt now explicitly states, would
      require a full smp_mb().
      
      However, we know the cpumask will only be set by one cpu (the data
      owner) and any preivous iteration of the mask would have cleared by the
      reading cpu.  By redundantly writing refs to 0 on the owning cpu before
      the smp_wmb, the write to refs will follow the same path as the writes
      that set the cpumask, which in turn allows us to keep the barrier in the
      interrupt handler a smp_rmb instead of promoting it to a smp_mb (which
      will be be executed by N cpus for each of the possible M elements on the
      list).
      
      I moved and expanded the comment about our (ab)use of the rcu list
      primitives for the concurrent walk earlier into this function.  I
      considered moving the first two paragraphs to the queue list head and
      lock, but felt it would have been too disconected from the code.
      
      Cc: Paul McKinney <paulmck@linux.vnet.ibm.com>
      Cc: stable@kernel.org (2.6.32 and later)
      Signed-off-by: NMilton Miller <miltonm@bga.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      45a57919
    • M
      call_function_many: fix list delete vs add race · e6cd1e07
      Milton Miller 提交于
      Peter pointed out there was nothing preventing the list_del_rcu in
      smp_call_function_interrupt from running before the list_add_rcu in
      smp_call_function_many.
      
      Fix this by not setting refs until we have gotten the lock for the list.
      Take advantage of the wmb in list_add_rcu to save an explicit additional
      one.
      
      I tried to force this race with a udelay before the lock & list_add and
      by mixing all 64 online cpus with just 3 random cpus in the mask, but
      was unsuccessful.  Still, inspection shows a valid race, and the fix is
      a extension of the existing protection window in the current code.
      
      Cc: stable@kernel.org (v2.6.32 and later)
      Reported-by: NPeter Zijlstra <peterz@infradead.org>
      Signed-off-by: NMilton Miller <miltonm@bga.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      e6cd1e07
  20. 21 1月, 2011 2 次提交
    • M
      kernel/smp.c: consolidate writes in smp_call_function_interrupt() · 225c8e01
      Milton Miller 提交于
      We have to test the cpu mask in the interrupt handler before checking the
      refs, otherwise we can start to follow an entry before its deleted and
      find it partially initailzed for the next trip.  Presently we also clear
      the cpumask bit before executing the called function, which implies
      getting write access to the line.  After the function is called we then
      decrement refs, and if they go to zero we then unlock the structure.
      
      However, this implies getting write access to the call function data
      before and after another the function is called.  If we can assert that no
      smp_call_function execution function is allowed to enable interrupts, then
      we can move both writes to after the function is called, hopfully allowing
      both writes with one cache line bounce.
      
      On a 256 thread system with a kernel compiled for 1024 threads, the time
      to execute testcase in the "smp_call_function_many race" changelog was
      reduced by about 30-40ms out of about 545 ms.
      
      I decided to keep this as WARN because its now a buggy function, even
      though the stack trace is of no value -- a simple printk would give us the
      information needed.
      
      Raw data:
      
      Without patch:
        ipi_test startup took 1219366ns complete 539819014ns total 541038380ns
        ipi_test startup took 1695754ns complete 543439872ns total 545135626ns
        ipi_test startup took 7513568ns complete 539606362ns total 547119930ns
        ipi_test startup took 13304064ns complete 533898562ns total 547202626ns
        ipi_test startup took 8668192ns complete 544264074ns total 552932266ns
        ipi_test startup took 4977626ns complete 548862684ns total 553840310ns
        ipi_test startup took 2144486ns complete 541292318ns total 543436804ns
        ipi_test startup took 21245824ns complete 530280180ns total 551526004ns
      
      With patch:
        ipi_test startup took 5961748ns complete 500859628ns total 506821376ns
        ipi_test startup took 8975996ns complete 495098924ns total 504074920ns
        ipi_test startup took 19797750ns complete 492204740ns total 512002490ns
        ipi_test startup took 14824796ns complete 487495878ns total 502320674ns
        ipi_test startup took 11514882ns complete 494439372ns total 505954254ns
        ipi_test startup took 8288084ns complete 502570774ns total 510858858ns
        ipi_test startup took 6789954ns complete 493388112ns total 500178066ns
      
      	#include <linux/module.h>
      	#include <linux/init.h>
      	#include <linux/sched.h> /* sched clock */
      
      	#define ITERATIONS 100
      
      	static void do_nothing_ipi(void *dummy)
      	{
      	}
      
      	static void do_ipis(struct work_struct *dummy)
      	{
      		int i;
      
      		for (i = 0; i < ITERATIONS; i++)
      			smp_call_function(do_nothing_ipi, NULL, 1);
      
      		printk(KERN_DEBUG "cpu %d finished\n", smp_processor_id());
      	}
      
      	static struct work_struct work[NR_CPUS];
      
      	static int __init testcase_init(void)
      	{
      		int cpu;
      		u64 start, started, done;
      
      		start = local_clock();
      		for_each_online_cpu(cpu) {
      			INIT_WORK(&work[cpu], do_ipis);
      			schedule_work_on(cpu, &work[cpu]);
      		}
      		started = local_clock();
      		for_each_online_cpu(cpu)
      			flush_work(&work[cpu]);
      		done = local_clock();
      		pr_info("ipi_test startup took %lldns complete %lldns total %lldns\n",
      			started-start, done-started, done-start);
      
      		return 0;
      	}
      
      	static void __exit testcase_exit(void)
      	{
      	}
      
      	module_init(testcase_init)
      	module_exit(testcase_exit)
      	MODULE_LICENSE("GPL");
      	MODULE_AUTHOR("Anton Blanchard");
      Signed-off-by: NMilton Miller <miltonm@bga.com>
      Cc: Anton Blanchard <anton@samba.org>
      Cc: Ingo Molnar <mingo@elte.hu>
      Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      225c8e01
    • A
      kernel/smp.c: fix smp_call_function_many() SMP race · 6dc19899
      Anton Blanchard 提交于
      I noticed a failure where we hit the following WARN_ON in
      generic_smp_call_function_interrupt:
      
                      if (!cpumask_test_and_clear_cpu(cpu, data->cpumask))
                              continue;
      
                      data->csd.func(data->csd.info);
      
                      refs = atomic_dec_return(&data->refs);
                      WARN_ON(refs < 0);      <-------------------------
      
      We atomically tested and cleared our bit in the cpumask, and yet the
      number of cpus left (ie refs) was 0.  How can this be?
      
      It turns out commit 54fdade1
      ("generic-ipi: make struct call_function_data lockless") is at fault.  It
      removes locking from smp_call_function_many and in doing so creates a
      rather complicated race.
      
      The problem comes about because:
      
       - The smp_call_function_many interrupt handler walks call_function.queue
         without any locking.
       - We reuse a percpu data structure in smp_call_function_many.
       - We do not wait for any RCU grace period before starting the next
         smp_call_function_many.
      
      Imagine a scenario where CPU A does two smp_call_functions back to back,
      and CPU B does an smp_call_function in between.  We concentrate on how CPU
      C handles the calls:
      
      CPU A            CPU B                  CPU C              CPU D
      
      smp_call_function
                                              smp_call_function_interrupt
                                                  walks
      					call_function.queue sees
      					data from CPU A on list
      
                       smp_call_function
      
                                              smp_call_function_interrupt
                                                  walks
      
                                              call_function.queue sees
                                                (stale) CPU A on list
      							   smp_call_function int
      							   clears last ref on A
      							   list_del_rcu, unlock
      smp_call_function reuses
      percpu *data A
                                               data->cpumask sees and
                                               clears bit in cpumask
                                               might be using old or new fn!
                                               decrements refs below 0
      
      set data->refs (too late!)
      
      The important thing to note is since the interrupt handler walks a
      potentially stale call_function.queue without any locking, then another
      cpu can view the percpu *data structure at any time, even when the owner
      is in the process of initialising it.
      
      The following test case hits the WARN_ON 100% of the time on my PowerPC
      box (having 128 threads does help :)
      
      #include <linux/module.h>
      #include <linux/init.h>
      
      #define ITERATIONS 100
      
      static void do_nothing_ipi(void *dummy)
      {
      }
      
      static void do_ipis(struct work_struct *dummy)
      {
      	int i;
      
      	for (i = 0; i < ITERATIONS; i++)
      		smp_call_function(do_nothing_ipi, NULL, 1);
      
      	printk(KERN_DEBUG "cpu %d finished\n", smp_processor_id());
      }
      
      static struct work_struct work[NR_CPUS];
      
      static int __init testcase_init(void)
      {
      	int cpu;
      
      	for_each_online_cpu(cpu) {
      		INIT_WORK(&work[cpu], do_ipis);
      		schedule_work_on(cpu, &work[cpu]);
      	}
      
      	return 0;
      }
      
      static void __exit testcase_exit(void)
      {
      }
      
      module_init(testcase_init)
      module_exit(testcase_exit)
      MODULE_LICENSE("GPL");
      MODULE_AUTHOR("Anton Blanchard");
      
      I tried to fix it by ordering the read and the write of ->cpumask and
      ->refs.  In doing so I missed a critical case but Paul McKenney was able
      to spot my bug thankfully :) To ensure we arent viewing previous
      iterations the interrupt handler needs to read ->refs then ->cpumask then
      ->refs _again_.
      
      Thanks to Milton Miller and Paul McKenney for helping to debug this issue.
      
      [miltonm@bga.com: add WARN_ON and BUG_ON, remove extra read of refs before initial read of mask that doesn't help (also noted by Peter Zijlstra), adjust comments, hopefully clarify scenario ]
      [miltonm@bga.com: remove excess tests]
      Signed-off-by: NAnton Blanchard <anton@samba.org>
      Signed-off-by: NMilton Miller <miltonm@bga.com>
      Cc: Ingo Molnar <mingo@elte.hu>
      Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
      Cc: <stable@kernel.org> [2.6.32+]
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      6dc19899
  21. 20 1月, 2011 1 次提交
  22. 14 1月, 2011 1 次提交
    • A
      kernel: clean up USE_GENERIC_SMP_HELPERS · 351f8f8e
      Amerigo Wang 提交于
      For arch which needs USE_GENERIC_SMP_HELPERS, it has to select
      USE_GENERIC_SMP_HELPERS, rather than leaving a choice to user, since they
      don't provide their own implementions.
      
      Also, move on_each_cpu() to kernel/smp.c, it is strange to put it in
      kernel/softirq.c.
      
      For arch which doesn't use USE_GENERIC_SMP_HELPERS, e.g.  blackfin, only
      on_each_cpu() is compiled.
      Signed-off-by: NAmerigo Wang <amwang@redhat.com>
      Cc: David Howells <dhowells@redhat.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Ingo Molnar <mingo@elte.hu>
      Cc: "H. Peter Anvin" <hpa@zytor.com>
      Cc: Yinghai Lu <yinghai@kernel.org>
      Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
      Cc: Randy Dunlap <randy.dunlap@oracle.com>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      351f8f8e
  23. 28 10月, 2010 1 次提交
  24. 10 9月, 2010 1 次提交
    • H
      generic-ipi: Fix deadlock in __smp_call_function_single · 27c379f7
      Heiko Carstens 提交于
      Just got my 6 way machine to a state where cpu 0 is in an
      endless loop within __smp_call_function_single.
      All other cpus are idle.
      
      The call trace on cpu 0 looks like this:
      
       __smp_call_function_single
       scheduler_tick
       update_process_times
       tick_sched_timer
       __run_hrtimer
       hrtimer_interrupt
       clock_comparator_work
       do_extint
       ext_int_handler
       ----> timer irq
       cpu_idle
      
      __smp_call_function_single() got called from nohz_balancer_kick()
      (inlined) with the remote cpu being 1, wait being 0 and the per
      cpu variable remote_sched_softirq_cb (call_single_data) of the
      current cpu (0).
      
      Then it loops forever when it tries to grab the lock of the
      call_single_data, since it is already locked and enqueued on cpu 0.
      
      My theory how this could have happened: for some reason the
      scheduler decided to call __smp_call_function_single() on it's own
      cpu, and sends an IPI to itself. The interrupt stays pending
      since IRQs are disabled. If then the hypervisor schedules the
      cpu away it might happen that upon rescheduling both the IPI and
      the timer IRQ are pending. If then interrupts are enabled again
      it depends which one gets scheduled first.
      If the timer interrupt gets delivered first we end up with the
      local deadlock as seen in the calltrace above.
      
      Let's make __smp_call_function_single() check if the target cpu is
      the current cpu and execute the function immediately just like
      smp_call_function_single does. That should prevent at least the
      scenario described here.
      
      It might also be that the scheduler is not supposed to call
      __smp_call_function_single with the remote cpu being the current
      cpu, but that is a different issue.
      Signed-off-by: NHeiko Carstens <heiko.carstens@de.ibm.com>
      Acked-by: NPeter Zijlstra <a.p.zijlstra@chello.nl>
      Acked-by: NJens Axboe <jaxboe@fusionio.com>
      Cc: Venkatesh Pallipadi <venki@google.com>
      Cc: Suresh Siddha <suresh.b.siddha@intel.com>
      LKML-Reference: <20100910114729.GB2827@osiris.boeblingen.de.ibm.com>
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      27c379f7
  25. 28 5月, 2010 1 次提交
  26. 30 3月, 2010 1 次提交
    • T
      include cleanup: Update gfp.h and slab.h includes to prepare for breaking... · 5a0e3ad6
      Tejun Heo 提交于
      include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h
      
      percpu.h is included by sched.h and module.h and thus ends up being
      included when building most .c files.  percpu.h includes slab.h which
      in turn includes gfp.h making everything defined by the two files
      universally available and complicating inclusion dependencies.
      
      percpu.h -> slab.h dependency is about to be removed.  Prepare for
      this change by updating users of gfp and slab facilities include those
      headers directly instead of assuming availability.  As this conversion
      needs to touch large number of source files, the following script is
      used as the basis of conversion.
      
        http://userweb.kernel.org/~tj/misc/slabh-sweep.py
      
      The script does the followings.
      
      * Scan files for gfp and slab usages and update includes such that
        only the necessary includes are there.  ie. if only gfp is used,
        gfp.h, if slab is used, slab.h.
      
      * When the script inserts a new include, it looks at the include
        blocks and try to put the new include such that its order conforms
        to its surrounding.  It's put in the include block which contains
        core kernel includes, in the same order that the rest are ordered -
        alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
        doesn't seem to be any matching order.
      
      * If the script can't find a place to put a new include (mostly
        because the file doesn't have fitting include block), it prints out
        an error message indicating which .h file needs to be added to the
        file.
      
      The conversion was done in the following steps.
      
      1. The initial automatic conversion of all .c files updated slightly
         over 4000 files, deleting around 700 includes and adding ~480 gfp.h
         and ~3000 slab.h inclusions.  The script emitted errors for ~400
         files.
      
      2. Each error was manually checked.  Some didn't need the inclusion,
         some needed manual addition while adding it to implementation .h or
         embedding .c file was more appropriate for others.  This step added
         inclusions to around 150 files.
      
      3. The script was run again and the output was compared to the edits
         from #2 to make sure no file was left behind.
      
      4. Several build tests were done and a couple of problems were fixed.
         e.g. lib/decompress_*.c used malloc/free() wrappers around slab
         APIs requiring slab.h to be added manually.
      
      5. The script was run on all .h files but without automatically
         editing them as sprinkling gfp.h and slab.h inclusions around .h
         files could easily lead to inclusion dependency hell.  Most gfp.h
         inclusion directives were ignored as stuff from gfp.h was usually
         wildly available and often used in preprocessor macros.  Each
         slab.h inclusion directive was examined and added manually as
         necessary.
      
      6. percpu.h was updated not to include slab.h.
      
      7. Build test were done on the following configurations and failures
         were fixed.  CONFIG_GCOV_KERNEL was turned off for all tests (as my
         distributed build env didn't work with gcov compiles) and a few
         more options had to be turned off depending on archs to make things
         build (like ipr on powerpc/64 which failed due to missing writeq).
      
         * x86 and x86_64 UP and SMP allmodconfig and a custom test config.
         * powerpc and powerpc64 SMP allmodconfig
         * sparc and sparc64 SMP allmodconfig
         * ia64 SMP allmodconfig
         * s390 SMP allmodconfig
         * alpha SMP allmodconfig
         * um on x86_64 SMP allmodconfig
      
      8. percpu.h modifications were reverted so that it could be applied as
         a separate patch and serve as bisection point.
      
      Given the fact that I had only a couple of failures from tests on step
      6, I'm fairly confident about the coverage of this conversion patch.
      If there is a breakage, it's likely to be something in one of the arch
      headers which should be easily discoverable easily on most builds of
      the specific arch.
      Signed-off-by: NTejun Heo <tj@kernel.org>
      Guess-its-ok-by: NChristoph Lameter <cl@linux-foundation.org>
      Cc: Ingo Molnar <mingo@redhat.com>
      Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
      5a0e3ad6
  27. 18 1月, 2010 1 次提交
  28. 17 1月, 2010 1 次提交
    • D
      smp_call_function_any(): pass the node value to cpumask_of_node() · af2422c4
      David John 提交于
      The change in acpi_cpufreq to use smp_call_function_any causes a warning
      when it is called since the function erroneously passes the cpu id to
      cpumask_of_node rather than the node that the cpu is on.  Fix this.
      
      cpumask_of_node(3): node > nr_node_ids(1)
      Pid: 1, comm: swapper Not tainted 2.6.33-rc3-00097-g2c1f1895 #223
      Call Trace:
       [<ffffffff81028bb3>] cpumask_of_node+0x23/0x58
       [<ffffffff81061f51>] smp_call_function_any+0x65/0xfa
       [<ffffffff810160d1>] ? do_drv_read+0x0/0x2f
       [<ffffffff81015fba>] get_cur_val+0xb0/0x102
       [<ffffffff81016080>] get_cur_freq_on_cpu+0x74/0xc5
       [<ffffffff810168a7>] acpi_cpufreq_cpu_init+0x417/0x515
       [<ffffffff81562ce9>] ? __down_write+0xb/0xd
       [<ffffffff8148055e>] cpufreq_add_dev+0x278/0x922
      Signed-off-by: NDavid John <davidjon@xenontk.org>
      Cc: Suresh Siddha <suresh.b.siddha@intel.com>
      Cc: Rusty Russell <rusty@rustcorp.com.au>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: "H. Peter Anvin" <hpa@zytor.com>
      Cc: Ingo Molnar <mingo@elte.hu>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      af2422c4
  29. 16 12月, 2009 1 次提交
  30. 15 12月, 2009 1 次提交