From suresh.b.siddha@intel.com Mon Oct 17 23:52:42 2005 Return-Path: Received: from imap.suse.de ([unix socket]) by imap-dhs (Cyrus v2.1.16) with LMTP; Mon, 17 Oct 2005 23:52:50 +0200 X-Sieve: CMU Sieve 2.2 Received: from Relay1.suse.de (relay1.suse.de [149.44.160.87]) (using TLSv1 with cipher EDH-RSA-DES-CBC3-SHA (168/168 bits)) (Client CN "relay.suse.de", Issuer "SuSE Linux AG internal IMAP-Server CA" (verified OK)) by imap.suse.de (Postfix) with ESMTP id D8BC42ECA4A for ; Mon, 17 Oct 2005 23:52:50 +0200 (CEST) Received: by Relay1.suse.de (Postfix) id C98EC2BEF7; Mon, 17 Oct 2005 23:52:50 +0200 (CEST) Received: from Relay1.suse.de (localhost [127.0.0.1]) by Relay1.suse.de (Postfix) with ESMTP id BBF912BEF5 for ; Mon, 17 Oct 2005 23:52:50 +0200 (CEST) Received: from Relay1.suse.de ([127.0.0.1]) by Relay1.suse.de (Relay1 [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 11997-03 for ; Mon, 17 Oct 2005 23:52:50 +0200 (CEST) Received: from mx1.suse.de (mail.suse.de [195.135.220.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by Relay1.suse.de (Postfix) with ESMTP id 639E82973D for ; Mon, 17 Oct 2005 23:52:50 +0200 (CEST) Received: from scsfmr003.sc.intel.com (fmr23.intel.com [143.183.121.15]) by mx1.suse.de (Postfix) with ESMTP id ED5C6EC3C for ; Mon, 17 Oct 2005 23:52:49 +0200 (CEST) Received: from scsfmr100.sc.intel.com (scsfmr100.sc.intel.com [10.3.253.9]) by scsfmr003.sc.intel.com (8.12.10/8.12.10/d: major-outer.mc,v 1.1 2004/09/17 17:50:56 root Exp $) with ESMTP id j9HLqgmE029541; Mon, 17 Oct 2005 21:52:42 GMT Received: from unix-os.sc.intel.com (unix-os.sc.intel.com [172.25.110.7]) by scsfmr100.sc.intel.com (8.12.10/8.12.10/d: major-inner.mc,v 1.2 2004/09/17 18:05:01 root Exp $) with ESMTP id j9HLqjFE002099; Mon, 17 Oct 2005 21:52:45 GMT Received: (from sbsiddha@localhost) by unix-os.sc.intel.com (8.11.6/8.11.2) id j9HLqgP14072; Mon, 17 Oct 2005 14:52:42 -0700 Date: Mon, 17 Oct 2005 14:52:42 -0700 From: "Siddha, Suresh B" To: akpm@osdl.org Cc: ak@suse.de Subject: [Patch 2/2] x86, x86_64: fix Intel cache detection code assumption about threads sharing Message-ID: <20051017145242.C13206@unix-os.sc.intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i X-Virus-Scanned: by amavisd-new at Relay1.suse.de X-Spam-Status: No, hits=-1.2 tagged_above=-20.0 required=5.0 tests=BAYES_40, MY_LINUX X-Spam-Level: X-UID: 70476 X-Length: 5504 Fix the Intel cache detection code assumption that number of threads sharing the cache will either be equal to number of HT or core siblings. Signed-off-by: Suresh Siddha Index: linux/arch/i386/kernel/cpu/intel_cacheinfo.c =================================================================== --- linux.orig/arch/i386/kernel/cpu/intel_cacheinfo.c +++ linux/arch/i386/kernel/cpu/intel_cacheinfo.c @@ -303,29 +303,45 @@ static struct _cpuid4_info *cpuid4_info[ #ifdef CONFIG_SMP static void __devinit cache_shared_cpu_map_setup(unsigned int cpu, int index) { - struct _cpuid4_info *this_leaf; + struct _cpuid4_info *this_leaf, *sibling_leaf; unsigned long num_threads_sharing; -#ifdef CONFIG_X86_HT - struct cpuinfo_x86 *c = cpu_data + cpu; -#endif + int index_msb, i; + struct cpuinfo_x86 *c = cpu_data; this_leaf = CPUID4_INFO_IDX(cpu, index); num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; if (num_threads_sharing == 1) cpu_set(cpu, this_leaf->shared_cpu_map); -#ifdef CONFIG_X86_HT - else if (num_threads_sharing == smp_num_siblings) - this_leaf->shared_cpu_map = cpu_sibling_map[cpu]; - else if (num_threads_sharing == (c->x86_max_cores * smp_num_siblings)) - this_leaf->shared_cpu_map = cpu_core_map[cpu]; - else - printk(KERN_DEBUG "Number of CPUs sharing cache didn't match " - "any known set of CPUs\n"); -#endif + else { + index_msb = get_count_order(num_threads_sharing); + + for_each_online_cpu(i) { + if (c[i].apicid >> index_msb == + c[cpu].apicid >> index_msb) { + cpu_set(i, this_leaf->shared_cpu_map); + if (i != cpu && cpuid4_info[i]) { + sibling_leaf = CPUID4_INFO_IDX(i, index); + cpu_set(cpu, sibling_leaf->shared_cpu_map); + } + } + } + } +} +static void __devinit cache_remove_shared_cpu_map(unsigned int cpu, int index) +{ + struct _cpuid4_info *this_leaf, *sibling_leaf; + int sibling; + + this_leaf = CPUID4_INFO_IDX(cpu, index); + for_each_cpu_mask(sibling, this_leaf->shared_cpu_map) { + sibling_leaf = CPUID4_INFO_IDX(sibling, index); + cpu_clear(cpu, sibling_leaf->shared_cpu_map); + } } #else static void __init cache_shared_cpu_map_setup(unsigned int cpu, int index) {} +static void __init cache_remove_shared_cpu_map(unsigned int cpu, int index) {} #endif static void free_cache_attributes(unsigned int cpu) @@ -584,8 +600,10 @@ static int __devexit cache_remove_dev(st unsigned int cpu = sys_dev->id; unsigned long i; - for (i = 0; i < num_cache_leaves; i++) + for (i = 0; i < num_cache_leaves; i++) { + cache_remove_shared_cpu_map(cpu, i); kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); + } kobject_unregister(cache_kobject[cpu]); cpuid4_cache_sysfs_exit(cpu); return 0;