summaryrefslogtreecommitdiff
path: root/include/linux/pci-ats.h
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2015-07-17 15:05:46 -0500
committerBjorn Helgaas <bhelgaas@google.com>2015-08-13 15:57:21 -0500
commitedc90fee916b4f0d14af9c6b5c08666747488ef8 (patch)
tree25ea93038ec7285c9bb6dbdd07ad7727e442eb23 /include/linux/pci-ats.h
parentfb0cc3aa552642631c3a4e83deae2b5c1a1ef4fa (diff)
PCI: Allocate ATS struct during enumeration
Previously, we allocated pci_ats structures when an IOMMU driver called pci_enable_ats(). An SR-IOV VF shares the STU setting with its PF, so when enabling ATS on the VF, we allocated a pci_ats struct for the PF if it didn't already have one. We held the sriov->lock to serialize threads concurrently enabling ATS on several VFS so only one would allocate the PF pci_ats. Gregor reported a deadlock here: pci_enable_sriov sriov_enable virtfn_add mutex_lock(dev->sriov->lock) # acquire sriov->lock pci_device_add device_add BUS_NOTIFY_ADD_DEVICE notifier chain iommu_bus_notifier amd_iommu_add_device # iommu_ops.add_device init_iommu_group iommu_group_get_for_dev iommu_group_add_device __iommu_attach_device amd_iommu_attach_device # iommu_ops.attach_device attach_device pci_enable_ats mutex_lock(dev->sriov->lock) # deadlock There's no reason to delay allocating the pci_ats struct, and if we allocate it for each device at enumeration-time, there's no need for locking in pci_enable_ats(). Allocate pci_ats struct during enumeration, when we initialize other capabilities. Note that this implementation requires ATS to be enabled on the PF first, before on any of the VFs because the PF controls the STU for all the VFs. Link: http://permalink.gmane.org/gmane.linux.kernel.iommu/9433 Reported-by: Gregor Dick <gdick@solarflare.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'include/linux/pci-ats.h')
-rw-r--r--include/linux/pci-ats.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/include/linux/pci-ats.h b/include/linux/pci-ats.h
index 72031785fe1d..e2dcc2ff3d0e 100644
--- a/include/linux/pci-ats.h
+++ b/include/linux/pci-ats.h
@@ -8,7 +8,7 @@ struct pci_ats {
int pos; /* capability position */
int stu; /* Smallest Translation Unit */
int qdep; /* Invalidate Queue Depth */
- int ref_cnt; /* Physical Function reference count */
+ atomic_t ref_cnt; /* number of VFs with ATS enabled */
unsigned int is_enabled:1; /* Enable bit is set */
};