iommu/amd: Avoid locking get_irq_table() from atomic context
authorScott Wood <swood@redhat.com>
Wed, 14 Feb 2018 23:36:28 +0000 (17:36 -0600)
committerJoerg Roedel <jroedel@suse.de>
Thu, 15 Feb 2018 11:03:26 +0000 (12:03 +0100)
commitdf42a04b15f19a842393dc98a84cbc52b1f8ed49
treeb8a8ee13f00ede449ce0fbfb3a3b9f53238e6f5f
parent01ee04badefd296eb7a4430497373be9b7b16783
iommu/amd: Avoid locking get_irq_table() from atomic context

get_irq_table() previously acquired amd_iommu_devtable_lock which is not
a raw lock, and thus cannot be acquired from atomic context on
PREEMPT_RT.  Many calls to modify_irte*() come from atomic context due to
the IRQ desc->lock, as does amd_iommu_update_ga() due to the preemption
disabling in vcpu_load/put().

The only difference between calling get_irq_table() and reading from
irq_lookup_table[] directly, other than the lock acquisition and
amd_iommu_rlookup_table[] check, is if the table entry is unpopulated,
which should never happen when looking up a devid that came from an
irq_2_irte struct, as get_irq_table() would have already been called on
that devid during irq_remapping_alloc().

The lock acquisition is not needed in these cases because entries in
irq_lookup_table[] never change once non-NULL -- nor would the
amd_iommu_devtable_lock usage in get_irq_table() provide meaningful
protection if they did, since it's released before using the looked up
table in the get_irq_table() caller.

Rename the old get_irq_table() to alloc_irq_table(), and create a new
lockless get_irq_table() to be used in non-allocating contexts that WARNs
if it doesn't find what it's looking for.

Signed-off-by: Scott Wood <swood@redhat.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/amd_iommu.c