Skip to content

Commit 47f218d

Browse files
jgunthorpejoergroedel
authored andcommitted
iommu/amd: Store the nid in io_pgtable_cfg instead of the domain
We already have memory in the union here that is being wasted in AMD's case, use it to store the nid. Putting the nid here further isolates the io_pgtable code from the struct protection_domain. Fixup protection_domain_alloc so that the NID from the device is provided, at this point dev is never NULL for AMD so this will now allocate the first table pointer on the correct NUMA node. Signed-off-by: Jason Gunthorpe <[email protected]> Reviewed-by: Vasant Hegde <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 977fc27 commit 47f218d

File tree

7 files changed

+20
-14
lines changed

7 files changed

+20
-14
lines changed

drivers/iommu/amd/amd_iommu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ extern enum io_pgtable_fmt amd_iommu_pgtable;
4545
extern int amd_iommu_gpt_level;
4646

4747
/* Protection domain ops */
48-
struct protection_domain *protection_domain_alloc(unsigned int type);
48+
struct protection_domain *protection_domain_alloc(unsigned int type, int nid);
4949
void protection_domain_free(struct protection_domain *domain);
5050
struct iommu_domain *amd_iommu_domain_alloc_sva(struct device *dev,
5151
struct mm_struct *mm);

drivers/iommu/amd/amd_iommu_types.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,6 @@ struct protection_domain {
571571
struct amd_io_pgtable iop;
572572
spinlock_t lock; /* mostly used to lock the page table*/
573573
u16 id; /* the domain id written to the device table */
574-
int nid; /* Node ID */
575574
enum protection_domain_mode pd_mode; /* Track page table type */
576575
bool dirty_tracking; /* dirty tracking is enabled in the domain */
577576
unsigned dev_cnt; /* devices assigned to this domain */

drivers/iommu/amd/io_pgtable.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,12 @@ static bool increase_address_space(struct protection_domain *domain,
141141
unsigned long address,
142142
gfp_t gfp)
143143
{
144+
struct io_pgtable_cfg *cfg = &domain->iop.pgtbl.cfg;
144145
unsigned long flags;
145146
bool ret = true;
146147
u64 *pte;
147148

148-
pte = iommu_alloc_page_node(domain->nid, gfp);
149+
pte = iommu_alloc_page_node(cfg->amd.nid, gfp);
149150
if (!pte)
150151
return false;
151152

@@ -181,6 +182,7 @@ static u64 *alloc_pte(struct protection_domain *domain,
181182
gfp_t gfp,
182183
bool *updated)
183184
{
185+
struct io_pgtable_cfg *cfg = &domain->iop.pgtbl.cfg;
184186
int level, end_lvl;
185187
u64 *pte, *page;
186188

@@ -232,7 +234,7 @@ static u64 *alloc_pte(struct protection_domain *domain,
232234

233235
if (!IOMMU_PTE_PRESENT(__pte) ||
234236
pte_level == PAGE_MODE_NONE) {
235-
page = iommu_alloc_page_node(domain->nid, gfp);
237+
page = iommu_alloc_page_node(cfg->amd.nid, gfp);
236238

237239
if (!page)
238240
return NULL;
@@ -559,7 +561,7 @@ static struct io_pgtable *v1_alloc_pgtable(struct io_pgtable_cfg *cfg, void *coo
559561
{
560562
struct amd_io_pgtable *pgtable = io_pgtable_cfg_to_data(cfg);
561563

562-
pgtable->root = iommu_alloc_page(GFP_KERNEL);
564+
pgtable->root = iommu_alloc_page_node(cfg->amd.nid, GFP_KERNEL);
563565
if (!pgtable->root)
564566
return NULL;
565567
pgtable->mode = PAGE_MODE_3_LEVEL;

drivers/iommu/amd/io_pgtable_v2.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ static int iommu_v2_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
251251

252252
while (mapped_size < size) {
253253
map_size = get_alloc_page_size(pgsize);
254-
pte = v2_alloc_pte(pdom->nid, pdom->iop.pgd,
254+
pte = v2_alloc_pte(cfg->amd.nid, pdom->iop.pgd,
255255
iova, map_size, gfp, &updated);
256256
if (!pte) {
257257
ret = -EINVAL;
@@ -359,10 +359,9 @@ static void v2_free_pgtable(struct io_pgtable *iop)
359359
static struct io_pgtable *v2_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
360360
{
361361
struct amd_io_pgtable *pgtable = io_pgtable_cfg_to_data(cfg);
362-
struct protection_domain *pdom = (struct protection_domain *)cookie;
363362
int ias = IOMMU_IN_ADDR_BIT_SIZE;
364363

365-
pgtable->pgd = iommu_alloc_page_node(pdom->nid, GFP_KERNEL);
364+
pgtable->pgd = iommu_alloc_page_node(cfg->amd.nid, GFP_KERNEL);
366365
if (!pgtable->pgd)
367366
return NULL;
368367

drivers/iommu/amd/iommu.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,15 +2023,16 @@ static int do_attach(struct iommu_dev_data *dev_data,
20232023
struct protection_domain *domain)
20242024
{
20252025
struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data);
2026+
struct io_pgtable_cfg *cfg = &domain->iop.pgtbl.cfg;
20262027
int ret = 0;
20272028

20282029
/* Update data structures */
20292030
dev_data->domain = domain;
20302031
list_add(&dev_data->list, &domain->dev_list);
20312032

20322033
/* Update NUMA Node ID */
2033-
if (domain->nid == NUMA_NO_NODE)
2034-
domain->nid = dev_to_node(dev_data->dev);
2034+
if (cfg->amd.nid == NUMA_NO_NODE)
2035+
cfg->amd.nid = dev_to_node(dev_data->dev);
20352036

20362037
/* Do reference counting */
20372038
domain->dev_iommu[iommu->index] += 1;
@@ -2266,7 +2267,7 @@ void protection_domain_free(struct protection_domain *domain)
22662267
kfree(domain);
22672268
}
22682269

2269-
struct protection_domain *protection_domain_alloc(unsigned int type)
2270+
struct protection_domain *protection_domain_alloc(unsigned int type, int nid)
22702271
{
22712272
struct io_pgtable_ops *pgtbl_ops;
22722273
struct protection_domain *domain;
@@ -2283,7 +2284,7 @@ struct protection_domain *protection_domain_alloc(unsigned int type)
22832284
spin_lock_init(&domain->lock);
22842285
INIT_LIST_HEAD(&domain->dev_list);
22852286
INIT_LIST_HEAD(&domain->dev_data_list);
2286-
domain->nid = NUMA_NO_NODE;
2287+
domain->iop.pgtbl.cfg.amd.nid = nid;
22872288

22882289
switch (type) {
22892290
/* No need to allocate io pgtable ops in passthrough mode */
@@ -2360,7 +2361,8 @@ static struct iommu_domain *do_iommu_domain_alloc(unsigned int type,
23602361
if (dirty_tracking && !amd_iommu_hd_support(iommu))
23612362
return ERR_PTR(-EOPNOTSUPP);
23622363

2363-
domain = protection_domain_alloc(type);
2364+
domain = protection_domain_alloc(type,
2365+
dev ? dev_to_node(dev) : NUMA_NO_NODE);
23642366
if (!domain)
23652367
return ERR_PTR(-ENOMEM);
23662368

drivers/iommu/amd/pasid.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ struct iommu_domain *amd_iommu_domain_alloc_sva(struct device *dev,
181181
struct protection_domain *pdom;
182182
int ret;
183183

184-
pdom = protection_domain_alloc(IOMMU_DOMAIN_SVA);
184+
pdom = protection_domain_alloc(IOMMU_DOMAIN_SVA, dev_to_node(dev));
185185
if (!pdom)
186186
return ERR_PTR(-ENOMEM);
187187

include/linux/io-pgtable.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ struct io_pgtable_cfg {
171171
u64 ttbr[4];
172172
u32 n_ttbrs;
173173
} apple_dart_cfg;
174+
175+
struct {
176+
int nid;
177+
} amd;
174178
};
175179
};
176180

0 commit comments

Comments
 (0)