linux/include
Paolo Bonzini 2ae7cdab39 srcu: Allow use of Classic SRCU from both process and interrupt context
commit 1123a60416 upstream.

Linu Cherian reported a WARN in cleanup_srcu_struct() when shutting
down a guest running iperf on a VFIO assigned device.  This happens
because irqfd_wakeup() calls srcu_read_lock(&kvm->irq_srcu) in interrupt
context, while a worker thread does the same inside kvm_set_irq().  If the
interrupt happens while the worker thread is executing __srcu_read_lock(),
updates to the Classic SRCU ->lock_count[] field or the Tree SRCU
->srcu_lock_count[] field can be lost.

The docs say you are not supposed to call srcu_read_lock() and
srcu_read_unlock() from irq context, but KVM interrupt injection happens
from (host) interrupt context and it would be nice if SRCU supported the
use case.  KVM is using SRCU here not really for the "sleepable" part,
but rather due to its IPI-free fast detection of grace periods.  It is
therefore not desirable to switch back to RCU, which would effectively
revert commit 719d93cd5f ("kvm/irqchip: Speed up KVM_SET_GSI_ROUTING",
2014-01-16).

However, the docs are overly conservative.  You can have an SRCU instance
only has users in irq context, and you can mix process and irq context
as long as process context users disable interrupts.  In addition,
__srcu_read_unlock() actually uses this_cpu_dec() on both Tree SRCU and
Classic SRCU.  For those two implementations, only srcu_read_lock()
is unsafe.

When Classic SRCU's __srcu_read_unlock() was changed to use this_cpu_dec(),
in commit 5a41344a3d ("srcu: Simplify __srcu_read_unlock() via
this_cpu_dec()", 2012-11-29), __srcu_read_lock() did two increments.
Therefore it kept __this_cpu_inc(), with preempt_disable/enable in
the caller.  Tree SRCU however only does one increment, so on most
architectures it is more efficient for __srcu_read_lock() to use
this_cpu_inc(), and any performance differences appear to be down in
the noise.

Fixes: 719d93cd5f ("kvm/irqchip: Speed up KVM_SET_GSI_ROUTING")
Reported-by: Linu Cherian <linuc.decode@gmail.com>
Suggested-by: Linu Cherian <linuc.decode@gmail.com>
Cc: kvm@vger.kernel.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
[bwh: Backported to 3.16: __srcu_read_lock() still updates two different
 counters.  So follow what  _this_cpu_generic_to_op() does and use
 raw_local_irq_{save,restore}() and raw_cpu_ptr().]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
History 2017-09-15 18:30:07 +01:00
..
acpi ACPICA: Tables: Enable default 64-bit FADT addresses favor 2015-07-15 10:01:11 +01:00
asm-generic asm-generic: make get_user() clear the destination on errors 2016-11-20 01:17:26 +00:00
clocksource drivers: clocksource: add support for ARM architected timer event stream 2013-09-26 09:48:00 +01:00
crypto crypto: ahash - Fix EINPROGRESS notification callback 2017-06-05 21:17:22 +01:00
drm drm/ttm, drm/vmwgfx: Relax permission checking when opening surfaces 2017-07-18 18:40:26 +01:00
dt-bindings pinctrl: dra: dt-bindings: Fix output pull up/down 2014-11-27 11:22:05 +00:00
keys KEYS: Separate the kernel signature checking keyring from module signing 2013-09-25 17:17:01 +01:00
kvm arm/arm64: KVM: Require in-kernel vgic for the arch timers 2015-05-20 13:25:52 +01:00
linux srcu: Allow use of Classic SRCU from both process and interrupt context 2017-09-15 18:30:07 +01:00
math-emu math-emu: fix floating-point to integer overflow detection 2014-01-07 18:36:24 -06:00
media media: vb2: fix VBI/poll regression 2014-10-09 12:23:49 -07:00
memory ddr: add LPDDR2 data from JESD209-2 2012-05-02 00:04:06 -07:00
misc [media] altera-stapl: it is time to move out from staging 2011-09-23 15:00:57 -03:00
net net: ping: do not abuse udp_poll() 2017-09-15 18:29:56 +01:00
pcmcia pcmcia/ds.h: introduce helper for pcmcia_driver module boilerplate 2013-03-15 12:26:03 -07:00
ras edac: add support for error type "Info" 2013-02-21 14:16:27 -03:00
rdma RDMA/core: Fix incorrect structure packing for booleans 2017-06-05 21:16:50 +01:00
rxrpc atomic: use <linux/atomic.h> 2011-07-26 16:49:47 -07:00
scsi scsi: scsi_error: count medium access timeout only once per EH run 2017-08-26 02:14:29 +01:00
sound ALSA: rawmidi: Make snd_rawmidi_transmit() race-free 2016-02-25 00:18:43 +00:00
target target: Make EXTENDED_COPY 0xe4 failure return COPY TARGET DEVICE NOT REACHABLE 2017-02-23 03:54:18 +00:00
trace tracing: Add #undef to fix compile error 2017-07-18 18:40:06 +01:00
uapi USB: hub: fix SS max number of ports 2017-09-15 18:29:42 +01:00
video Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux 2014-06-12 11:32:30 -07:00
xen xen: Add RING_COPY_REQUEST() 2016-01-25 10:43:42 +00:00
Kbuild UAPI: remove empty Kbuild files 2013-04-30 17:04:09 -07:00