Skip to content

Commit 539d378

Browse files
Shanker DonthineniMarc Zyngier
authored andcommitted
irqchip/gicv3-its: Use NUMA aware memory allocation for ITS tables
The NUMA node information is visible to ITS driver but not being used other than handling hardware errata. ITS/GICR hardware accesses to the local NUMA node is usually quicker than the remote NUMA node. How slow the remote NUMA accesses are depends on the implementation details. This patch allocates memory for ITS management tables and command queue from the corresponding NUMA node using the appropriate NUMA aware functions. This change improves the performance of the ITS tables read latency on systems where it has more than one ITS block, and with the slower inter node accesses. Apache Web server benchmarking using ab tool on a HiSilicon D06 board with multiple numa mem nodes shows Time per request and Transfer rate improvements of ~3.6% with this patch. Signed-off-by: Shanker Donthineni <shankerd@codeaurora.org> Signed-off-by: Hanjun Guo <guohanjun@huawei.com> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> Reviewed-by: Ganapatrao Kulkarni <gkulkarni@marvell.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
1 parent 9f199dd commit 539d378

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,6 +1737,7 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
17371737
u64 type = GITS_BASER_TYPE(val);
17381738
u64 baser_phys, tmp;
17391739
u32 alloc_pages;
1740+
struct page *page;
17401741
void *base;
17411742

17421743
retry_alloc_baser:
@@ -1749,10 +1750,11 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
17491750
order = get_order(GITS_BASER_PAGES_MAX * psz);
17501751
}
17511752

1752-
base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
1753-
if (!base)
1753+
page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, order);
1754+
if (!page)
17541755
return -ENOMEM;
17551756

1757+
base = (void *)page_address(page);
17561758
baser_phys = virt_to_phys(base);
17571759

17581760
/* Check if the physical address of the memory is above 48bits */
@@ -2238,7 +2240,8 @@ static struct its_baser *its_get_baser(struct its_node *its, u32 type)
22382240
return NULL;
22392241
}
22402242

2241-
static bool its_alloc_table_entry(struct its_baser *baser, u32 id)
2243+
static bool its_alloc_table_entry(struct its_node *its,
2244+
struct its_baser *baser, u32 id)
22422245
{
22432246
struct page *page;
22442247
u32 esz, idx;
@@ -2258,7 +2261,8 @@ static bool its_alloc_table_entry(struct its_baser *baser, u32 id)
22582261

22592262
/* Allocate memory for 2nd level table */
22602263
if (!table[idx]) {
2261-
page = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(baser->psz));
2264+
page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
2265+
get_order(baser->psz));
22622266
if (!page)
22632267
return false;
22642268

@@ -2289,7 +2293,7 @@ static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
22892293
if (!baser)
22902294
return (ilog2(dev_id) < its->device_ids);
22912295

2292-
return its_alloc_table_entry(baser, dev_id);
2296+
return its_alloc_table_entry(its, baser, dev_id);
22932297
}
22942298

22952299
static bool its_alloc_vpe_table(u32 vpe_id)
@@ -2313,7 +2317,7 @@ static bool its_alloc_vpe_table(u32 vpe_id)
23132317
if (!baser)
23142318
return false;
23152319

2316-
if (!its_alloc_table_entry(baser, vpe_id))
2320+
if (!its_alloc_table_entry(its, baser, vpe_id))
23172321
return false;
23182322
}
23192323

@@ -2347,7 +2351,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
23472351
nr_ites = max(2, nvecs);
23482352
sz = nr_ites * its->ite_size;
23492353
sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
2350-
itt = kzalloc(sz, GFP_KERNEL);
2354+
itt = kzalloc_node(sz, GFP_KERNEL, its->numa_node);
23512355
if (alloc_lpis) {
23522356
lpi_map = its_lpi_alloc(nvecs, &lpi_base, &nr_lpis);
23532357
if (lpi_map)
@@ -3488,6 +3492,7 @@ static int __init its_probe_one(struct resource *res,
34883492
void __iomem *its_base;
34893493
u32 val, ctlr;
34903494
u64 baser, tmp, typer;
3495+
struct page *page;
34913496
int err;
34923497

34933498
its_base = ioremap(res->start, resource_size(res));
@@ -3543,12 +3548,13 @@ static int __init its_probe_one(struct resource *res,
35433548

35443549
its->numa_node = numa_node;
35453550

3546-
its->cmd_base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
3547-
get_order(ITS_CMD_QUEUE_SZ));
3548-
if (!its->cmd_base) {
3551+
page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
3552+
get_order(ITS_CMD_QUEUE_SZ));
3553+
if (!page) {
35493554
err = -ENOMEM;
35503555
goto out_free_its;
35513556
}
3557+
its->cmd_base = (void *)page_address(page);
35523558
its->cmd_write = its->cmd_base;
35533559
its->fwnode_handle = handle;
35543560
its->get_msi_base = its_irq_get_msi_base;

0 commit comments

Comments
 (0)