Skip to content

Commit ce00eec

Browse files
Matthew Wilcox (Oracle)joergroedel
authored andcommitted
iommu/amd: Use put_pages_list
page->freelist is for the use of slab. We already have the ability to free a list of pages in the core mm, but it requires the use of a list_head and for the pages to be chained together through page->lru. Switch the AMD IOMMU code over to using free_pages_list(). Signed-off-by: Matthew Wilcox (Oracle) <[email protected]> [rm: split from original patch, cosmetic tweaks] Signed-off-by: Robin Murphy <[email protected]> Link: https://lore.kernel.org/r/73af128f651aaa1f38f69e586c66765a88ad2de0.1639753638.git.robin.murphy@arm.com Signed-off-by: Joerg Roedel <[email protected]>
1 parent 6b3106e commit ce00eec

File tree

1 file changed

+18
-32
lines changed

1 file changed

+18
-32
lines changed

drivers/iommu/amd/io_pgtable.c

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -74,26 +74,14 @@ static u64 *first_pte_l7(u64 *pte, unsigned long *page_size,
7474
*
7575
****************************************************************************/
7676

77-
static void free_page_list(struct page *freelist)
78-
{
79-
while (freelist != NULL) {
80-
unsigned long p = (unsigned long)page_address(freelist);
81-
82-
freelist = freelist->freelist;
83-
free_page(p);
84-
}
85-
}
86-
87-
static struct page *free_pt_page(u64 *pt, struct page *freelist)
77+
static void free_pt_page(u64 *pt, struct list_head *freelist)
8878
{
8979
struct page *p = virt_to_page(pt);
9080

91-
p->freelist = freelist;
92-
93-
return p;
81+
list_add_tail(&p->lru, freelist);
9482
}
9583

96-
static struct page *free_pt_lvl(u64 *pt, struct page *freelist, int lvl)
84+
static void free_pt_lvl(u64 *pt, struct list_head *freelist, int lvl)
9785
{
9886
u64 *p;
9987
int i;
@@ -114,22 +102,22 @@ static struct page *free_pt_lvl(u64 *pt, struct page *freelist, int lvl)
114102
*/
115103
p = IOMMU_PTE_PAGE(pt[i]);
116104
if (lvl > 2)
117-
freelist = free_pt_lvl(p, freelist, lvl - 1);
105+
free_pt_lvl(p, freelist, lvl - 1);
118106
else
119-
freelist = free_pt_page(p, freelist);
107+
free_pt_page(p, freelist);
120108
}
121109

122-
return free_pt_page(pt, freelist);
110+
free_pt_page(pt, freelist);
123111
}
124112

125-
static struct page *free_sub_pt(u64 *root, int mode, struct page *freelist)
113+
static void free_sub_pt(u64 *root, int mode, struct list_head *freelist)
126114
{
127115
switch (mode) {
128116
case PAGE_MODE_NONE:
129117
case PAGE_MODE_7_LEVEL:
130118
break;
131119
case PAGE_MODE_1_LEVEL:
132-
freelist = free_pt_page(root, freelist);
120+
free_pt_page(root, freelist);
133121
break;
134122
case PAGE_MODE_2_LEVEL:
135123
case PAGE_MODE_3_LEVEL:
@@ -141,8 +129,6 @@ static struct page *free_sub_pt(u64 *root, int mode, struct page *freelist)
141129
default:
142130
BUG();
143131
}
144-
145-
return freelist;
146132
}
147133

148134
void amd_iommu_domain_set_pgtable(struct protection_domain *domain,
@@ -350,7 +336,7 @@ static u64 *fetch_pte(struct amd_io_pgtable *pgtable,
350336
return pte;
351337
}
352338

353-
static struct page *free_clear_pte(u64 *pte, u64 pteval, struct page *freelist)
339+
static void free_clear_pte(u64 *pte, u64 pteval, struct list_head *freelist)
354340
{
355341
u64 *pt;
356342
int mode;
@@ -361,12 +347,12 @@ static struct page *free_clear_pte(u64 *pte, u64 pteval, struct page *freelist)
361347
}
362348

363349
if (!IOMMU_PTE_PRESENT(pteval))
364-
return freelist;
350+
return;
365351

366352
pt = IOMMU_PTE_PAGE(pteval);
367353
mode = IOMMU_PTE_MODE(pteval);
368354

369-
return free_sub_pt(pt, mode, freelist);
355+
free_sub_pt(pt, mode, freelist);
370356
}
371357

372358
/*
@@ -380,7 +366,7 @@ static int iommu_v1_map_page(struct io_pgtable_ops *ops, unsigned long iova,
380366
phys_addr_t paddr, size_t size, int prot, gfp_t gfp)
381367
{
382368
struct protection_domain *dom = io_pgtable_ops_to_domain(ops);
383-
struct page *freelist = NULL;
369+
LIST_HEAD(freelist);
384370
bool updated = false;
385371
u64 __pte, *pte;
386372
int ret, i, count;
@@ -400,9 +386,9 @@ static int iommu_v1_map_page(struct io_pgtable_ops *ops, unsigned long iova,
400386
goto out;
401387

402388
for (i = 0; i < count; ++i)
403-
freelist = free_clear_pte(&pte[i], pte[i], freelist);
389+
free_clear_pte(&pte[i], pte[i], &freelist);
404390

405-
if (freelist != NULL)
391+
if (!list_empty(&freelist))
406392
updated = true;
407393

408394
if (count > 1) {
@@ -437,7 +423,7 @@ static int iommu_v1_map_page(struct io_pgtable_ops *ops, unsigned long iova,
437423
}
438424

439425
/* Everything flushed out, free pages now */
440-
free_page_list(freelist);
426+
put_pages_list(&freelist);
441427

442428
return ret;
443429
}
@@ -499,7 +485,7 @@ static void v1_free_pgtable(struct io_pgtable *iop)
499485
{
500486
struct amd_io_pgtable *pgtable = container_of(iop, struct amd_io_pgtable, iop);
501487
struct protection_domain *dom;
502-
struct page *freelist = NULL;
488+
LIST_HEAD(freelist);
503489

504490
if (pgtable->mode == PAGE_MODE_NONE)
505491
return;
@@ -516,9 +502,9 @@ static void v1_free_pgtable(struct io_pgtable *iop)
516502
BUG_ON(pgtable->mode < PAGE_MODE_NONE ||
517503
pgtable->mode > PAGE_MODE_6_LEVEL);
518504

519-
freelist = free_sub_pt(pgtable->root, pgtable->mode, freelist);
505+
free_sub_pt(pgtable->root, pgtable->mode, &freelist);
520506

521-
free_page_list(freelist);
507+
put_pages_list(&freelist);
522508
}
523509

524510
static struct io_pgtable *v1_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)

0 commit comments

Comments
 (0)