From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751994AbbJBHqf (ORCPT ); Fri, 2 Oct 2015 03:46:35 -0400 Received: from mail-db3on0119.outbound.protection.outlook.com ([157.55.234.119]:18195 "EHLO emea01-db3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751042AbbJBHqb (ORCPT ); Fri, 2 Oct 2015 03:46:31 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=daniel@numascale.com; Date: Fri, 2 Oct 2015 15:31:26 +0800 From: Daniel J Blueman Subject: Re: [PATCH RFC] x86: Reduce MAX_LOCAL_APIC and MAX_IO_APICS To: Denys Vlasenko , Thomas Gleixner , Jiang Liu , Len Brown CC: the arch/x86 maintainers , Linux Kernel Mailing List , Steffen Persvold Message-ID: <1443771086.28316.0@outlook-emeawest.office365.com> X-Mailer: geary/0.10.0 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8"; format=flowed X-Originating-IP: [175.156.157.249] X-ClientProxiedBy: DB5PR03CA0056.eurprd03.prod.outlook.com (25.164.34.24) To DB5PR07MB1304.eurprd07.prod.outlook.com (25.164.41.158) X-Microsoft-Exchange-Diagnostics: 1;DB5PR07MB1304;2:D9DgHPPAausxmSqE3y1nyRpk+xwwHhYvL1yhHJ+3BVpAWCU3qX8h9Nu42eC1oQNbBfClxmlEk/T1tp7r88VWcMi35GZCaewfFsxhiJuEkgFQbC3qz6Z1efQwiusVjXssJYkZx1uv9GZRLEKOk5Rsz3fHfpjK2TbIFumAOva2G8o=;3:qp35y+YfLhztNm8jE44ALWDY3jpvINgtt+M6QqLbEX0XilwNooWB4T2IdzRegW4a3IfKY2YyZiGNyRGTvD9SC0rktpGpKECsUdSHw1Jze+zEWXkSbumh8rCoaKMdXUHpOOb0NcKNEaB4enTzSUB2cA==;25:GsmT5o4RMyYJStFQzBZMdXRX1Ww0Lluina14IhuZK42YFNnnH/CDspcl5EytE6fAY3X1709nY3vXxO4sw1HxdujFbM+ZqQQ41STpuXGD/xlKfZVfQ/1CXU6a1ZQYvILZjFtiPSuziFXzseGqxURHF0ClNmSdVpYdfBEjgGqhaIlR0xU7+VSRzdJnJcSV32L4WA950m8z2c94DoMpzDdiwLAK4JFb6aa1qvgRhyOE/uS8TwPJyfkxn62EYtZh8DE0sEkJbvCbcuQ5qjktN2HD+g== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:DB5PR07MB1304; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(5005006)(520078)(8121501046)(3002001);SRVR:DB5PR07MB1304;BCL:0;PCL:0;RULEID:;SRVR:DB5PR07MB1304; X-Microsoft-Exchange-Diagnostics: 1;DB5PR07MB1304;4:WVSITESG5+g3GL7CaQBFOcVXk9h1tgbngtiZZ5aaQrsZ51UaBdWdAjdEKsY7aLC1TxMyRVw7INKqiqJS0jCuKjdAmcQ66W5X+6D/yyRbf75zqkzAsxeQ4OCtB/Ys24hvDpevoeb2VrPBMVZ/kix7vHfhPsQryQgeNfWShwGoX00pJ3sPRxnte+HCmUzRmThMbWNoQT8jUsgxMIyeqrylQCLLt4NCjhgekoLf6GvwTUONq1cuJVrn/0RVjEUtfPxx6+/UIdwy7Iruprr9XeEywI0PJY0KBZeMGDcHi9nL2XWluMhSPHTIy6gnAqjyCNfOB3q6/A+m2b7y2Sw9MgqRdQQG5w+CLyt8sAySjSPWNvQ= X-Forefront-PRVS: 0717E25089 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(6009001)(6049001)(377454003)(189002)(24454002)(199003)(243025005)(189998001)(62966003)(77096005)(68736005)(47776003)(86362001)(92566002)(88526003)(77156002)(66066001)(15975445007)(46102003)(5007970100001)(5004730100002)(5001960100002)(107886002)(42186005)(23676002)(64706001)(117156001)(50986999)(50226001)(5001860100001)(87976001)(81156007)(5001830100001)(97736004)(122386002)(40100003)(4001540100001)(5008740100001)(5001770100001)(105586002)(19580405001)(19580395003)(50466002)(106356001)(101416001)(4001430100001);DIR:OUT;SFP:1102;SCL:1;SRVR:DB5PR07MB1304;H:[192.168.10.240];FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtEQjVQUjA3TUIxMzA0OzIzOnNvMTJPUFJVaUMzck1vdlliTElOb1JQWURN?= =?utf-8?B?OXRMWVpTM0l1QkRwOG8yUWhRQ2hDN1lxdmF5TGRBbm1JRkpiRUdqSGRuY3lB?= =?utf-8?B?WG1MeDdGM2JreDVCNGExVHF5SUlpZEZVZ0VOcE1ZcmQwak5Ram1kTzgzZzdG?= =?utf-8?B?ZFZZMTV3SkxvdlBtcHFSSXRheG9uVjdEWmNLZHl2d1BBUzA5ZVlQd0NBUy9M?= =?utf-8?B?ZUlGd0hTSEU5N2ROVGx1T013VjE5QnZzZWdIODI0STEyWFZCVEVpL0pDLzNX?= =?utf-8?B?N05BclBwZWV2bHdNc0JXMHJtZnJpZVp3UTVGOUE4Y09JYlM3cjFhNTN4cWdx?= =?utf-8?B?N2RxdHQ4UWw4dWZtVTRGVHUrZkZNck1SYkNyVWozS3R2Qy9ncVlxVUVWbEJM?= =?utf-8?B?VEV3N3dPa29iUGtCQk1SN2laT21GTUtDU1pWdUpnc2Y5WXUwQVZSUGtqQ25q?= =?utf-8?B?UnZ1UWhyNHFtMXVQSU1aQkRXT3pNNmpaSEh3a2F1R1ZqN0NOVnJQeGU1R3Z3?= =?utf-8?B?NlE3QVltSDk0WCtaeWtjcWh1eWxXUnlzYjJraHYzZmJvTUc1RkJQT2pITHZK?= =?utf-8?B?cGJQblhSck84L3FrNzQ1Y2UyQzFoUk1rN0FISEluVkIzUlR1eFB2cHMyeFg5?= =?utf-8?B?UGcxNHowNlNlODlNNWdPTysyVStLcGcwTklsYkZyaFZtaUltaDc4QU9pS1Qr?= =?utf-8?B?NWVuQlp2VytOdnFISXU3eGdURVlJczRDWGFsU3puVU9PdEFoZnYyL3dneFVx?= =?utf-8?B?T1FBcmhxSms0US8xZEc2OGdVbGNaUmdZSnhGRm5PbTYzTm01SmFidWZsd01u?= =?utf-8?B?L1FRcWhqM1BxSFRHQTdaNVFqQWt5VkNETDB3QXJBdThVVTB6WDJwcHQzYTRw?= =?utf-8?B?L3daTXJJNFBMWmFGVHI3K1Znd3JQWDRwWlJRNjlPbXg3cDVCSWlZY2I3MjR0?= =?utf-8?B?aXZHdFZEQVlhZ1BLNzQ5RDJuQk5BVW5qQmdZK1RsMWJVSWl5OUQ3cHY5Q0t4?= =?utf-8?B?U2ExSjZxV0Q5WVhNMTJSTUVVUVRraVc3Z3VyWTN5eUtIOGJFSmErYW9UT3E1?= =?utf-8?B?SnBxNVJlMUJWaUNyZ3JHdDU3QUY1eHdDdmp6b0JmenpNVG5QZnhPaG9yR29q?= =?utf-8?B?VDlva25VeWtHeVFxc2E4WFF2cjZkOG4yR2FUczZZT1Avekt6WTVTMGE2cGNH?= =?utf-8?B?TWZ6dm5wM2hoMmg2NURSOTlIUmdTelRIZWExRWVHelN6bllJaEtCMXhIZUtv?= =?utf-8?B?WHZ2M3NnR1Y5THhPWTB1QXB3RWhBZGpzSkthaHYzSVp2ajUwVUM4aTcxaDRP?= =?utf-8?B?bE1wMzNORG03L1lnTWZ5L2U5N0gzU0o5ZkZ0RnkwUVQrR1JUcHhvNy9DMkZI?= =?utf-8?B?MWpNUXRQV05xK1g3UHNEeW4rZXUrNEdxK2dwT2J5OUhFcWMzbVVpUW5RWUdt?= =?utf-8?B?a2RGMmdlVFViYzRzb2QzaDVDMGNwQjZRQjQwM3RpQXVlcGNQbUpSaVUxVUY1?= =?utf-8?B?cHRoZTkvVXlzeWlkL09DNVprRkZFMkIwVzJEYXFiczNhR1hFVGhrWG1jOUlr?= =?utf-8?B?R1Q0UURmT2owbXRTVlNJR3hTUUVna2I4Nys5L0NPMWNmN2wxcThzTmlPTXVV?= =?utf-8?B?NVoyVTQ3TUkvSU45TmtuWEEwMzlxZTFsT3NoazBRS2E4cHEyUVJnVUtRWFE4?= =?utf-8?Q?CaL/YHIqryseSdVavWMfEvbrF3VVzEChqt93FWn?= X-Microsoft-Exchange-Diagnostics: 1;DB5PR07MB1304;5:+jYHQ2DtvqxB+CXBPQcN/GVE3LaeeQlIr29eFQqCSjSJrN+t9ljmWf9s9bVxQewW0XrSqT/D3/o7tGeNHXCbN/aTMPrJqhG2U3SCyBYe/Lx/LM5BvgsOSiCWwJbvKQNL/AQfza2OUsLOxN/fUs47dQ==;24:PYWDmoWUq2/Rh9h5d6BbqI2M+Pt5qXUgZu+PLEQluVI417TSar0lSUGpPBqjLG1FwhpkgwwoWdFujoICs1yAYMJ/37FLU1UeEGlvbbGSRuE=;20:Ku2MkGABt62Nq9VaWiIf/4Wga6jTDzqS7t5WR0BsjbRSZv4iKozC5cngZPj6FX/VBFg1RtGds+U6meU7MDlDeg== SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: numascale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Oct 2015 07:31:40.6278 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB5PR07MB1304 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Saturday, September 26, 2015 at 4:40:07 AM UTC+8, Denys Vlasenko wrote: > Before this change MAX_LOCAL_APIC had the fixed value of 32*1024. > Such a big value causes several data arrays to be quite oversized: > > phys_cpu_present_map is 4 kbytes (one bit per apic id), > __apicid_to_node[] is 64 kbytes, > apic_version[] is 128 kbytes. > > On "usual" systems, APIC ids simply go from zero > to maximum logical CPU number, mirroring CPU ids. > > On broken and unusual multi-socket systems > APIC ids can be non-contiguous. The Intel x2APIC spec states the upper 16-bits of APIC ID is the cluster ID [1, p2-12], intended for future distributed systems. Beyond the legacy 8-bit APIC ID, Numascale NumaConnect uses 4-bits for the position of a server on each axis of a multi-dimension torus; SGI NUMAlink also structures the APIC ID space. Instead, define an array based on NR_CPUs to achieve a 1:1 mapping and perform linear search; this addresses the binary bloat and the present artificial APIC ID limits. With CONFIG_NR_CPUS=256: $ size vmlinux vmlinux-patched text data bss dec hex filename 18232877 1849656 2281472 22364005 1553f65 vmlinux 18233034 1786168 2281472 22300674 1544802 vmlinux-patched Works peachy on a 256-core system with a 20-bit APIC ID space, and on a 48-core legacy 8-bit APIC ID system. If we care, I can make numa_cpu_node O(1) lookup for typical cases. Signed-off-by: Daniel J Blueman Daniel [1] http://www.intel.com/content/dam/doc/specification-update/64-architecture-x2apic-specification.pdf --- arch/x86/include/asm/numa.h | 13 +++++++------ arch/x86/kernel/cpu/amd.c | 8 ++++---- arch/x86/mm/numa.c | 31 +++++++++++++++++++++++-------- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/arch/x86/include/asm/numa.h b/arch/x86/include/asm/numa.h index 01b493e..33becb8 100644 --- a/arch/x86/include/asm/numa.h +++ b/arch/x86/include/asm/numa.h @@ -17,6 +17,11 @@ */ #define NODE_MIN_SIZE (4*1024*1024) +struct apicid_to_node { + int apicid; + s16 node; +}; + extern int numa_off; /* @@ -27,17 +32,13 @@ extern int numa_off; * should be accessed by the accessors - set_apicid_to_node() and * numa_cpu_node(). */ -extern s16 __apicid_to_node[MAX_LOCAL_APIC]; +extern struct apicid_to_node __apicid_to_node[NR_CPUS]; extern nodemask_t numa_nodes_parsed __initdata; extern int __init numa_add_memblk(int nodeid, u64 start, u64 end); extern void __init numa_set_distance(int from, int to, int distance); -static inline void set_apicid_to_node(int apicid, s16 node) -{ - __apicid_to_node[apicid] = node; -} - +extern void set_apicid_to_node(int apicid, s16 node); extern int numa_cpu_node(int cpu); #else /* CONFIG_NUMA */ diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 4a70fc6..e65c01c 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -277,12 +277,12 @@ static int nearby_node(int apicid) int i, node; for (i = apicid - 1; i >= 0; i--) { - node = __apicid_to_node[i]; + node = __apicid_to_node[i].node; if (node != NUMA_NO_NODE && node_online(node)) return node; } for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) { - node = __apicid_to_node[i]; + node = __apicid_to_node[i].node; if (node != NUMA_NO_NODE && node_online(node)) return node; } @@ -422,8 +422,8 @@ static void srat_detect_node(struct cpuinfo_x86 *c) int ht_nodeid = c->initial_apicid; if (ht_nodeid >= 0 && - __apicid_to_node[ht_nodeid] != NUMA_NO_NODE) - node = __apicid_to_node[ht_nodeid]; + __apicid_to_node[ht_nodeid].node != NUMA_NO_NODE) + node = __apicid_to_node[ht_nodeid].node; /* Pick a nearby node */ if (!node_online(node)) node = nearby_node(apicid); diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index c3b3f65..70f03a0 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c @@ -56,16 +56,34 @@ early_param("numa", numa_setup); /* * apicid, cpu, node mappings */ -s16 __apicid_to_node[MAX_LOCAL_APIC] = { - [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE + +struct apicid_to_node __apicid_to_node[NR_CPUS] = { + [0 ... NR_CPUS-1] = {-1, NUMA_NO_NODE} }; +void set_apicid_to_node(int apicid, s16 node) +{ + static int ent; + + /* Protect against small kernel on large system */ + if (ent >= NR_CPUS) + return; + + __apicid_to_node[ent].apicid = apicid; + __apicid_to_node[ent].node = node; + ent++; +} + int numa_cpu_node(int cpu) { - int apicid = early_per_cpu(x86_cpu_to_apicid, cpu); + int ent, apicid = early_per_cpu(x86_cpu_to_apicid, cpu); + if (apicid == BAD_APICID) + return NUMA_NO_NODE; + + for (ent = 0; ent < NR_CPUS; ent++) + if (__apicid_to_node[ent].apicid == apicid) + return __apicid_to_node[ent].node; - if (apicid != BAD_APICID) - return __apicid_to_node[apicid]; return NUMA_NO_NODE; } @@ -607,9 +625,6 @@ static int __init numa_init(int (*init_func)(void)) int i; int ret; - for (i = 0; i < MAX_LOCAL_APIC; i++) - set_apicid_to_node(i, NUMA_NO_NODE); - nodes_clear(numa_nodes_parsed); nodes_clear(node_possible_map); nodes_clear(node_online_map);