parisc: Use per-pagetable spinlock

PA-RISC uses a global spinlock to protect pagetable updates in the TLB
fault handlers. When multiple cores are taking TLB faults simultaneously,
the cache line containing the spinlock becomes a bottleneck.

This patch embeds the spinlock in the top level page directory, so that
every process has its own lock. It improves performance by 30% when
doing parallel compilations.

At least on the N class systems, only one PxTLB inter processor
broadcast can be active at any one time on the Merced bus. If a Merced
bus is found, this patch serializes the TLB flushes with the
pa_tlb_flush_lock spinlock.

v1: Initial patch by Mikulas
v2: Added Merced detection by Helge
v3: Revised TLB serialization by Dave & Helge

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: John David Anglin <dave.anglin@bell.net>
Signed-off-by: Helge Deller <deller@gmx.de>
This commit is contained in:
Mikulas Patocka
2019-04-28 00:09:53 +02:00
committed by Helge Deller
parent d19a12906e
commit b37d1c1898
9 changed files with 108 additions and 49 deletions

View File

@@ -38,6 +38,7 @@
#include <asm/io.h>
#include <asm/pdc.h>
#include <asm/parisc-device.h>
#include <asm/ropes.h>
/* See comments in include/asm-parisc/pci.h */
const struct dma_map_ops *hppa_dma_ops __read_mostly;
@@ -257,6 +258,30 @@ static struct parisc_device *find_device_by_addr(unsigned long hpa)
return ret ? d.dev : NULL;
}
static int __init is_IKE_device(struct device *dev, void *data)
{
struct parisc_device *pdev = to_parisc_device(dev);
if (!check_dev(dev))
return 0;
if (pdev->id.hw_type != HPHW_BCPORT)
return 0;
if (IS_IKE(pdev) ||
(pdev->id.hversion == REO_MERCED_PORT) ||
(pdev->id.hversion == REOG_MERCED_PORT)) {
return 1;
}
return 0;
}
int __init machine_has_merced_bus(void)
{
int ret;
ret = for_each_padev(is_IKE_device, NULL);
return ret ? 1 : 0;
}
/**
* find_pa_parent_type - Find a parent of a specific type
* @dev: The device to start searching from