Skip to content

Commit f682b44

Browse files
hegdevasantgregkh
authored andcommitted
iommu/amd: Reduce domain lock scope in attach device path
[ Upstream commit d6b47de ] Currently attach device path takes protection domain lock followed by dev_data lock. Most of the operations in this function is specific to device data except pdom_attach_iommu() where it updates protection domain structure. Hence reduce the scope of protection domain lock. Note that this changes the locking order. Now it takes device lock before taking doamin lock (group->mutex -> dev_data->lock -> pdom->lock). dev_data->lock is used only in device attachment path. So changing order is fine. It will not create any issue. Finally move numa node assignment to pdom_attach_iommu(). Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Link: https://lore.kernel.org/r/20241030063556.6104-8-vasant.hegde@amd.com Signed-off-by: Joerg Roedel <jroedel@suse.de> Stable-dep-of: faad224 ("iommu/amd: Fix clone_alias() to use the original device's devid") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 596bb22 commit f682b44

1 file changed

Lines changed: 30 additions & 22 deletions

File tree

drivers/iommu/amd/iommu.c

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2057,16 +2057,23 @@ static int pdom_attach_iommu(struct amd_iommu *iommu,
20572057
struct protection_domain *pdom)
20582058
{
20592059
struct pdom_iommu_info *pdom_iommu_info, *curr;
2060+
struct io_pgtable_cfg *cfg = &pdom->iop.pgtbl.cfg;
2061+
unsigned long flags;
2062+
int ret = 0;
2063+
2064+
spin_lock_irqsave(&pdom->lock, flags);
20602065

20612066
pdom_iommu_info = xa_load(&pdom->iommu_array, iommu->index);
20622067
if (pdom_iommu_info) {
20632068
pdom_iommu_info->refcnt++;
2064-
return 0;
2069+
goto out_unlock;
20652070
}
20662071

20672072
pdom_iommu_info = kzalloc(sizeof(*pdom_iommu_info), GFP_ATOMIC);
2068-
if (!pdom_iommu_info)
2069-
return -ENOMEM;
2073+
if (!pdom_iommu_info) {
2074+
ret = -ENOMEM;
2075+
goto out_unlock;
2076+
}
20702077

20712078
pdom_iommu_info->iommu = iommu;
20722079
pdom_iommu_info->refcnt = 1;
@@ -2075,43 +2082,52 @@ static int pdom_attach_iommu(struct amd_iommu *iommu,
20752082
NULL, pdom_iommu_info, GFP_ATOMIC);
20762083
if (curr) {
20772084
kfree(pdom_iommu_info);
2078-
return -ENOSPC;
2085+
ret = -ENOSPC;
2086+
goto out_unlock;
20792087
}
20802088

2081-
return 0;
2089+
/* Update NUMA Node ID */
2090+
if (cfg->amd.nid == NUMA_NO_NODE)
2091+
cfg->amd.nid = dev_to_node(&iommu->dev->dev);
2092+
2093+
out_unlock:
2094+
spin_unlock_irqrestore(&pdom->lock, flags);
2095+
return ret;
20822096
}
20832097

20842098
static void pdom_detach_iommu(struct amd_iommu *iommu,
20852099
struct protection_domain *pdom)
20862100
{
20872101
struct pdom_iommu_info *pdom_iommu_info;
2102+
unsigned long flags;
2103+
2104+
spin_lock_irqsave(&pdom->lock, flags);
20882105

20892106
pdom_iommu_info = xa_load(&pdom->iommu_array, iommu->index);
2090-
if (!pdom_iommu_info)
2107+
if (!pdom_iommu_info) {
2108+
spin_unlock_irqrestore(&pdom->lock, flags);
20912109
return;
2110+
}
20922111

20932112
pdom_iommu_info->refcnt--;
20942113
if (pdom_iommu_info->refcnt == 0) {
20952114
xa_erase(&pdom->iommu_array, iommu->index);
20962115
kfree(pdom_iommu_info);
20972116
}
2117+
2118+
spin_unlock_irqrestore(&pdom->lock, flags);
20982119
}
20992120

21002121
static int do_attach(struct iommu_dev_data *dev_data,
21012122
struct protection_domain *domain)
21022123
{
21032124
struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data);
2104-
struct io_pgtable_cfg *cfg = &domain->iop.pgtbl.cfg;
21052125
int ret = 0;
21062126

21072127
/* Update data structures */
21082128
dev_data->domain = domain;
21092129
list_add(&dev_data->list, &domain->dev_list);
21102130

2111-
/* Update NUMA Node ID */
2112-
if (cfg->amd.nid == NUMA_NO_NODE)
2113-
cfg->amd.nid = dev_to_node(dev_data->dev);
2114-
21152131
/* Do reference counting */
21162132
ret = pdom_attach_iommu(iommu, domain);
21172133
if (ret)
@@ -2133,12 +2149,15 @@ static void do_detach(struct iommu_dev_data *dev_data)
21332149
{
21342150
struct protection_domain *domain = dev_data->domain;
21352151
struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data);
2152+
unsigned long flags;
21362153

21372154
/* Clear DTE and flush the entry */
21382155
dev_update_dte(dev_data, false);
21392156

21402157
/* Flush IOTLB and wait for the flushes to finish */
2158+
spin_lock_irqsave(&domain->lock, flags);
21412159
amd_iommu_domain_flush_all(domain);
2160+
spin_unlock_irqrestore(&domain->lock, flags);
21422161

21432162
/* Clear GCR3 table */
21442163
if (pdom_is_sva_capable(domain))
@@ -2160,11 +2179,8 @@ static int attach_device(struct device *dev,
21602179
struct protection_domain *domain)
21612180
{
21622181
struct iommu_dev_data *dev_data;
2163-
unsigned long flags;
21642182
int ret = 0;
21652183

2166-
spin_lock_irqsave(&domain->lock, flags);
2167-
21682184
dev_data = dev_iommu_priv_get(dev);
21692185

21702186
spin_lock(&dev_data->lock);
@@ -2179,8 +2195,6 @@ static int attach_device(struct device *dev,
21792195
out:
21802196
spin_unlock(&dev_data->lock);
21812197

2182-
spin_unlock_irqrestore(&domain->lock, flags);
2183-
21842198
return ret;
21852199
}
21862200

@@ -2190,13 +2204,9 @@ static int attach_device(struct device *dev,
21902204
static void detach_device(struct device *dev)
21912205
{
21922206
struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);
2193-
struct protection_domain *domain = dev_data->domain;
21942207
struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data);
2195-
unsigned long flags;
21962208
bool ppr = dev_data->ppr;
21972209

2198-
spin_lock_irqsave(&domain->lock, flags);
2199-
22002210
spin_lock(&dev_data->lock);
22012211

22022212
/*
@@ -2220,8 +2230,6 @@ static void detach_device(struct device *dev)
22202230
out:
22212231
spin_unlock(&dev_data->lock);
22222232

2223-
spin_unlock_irqrestore(&domain->lock, flags);
2224-
22252233
/* Remove IOPF handler */
22262234
if (ppr)
22272235
amd_iommu_iopf_remove_device(iommu, dev_data);

0 commit comments

Comments
 (0)