linux-kernel-test/drivers/xen
David Vrabel 179fbd5a45 xen/evtchn: avoid a deadlock when unbinding an event channel
Unbinding an event channel (either with the ioctl or when the evtchn
device is closed) may deadlock because disable_irq() is called with
port_user_lock held which is also locked by the interrupt handler.

Think of the IOCTL_EVTCHN_UNBIND is being serviced, the routine has
just taken the lock, and an interrupt happens. The evtchn_interrupt
is invoked, tries to take the lock and spins forever.

A quick glance at the code shows that the spinlock is a local IRQ
variant. Unfortunately that does not help as "disable_irq() waits for
the interrupt handler on all CPUs to stop running.  If the irq occurs
on another VCPU, it tries to take port_user_lock and can't because
the unbind ioctl is holding it." (from David). Hence we cannot
depend on the said spinlock to protect us. We could make it a system
wide IRQ disable spinlock but there is a better way.

We can piggyback on the fact that the existence of the spinlock is
to make get_port_user() checks be up-to-date. And we can alter those
checks to not depend on the spin lock (as it's protected by u->bind_mutex
in the ioctl) and can remove the unnecessary locking (this is
IOCTL_EVTCHN_UNBIND) path.

In the interrupt handler we cannot use the mutex, but we do not
need it.

"The unbind disables the irq before making the port user stale, so when
you clear it you are guaranteed that the interrupt handler that might
use that port cannot be running." (from David).

Hence this patch removes the spinlock usage on the teardown path
and piggybacks on disable_irq happening before we muck with the
get_port_user() data. This ensures that the interrupt handler will
never run on stale data.

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
[v1: Expanded the commit description a bit]
2013-07-30 09:21:14 -04:00
..
xen-pciback xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
xenbus xenbus: frontend resume cleanup 2013-07-29 09:32:31 -04:00
xenfs xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
acpi.c xen/acpi/sleep: Enable ACPI sleep via the __acpi_os_prepare_sleep 2012-05-07 15:33:18 -04:00
balloon.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
biomerge.c xen: using EXPORT_SYMBOL requires including export.h 2012-01-18 15:37:49 -08:00
cpu_hotplug.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
dbgp.c xen: dbgp: Fix warning when CONFIG_PCI is not enabled. 2012-10-19 15:19:37 -04:00
events.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
evtchn.c xen/evtchn: avoid a deadlock when unbinding an event channel 2013-07-30 09:21:14 -04:00
fallback.c xen-pciback: notify hypervisor about devices intended to be assigned to guests 2013-03-22 10:20:55 -04:00
features.c
gntalloc.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
gntdev.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
grant-table.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
Kconfig xen/tmem: Remove the usage of '[no|]selfballoon' and use 'tmem.selfballooning' bool instead. 2013-05-15 10:27:49 -04:00
Makefile xen/arm: enable PV control for ARM 2013-07-29 09:35:11 -04:00
manage.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
mcelog.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
pci.c xen/pci: Check for PCI bridge before using it. 2012-05-30 10:16:35 -04:00
pcpu.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
platform-pci.c Drivers: xen: remove __dev* attributes. 2013-01-03 15:57:01 -08:00
privcmd.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
privcmd.h
swiotlb-xen.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
sys-hypervisor.c xen: sysfs: fix build warning. 2012-10-19 15:17:51 -04:00
tmem.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
xen-acpi-cpuhotplug.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
xen-acpi-memhotplug.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
xen-acpi-pad.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
xen-acpi-processor.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
xen-balloon.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
xen-selfballoon.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00
xen-stub.c xen/acpi: remove redundant acpi/acpi_drivers.h include 2013-03-11 13:53:02 -04:00
xencomm.c xen: Convert printks to pr_<level> 2013-06-28 11:19:58 -04:00