• Paul E. McKenney's avatar
    x86/cpu: Avoid cpuinfo-induced IPI pileups · f4deaf90
    Paul E. McKenney authored
    The aperfmperf_snapshot_cpu() function is invoked upon access to
    /proc/cpuinfo, and it does do an early exit if the specified CPU has
    recently done a snapshot.  Unfortunately, the indication that a snapshot
    has been completed is set in an IPI handler, and the execution of this
    handler can be delayed by any number of unfortunate events.  This means
    that a system that starts a number of applications, each of which
    parses /proc/cpuinfo, can suffer from an smp_call_function_single()
    storm, especially given that each access to /proc/cpuinfo invokes
    smp_call_function_single() for all CPUs.  Please note that this is not
    theoretical speculation.  Note also that one CPU's pending IPI serves
    all requests, so there is no point in ever having more than one IPI
    pending to a given CPU.
    
    This commit therefore suppresses duplicate IPIs to a given CPU via a
    new ->scfpending field in the aperfmperf_sample structure.  This field
    is set to the value one if an IPI is pending to the corresponding CPU
    and to zero otherwise.
    
    The aperfmperf_snapshot_cpu() function uses atomic_xchg() to set this
    field to the value one and sample the old value.  If this function's
    "wait" parameter is zero, smp_call_function_single() is called only if
    the old value of the ->scfpending field was zero.  The IPI handler uses
    atomic_set_release() to set this new field to zero just before returning,
    so that the prior stores into the aperfmperf_sample structure are seen
    by future requests that get to the atomic_xchg().  Future requests that
    pass the elapsed-time check are ordered by the fact that on x86 loads act
    as acquire loads, just as was the case prior to this change.  The return
    value is based off of the age of the prior snapshot, just as before.
    Reported-by: default avatarDave Jones <davej@codemonkey.org.uk>
    [ paulmck: Allow /proc/cpuinfo to take advantage of arch_freq_get_on_cpu(). ]
    [ paulmck: Add comment on memory barrier. ]
    Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
    Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: "H. Peter Anvin" <hpa@zytor.com>
    Cc: <x86@kernel.org>
    f4deaf90
aperfmperf.c 3.25 KB