* [PATCH v2 0/2] Allocate IOMMU irq/page table using numa locality info
@ 2023-03-21 9:23 Vasant Hegde
2023-03-21 9:23 ` [PATCH v2 1/2] iommu/amd: Allocate page " Vasant Hegde
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Vasant Hegde @ 2023-03-21 9:23 UTC (permalink / raw)
To: iommu, joro; +Cc: suravee.suthikulpanit, aik, baolu.lu, Vasant Hegde
By default page allocator uses running CPU info to allocate page table.
If it allocates page table in remote memory then every IOMMU access to
page table will have overhead of reading remote page.
This patchset uses IOMMU NUMA node info and tries to allocate memory
from same NUMA node. Similarly use NUMA node info to allocate IOMMU
irqs.
Changes in v2:
- Removed redundant GFP_ATOMIC from alloc_pgtable_page()
- Folded first two patches
Thanks Lu Baolu and Alexey for the reviews.
Vasant Hegde (2):
iommu/amd: Allocate page table using numa locality info
iommu/amd: Allocate IOMMU irqs using numa locality info
drivers/iommu/amd/amd_iommu.h | 8 ++++++++
drivers/iommu/amd/amd_iommu_types.h | 1 +
drivers/iommu/amd/init.c | 3 ++-
drivers/iommu/amd/io_pgtable.c | 4 ++--
drivers/iommu/amd/io_pgtable_v2.c | 16 ++++++----------
drivers/iommu/amd/iommu.c | 6 ++++++
6 files changed, 25 insertions(+), 13 deletions(-)
--
2.31.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 1/2] iommu/amd: Allocate page table using numa locality info
2023-03-21 9:23 [PATCH v2 0/2] Allocate IOMMU irq/page table using numa locality info Vasant Hegde
@ 2023-03-21 9:23 ` Vasant Hegde
2023-03-21 9:23 ` [PATCH v2 2/2] iommu/amd: Allocate IOMMU irqs " Vasant Hegde
2023-03-22 14:44 ` [PATCH v2 0/2] Allocate IOMMU irq/page table " Joerg Roedel
2 siblings, 0 replies; 4+ messages in thread
From: Vasant Hegde @ 2023-03-21 9:23 UTC (permalink / raw)
To: iommu, joro; +Cc: suravee.suthikulpanit, aik, baolu.lu, Vasant Hegde
Introduce 'struct protection_domain->nid' variable. It will contain
IOMMU NUMA node ID. And allocate page table pages using IOMMU numa
locality info. This optimizes page table walk by IOMMU.
Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
---
drivers/iommu/amd/amd_iommu.h | 8 ++++++++
drivers/iommu/amd/amd_iommu_types.h | 1 +
drivers/iommu/amd/io_pgtable.c | 4 ++--
drivers/iommu/amd/io_pgtable_v2.c | 16 ++++++----------
drivers/iommu/amd/iommu.c | 6 ++++++
5 files changed, 23 insertions(+), 12 deletions(-)
diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h
index c160a332ce33..20a142b54498 100644
--- a/drivers/iommu/amd/amd_iommu.h
+++ b/drivers/iommu/amd/amd_iommu.h
@@ -122,6 +122,14 @@ static inline int get_pci_sbdf_id(struct pci_dev *pdev)
return PCI_SEG_DEVID_TO_SBDF(seg, devid);
}
+static inline void *alloc_pgtable_page(int nid, gfp_t gfp)
+{
+ struct page *page;
+
+ page = alloc_pages_node(nid, gfp | __GFP_ZERO, 0);
+ return page ? page_address(page) : NULL;
+}
+
extern bool translation_pre_enabled(struct amd_iommu *iommu);
extern bool amd_iommu_is_attach_deferred(struct device *dev);
extern int __init add_special_device(u8 type, u8 id, u32 *devid,
diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h
index 3d684190b4d5..e5cfdeaaad48 100644
--- a/drivers/iommu/amd/amd_iommu_types.h
+++ b/drivers/iommu/amd/amd_iommu_types.h
@@ -549,6 +549,7 @@ struct protection_domain {
spinlock_t lock; /* mostly used to lock the page table*/
u16 id; /* the domain id written to the device table */
int glx; /* Number of levels for GCR3 table */
+ int nid; /* Node ID */
u64 *gcr3_tbl; /* Guest CR3 table */
unsigned long flags; /* flags to find out type of domain */
unsigned dev_cnt; /* devices assigned to this domain */
diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c
index ace0e9b8b913..1b67116882be 100644
--- a/drivers/iommu/amd/io_pgtable.c
+++ b/drivers/iommu/amd/io_pgtable.c
@@ -156,7 +156,7 @@ static bool increase_address_space(struct protection_domain *domain,
bool ret = true;
u64 *pte;
- pte = (void *)get_zeroed_page(gfp);
+ pte = alloc_pgtable_page(domain->nid, gfp);
if (!pte)
return false;
@@ -250,7 +250,7 @@ static u64 *alloc_pte(struct protection_domain *domain,
if (!IOMMU_PTE_PRESENT(__pte) ||
pte_level == PAGE_MODE_NONE) {
- page = (u64 *)get_zeroed_page(gfp);
+ page = alloc_pgtable_page(domain->nid, gfp);
if (!page)
return NULL;
diff --git a/drivers/iommu/amd/io_pgtable_v2.c b/drivers/iommu/amd/io_pgtable_v2.c
index 8638ddf6fb3b..9f8b423f7630 100644
--- a/drivers/iommu/amd/io_pgtable_v2.c
+++ b/drivers/iommu/amd/io_pgtable_v2.c
@@ -46,11 +46,6 @@ static inline bool is_large_pte(u64 pte)
return (pte & IOMMU_PAGE_PSE);
}
-static inline void *alloc_pgtable_page(void)
-{
- return (void *)get_zeroed_page(GFP_KERNEL);
-}
-
static inline u64 set_pgtable_attr(u64 *page)
{
u64 prot;
@@ -138,8 +133,8 @@ static void free_pgtable(u64 *pt, int level)
}
/* Allocate page table */
-static u64 *v2_alloc_pte(u64 *pgd, unsigned long iova,
- unsigned long pg_size, bool *updated)
+static u64 *v2_alloc_pte(int nid, u64 *pgd, unsigned long iova,
+ unsigned long pg_size, gfp_t gfp, bool *updated)
{
u64 *pte, *page;
int level, end_level;
@@ -162,7 +157,7 @@ static u64 *v2_alloc_pte(u64 *pgd, unsigned long iova,
}
if (!IOMMU_PTE_PRESENT(__pte)) {
- page = alloc_pgtable_page();
+ page = alloc_pgtable_page(nid, gfp);
if (!page)
return NULL;
@@ -262,7 +257,8 @@ static int iommu_v2_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
while (mapped_size < size) {
map_size = get_alloc_page_size(pgsize);
- pte = v2_alloc_pte(pdom->iop.pgd, iova, map_size, &updated);
+ pte = v2_alloc_pte(pdom->nid, pdom->iop.pgd,
+ iova, map_size, gfp, &updated);
if (!pte) {
ret = -EINVAL;
goto out;
@@ -384,7 +380,7 @@ static struct io_pgtable *v2_alloc_pgtable(struct io_pgtable_cfg *cfg, void *coo
struct protection_domain *pdom = (struct protection_domain *)cookie;
int ret;
- pgtable->pgd = alloc_pgtable_page();
+ pgtable->pgd = alloc_pgtable_page(pdom->nid, GFP_ATOMIC);
if (!pgtable->pgd)
return NULL;
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 5a505ba5467e..5452d0dd6569 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -1662,6 +1662,10 @@ static void do_attach(struct iommu_dev_data *dev_data,
dev_data->domain = domain;
list_add(&dev_data->list, &domain->dev_list);
+ /* Update NUMA Node ID */
+ if (domain->nid == NUMA_NO_NODE)
+ domain->nid = dev_to_node(dev_data->dev);
+
/* Do reference counting */
domain->dev_iommu[iommu->index] += 1;
domain->dev_cnt += 1;
@@ -2097,6 +2101,8 @@ static struct protection_domain *protection_domain_alloc(unsigned int type)
if (type == IOMMU_DOMAIN_IDENTITY)
return domain;
+ domain->nid = NUMA_NO_NODE;
+
pgtbl_ops = alloc_io_pgtable_ops(pgtable, &domain->iop.pgtbl_cfg, domain);
if (!pgtbl_ops) {
domain_id_free(domain->id);
--
2.31.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v2 2/2] iommu/amd: Allocate IOMMU irqs using numa locality info
2023-03-21 9:23 [PATCH v2 0/2] Allocate IOMMU irq/page table using numa locality info Vasant Hegde
2023-03-21 9:23 ` [PATCH v2 1/2] iommu/amd: Allocate page " Vasant Hegde
@ 2023-03-21 9:23 ` Vasant Hegde
2023-03-22 14:44 ` [PATCH v2 0/2] Allocate IOMMU irq/page table " Joerg Roedel
2 siblings, 0 replies; 4+ messages in thread
From: Vasant Hegde @ 2023-03-21 9:23 UTC (permalink / raw)
To: iommu, joro; +Cc: suravee.suthikulpanit, aik, baolu.lu, Vasant Hegde
Use numa information to allocate irq resources and also to set
irq affinity. This optimizes the IOMMU interrupt handling.
Reviewed-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Reviewed-by: Alexey Kardashevskiy <aik@amd.com>
Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
---
drivers/iommu/amd/init.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
index 19a46b9f7357..141eca29c951 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -2383,6 +2383,7 @@ static int iommu_setup_intcapxt(struct amd_iommu *iommu)
struct irq_domain *domain;
struct irq_alloc_info info;
int irq, ret;
+ int node = dev_to_node(&iommu->dev->dev);
domain = iommu_get_irqdomain();
if (!domain)
@@ -2392,7 +2393,7 @@ static int iommu_setup_intcapxt(struct amd_iommu *iommu)
info.type = X86_IRQ_ALLOC_TYPE_AMDVI;
info.data = iommu;
- irq = irq_domain_alloc_irqs(domain, 1, NUMA_NO_NODE, &info);
+ irq = irq_domain_alloc_irqs(domain, 1, node, &info);
if (irq < 0) {
irq_domain_remove(domain);
return irq;
--
2.31.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v2 0/2] Allocate IOMMU irq/page table using numa locality info
2023-03-21 9:23 [PATCH v2 0/2] Allocate IOMMU irq/page table using numa locality info Vasant Hegde
2023-03-21 9:23 ` [PATCH v2 1/2] iommu/amd: Allocate page " Vasant Hegde
2023-03-21 9:23 ` [PATCH v2 2/2] iommu/amd: Allocate IOMMU irqs " Vasant Hegde
@ 2023-03-22 14:44 ` Joerg Roedel
2 siblings, 0 replies; 4+ messages in thread
From: Joerg Roedel @ 2023-03-22 14:44 UTC (permalink / raw)
To: Vasant Hegde; +Cc: iommu, suravee.suthikulpanit, aik, baolu.lu
On Tue, Mar 21, 2023 at 09:23:46AM +0000, Vasant Hegde wrote:
> Vasant Hegde (2):
> iommu/amd: Allocate page table using numa locality info
> iommu/amd: Allocate IOMMU irqs using numa locality info
>
> drivers/iommu/amd/amd_iommu.h | 8 ++++++++
> drivers/iommu/amd/amd_iommu_types.h | 1 +
> drivers/iommu/amd/init.c | 3 ++-
> drivers/iommu/amd/io_pgtable.c | 4 ++--
> drivers/iommu/amd/io_pgtable_v2.c | 16 ++++++----------
> drivers/iommu/amd/iommu.c | 6 ++++++
> 6 files changed, 25 insertions(+), 13 deletions(-)
Applied, thanks Vasant.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-03-22 14:44 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-03-21 9:23 [PATCH v2 0/2] Allocate IOMMU irq/page table using numa locality info Vasant Hegde
2023-03-21 9:23 ` [PATCH v2 1/2] iommu/amd: Allocate page " Vasant Hegde
2023-03-21 9:23 ` [PATCH v2 2/2] iommu/amd: Allocate IOMMU irqs " Vasant Hegde
2023-03-22 14:44 ` [PATCH v2 0/2] Allocate IOMMU irq/page table " Joerg Roedel
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.