[PATCH 07/21] X86_64, UV: Disable Obsolete APIC ID fixup code used only on UV1

Mike Travis
2016-04-29T21:54:14Z

[-- Attachment #1: uv4_disable_obs_uv1_code --]
[-- Type: text/plain, Size: 4548 bytes --]

This patch deletes old code that artificially added and removed APIC
ID bits not available on UV100/UV1000 systems only. An additional
performance hit and code bloat occurs when selecting MMR address or
field defines as the following code example shows. (This is produced
by one of the Verilog to MMR defines tool chain scripts).

#define UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT ( \
is_uv1_hub() ? UV1H_EVENT_OCCURRED0_EXTIO_INT0_SHFT : \
is_uv2_hub() ? UV2H_EVENT_OCCURRED0_EXTIO_INT0_SHFT : \
is_uv3_hub() ? UV3H_EVENT_OCCURRED0_EXTIO_INT0_SHFT : \
/*is_uv4_hub*/ UV4H_EVENT_OCCURRED0_EXTIO_INT0_SHFT)

The patch causes "is_uv1_hub()" to produce a constant '0' as shown in
"PATCH [02/21] X86_64, UV: Add UV Architecture Defines." This should
cause the optimizer to remove the 25% irrelevant code in the above
selection macro. It will also remove other dead code that is conditioned
by "if (is_uv1_hub()) ..." for those systems that do not need nor want
that extra code.

Signed-off-by: Mike Travis <travis@sgi.com>
Reviewed-by: Dimitri Sivanich <sivanich@sgi.com>
Reviewed-by: Russ Anderson <rja@sgi.com>
Tested-by: Nathan Zimmer <nzimmer@sgi.com>
---
arch/x86/Kconfig | 9 +++++++++
arch/x86/include/asm/uv/uv_mmrs.h | 2 ++
arch/x86/kernel/apic/x2apic_uv_x.c | 25 +++++++++----------------
3 files changed, 20 insertions(+), 16 deletions(-)

--- linux.orig/arch/x86/Kconfig
+++ linux/arch/x86/Kconfig
@@ -489,6 +489,15 @@ config X86_UV
This option is needed in order to support SGI Ultraviolet systems.
If you don't have one of these, you should say N here.

+config X86_UV1_SUPPORTED
+ bool "SGI Ultraviolet Series 1 Supported"
+ depends on X86_UV
+ default n
+ ---help---
+ Set this option if you have a UV100/UV1000 system. With it off
+ some code bloat and a performance hit is removed for those systems
+ that do not need it.
+
# Following is an alphabetically sorted list of 32 bit extended platforms
# Please maintain the alphabetic order if and when there are additions

--- linux.orig/arch/x86/include/asm/uv/uv_mmrs.h
+++ linux/arch/x86/include/asm/uv/uv_mmrs.h
@@ -95,7 +95,9 @@
#define UV4_HUB_PART_NUMBER 0x99a1

/* Compat: Indicate which UV Hubs are supported. */
+#ifdef CONFIG_X86_UV1_SUPPORTED
#define UV1_HUB_IS_SUPPORTED 1
+#endif
#define UV2_HUB_IS_SUPPORTED 1
#define UV3_HUB_IS_SUPPORTED 1
#define UV4_HUB_IS_SUPPORTED 1
--- linux.orig/arch/x86/kernel/apic/x2apic_uv_x.c
+++ linux/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -53,6 +53,7 @@ EXPORT_SYMBOL_GPL(uv_min_hub_revision_id
unsigned int uv_apicid_hibits;
EXPORT_SYMBOL_GPL(uv_apicid_hibits);

+static int uv1_apic_driver;
static struct apic apic_x2apic_uv_x;

/* Set this to use hardware error handler instead of kernel panic */
@@ -160,7 +161,6 @@ static void __init uv_set_apicid_hibit(v
static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
int pnodeid;
- int uv_apic;

if (strncmp(oem_id, "SGI", 3) != 0)
return 0;
@@ -188,28 +188,26 @@ static int __init uv_acpi_madt_oem_check

if (!strcmp(oem_table_id, "UVX")) { /* most common */
uv_system_type = UV_X2APIC;
- uv_apic = 0;

} else if (!strcmp(oem_table_id, "UVH")) { /* only UV1 systems */
uv_system_type = UV_NON_UNIQUE_APIC;
__this_cpu_write(x2apic_extra_bits,
pnodeid << uvh_apicid.s.pnode_shift);
uv_set_apicid_hibit();
- uv_apic = 1;
+ uv1_apic_driver = 1;

} else if (!strcmp(oem_table_id, "UVL")) { /* only used for */
uv_system_type = UV_LEGACY_APIC; /* very small systems */
- uv_apic = 0;

} else {
goto badbios;
}

- pr_info("UV: OEM IDs %s/%s, System/HUB Types %d/%d, uv_apic %d\n",
+ pr_info("UV: OEM IDs %s/%s, System/HUB Types %d/%d, apic type %d\n",
oem_id, oem_table_id, uv_system_type,
- uv_min_hub_revision_id, uv_apic);
+ uv_min_hub_revision_id, uv1_apic_driver);

- return uv_apic;
+ return uv1_apic_driver;

badbios:
pr_err("UV: OEM_ID:%s OEM_TABLE_ID:%s\n", oem_id, oem_table_id);
@@ -353,21 +351,16 @@ uv_cpu_mask_to_apicid_and(const struct c

static unsigned int x2apic_get_apic_id(unsigned long x)
{
- unsigned int id;
+ if (likely(!uv1_apic_driver))
+ return x;

WARN_ON(preemptible() && num_online_cpus() > 1);
- id = x | __this_cpu_read(x2apic_extra_bits);
-
- return id;
+ return x | __this_cpu_read(x2apic_extra_bits);
}

static unsigned long set_apic_id(unsigned int id)
{
- unsigned long x;
-
- /* maskout x2apic_extra_bits ? */
- x = id;
- return x;
+ return id;
}

static unsigned int uv_read_apic_id(void)

--