Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 521
b: refs/heads/master
c: e927ecb
h: refs/heads/master
i:
  519: f0a750c
v: v3
  • Loading branch information
Suresh Siddha authored and Tony Luck committed Apr 25, 2005
1 parent 5033746 commit 270998a
Show file tree
Hide file tree
Showing 7 changed files with 366 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6118ec847e8e35393efc0f88394c2f5dd48c3313
refs/heads/master: e927ecb05e1ce4bbb1e10f57008c94994e2160f5
69 changes: 67 additions & 2 deletions trunk/arch/ia64/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@
* Copyright (C) 1998-2001, 2003-2004 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
* Stephane Eranian <eranian@hpl.hp.com>
* Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com>
* Copyright (C) 2000, 2004 Intel Corp
* Rohit Seth <rohit.seth@intel.com>
* Suresh Siddha <suresh.b.siddha@intel.com>
* Gordon Jin <gordon.jin@intel.com>
* Copyright (C) 1999 VA Linux Systems
* Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
*
* 12/26/04 S.Siddha, G.Jin, R.Seth
* Add multi-threading and multi-core detection
* 11/12/01 D.Mosberger Convert get_cpuinfo() to seq_file based show_cpuinfo().
* 04/04/00 D.Mosberger renamed cpu_initialized to cpu_online_map
* 03/31/00 R.Seth cpu_initialized and current->processor fixes
Expand Down Expand Up @@ -296,6 +301,34 @@ mark_bsp_online (void)
#endif
}

#ifdef CONFIG_SMP
static void
check_for_logical_procs (void)
{
pal_logical_to_physical_t info;
s64 status;

status = ia64_pal_logical_to_phys(0, &info);
if (status == -1) {
printk(KERN_INFO "No logical to physical processor mapping "
"available\n");
return;
}
if (status) {
printk(KERN_ERR "ia64_pal_logical_to_phys failed with %ld\n",
status);
return;
}
/*
* Total number of siblings that BSP has. Though not all of them
* may have booted successfully. The correct number of siblings
* booted is in info.overview_num_log.
*/
smp_num_siblings = info.overview_tpc;
smp_num_cpucores = info.overview_cpp;
}
#endif

void __init
setup_arch (char **cmdline_p)
{
Expand Down Expand Up @@ -356,6 +389,19 @@ setup_arch (char **cmdline_p)

#ifdef CONFIG_SMP
cpu_physical_id(0) = hard_smp_processor_id();

cpu_set(0, cpu_sibling_map[0]);
cpu_set(0, cpu_core_map[0]);

check_for_logical_procs();
if (smp_num_cpucores > 1)
printk(KERN_INFO
"cpu package is Multi-Core capable: number of cores=%d\n",
smp_num_cpucores);
if (smp_num_siblings > 1)
printk(KERN_INFO
"cpu package is Multi-Threading capable: number of siblings=%d\n",
smp_num_siblings);
#endif

cpu_init(); /* initialize the bootstrap CPU */
Expand Down Expand Up @@ -459,12 +505,23 @@ show_cpuinfo (struct seq_file *m, void *v)
"cpu regs : %u\n"
"cpu MHz : %lu.%06lu\n"
"itc MHz : %lu.%06lu\n"
"BogoMIPS : %lu.%02lu\n\n",
"BogoMIPS : %lu.%02lu\n",
cpunum, c->vendor, family, c->model, c->revision, c->archrev,
features, c->ppn, c->number,
c->proc_freq / 1000000, c->proc_freq % 1000000,
c->itc_freq / 1000000, c->itc_freq % 1000000,
lpj*HZ/500000, (lpj*HZ/5000) % 100);
#ifdef CONFIG_SMP
if (c->threads_per_core > 1 || c->cores_per_socket > 1)
seq_printf(m,
"physical id: %u\n"
"core id : %u\n"
"thread id : %u\n",
c->socket_id, c->core_id, c->thread_id);
seq_printf(m, "siblings : %u\n", c->num_log);
#endif
seq_printf(m,"\n");

return 0;
}

Expand Down Expand Up @@ -533,6 +590,14 @@ identify_cpu (struct cpuinfo_ia64 *c)
memcpy(c->vendor, cpuid.field.vendor, 16);
#ifdef CONFIG_SMP
c->cpu = smp_processor_id();

/* below default values will be overwritten by identify_siblings()
* for Multi-Threading/Multi-Core capable cpu's
*/
c->threads_per_core = c->cores_per_socket = c->num_log = 1;
c->socket_id = -1;

identify_siblings(c);
#endif
c->ppn = cpuid.field.ppn;
c->number = cpuid.field.number;
Expand Down
206 changes: 206 additions & 0 deletions trunk/arch/ia64/kernel/smpboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,23 @@
*
* Copyright (C) 1998-2003, 2005 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
* Copyright (C) 2001, 2004-2005 Intel Corp
* Rohit Seth <rohit.seth@intel.com>
* Suresh Siddha <suresh.b.siddha@intel.com>
* Gordon Jin <gordon.jin@intel.com>
* Ashok Raj <ashok.raj@intel.com>
*
* 01/05/16 Rohit Seth <rohit.seth@intel.com> Moved SMP booting functions from smp.c to here.
* 01/04/27 David Mosberger <davidm@hpl.hp.com> Added ITC synching code.
* 02/07/31 David Mosberger <davidm@hpl.hp.com> Switch over to hotplug-CPU boot-sequence.
* smp_boot_cpus()/smp_commence() is replaced by
* smp_prepare_cpus()/__cpu_up()/smp_cpus_done().
* 04/06/21 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support
* 04/12/26 Jin Gordon <gordon.jin@intel.com>
* 04/12/26 Rohit Seth <rohit.seth@intel.com>
* Add multi-threading and multi-core detection
* 05/01/30 Suresh Siddha <suresh.b.siddha@intel.com>
* Setup cpu_sibling_map and cpu_core_map
*/
#include <linux/config.h>

Expand Down Expand Up @@ -122,6 +132,11 @@ EXPORT_SYMBOL(cpu_online_map);
cpumask_t cpu_possible_map;
EXPORT_SYMBOL(cpu_possible_map);

cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
int smp_num_siblings = 1;
int smp_num_cpucores = 1;

/* which logical CPU number maps to which CPU (physical APIC ID) */
volatile int ia64_cpu_to_sapicid[NR_CPUS];
EXPORT_SYMBOL(ia64_cpu_to_sapicid);
Expand Down Expand Up @@ -598,7 +613,68 @@ void __devinit smp_prepare_boot_cpu(void)
cpu_set(smp_processor_id(), cpu_callin_map);
}

/*
* mt_info[] is a temporary store for all info returned by
* PAL_LOGICAL_TO_PHYSICAL, to be copied into cpuinfo_ia64 when the
* specific cpu comes.
*/
static struct {
__u32 socket_id;
__u16 core_id;
__u16 thread_id;
__u16 proc_fixed_addr;
__u8 valid;
}mt_info[NR_CPUS] __devinit;

#ifdef CONFIG_HOTPLUG_CPU
static inline void
remove_from_mtinfo(int cpu)
{
int i;

for_each_cpu(i)
if (mt_info[i].valid && mt_info[i].socket_id ==
cpu_data(cpu)->socket_id)
mt_info[i].valid = 0;
}

static inline void
clear_cpu_sibling_map(int cpu)
{
int i;

for_each_cpu_mask(i, cpu_sibling_map[cpu])
cpu_clear(cpu, cpu_sibling_map[i]);
for_each_cpu_mask(i, cpu_core_map[cpu])
cpu_clear(cpu, cpu_core_map[i]);

cpu_sibling_map[cpu] = cpu_core_map[cpu] = CPU_MASK_NONE;
}

static void
remove_siblinginfo(int cpu)
{
int last = 0;

if (cpu_data(cpu)->threads_per_core == 1 &&
cpu_data(cpu)->cores_per_socket == 1) {
cpu_clear(cpu, cpu_core_map[cpu]);
cpu_clear(cpu, cpu_sibling_map[cpu]);
return;
}

last = (cpus_weight(cpu_core_map[cpu]) == 1 ? 1 : 0);

/* remove it from all sibling map's */
clear_cpu_sibling_map(cpu);

/* if this cpu is the last in the core group, remove all its info
* from mt_info structure
*/
if (last)
remove_from_mtinfo(cpu);
}

extern void fixup_irqs(void);
/* must be called with cpucontrol mutex held */
int __cpu_disable(void)
Expand All @@ -611,6 +687,7 @@ int __cpu_disable(void)
if (cpu == 0)
return -EBUSY;

remove_siblinginfo(cpu);
fixup_irqs();
local_flush_tlb_all();
cpu_clear(cpu, cpu_callin_map);
Expand Down Expand Up @@ -663,6 +740,23 @@ smp_cpus_done (unsigned int dummy)
(int)num_online_cpus(), bogosum/(500000/HZ), (bogosum/(5000/HZ))%100);
}

static inline void __devinit
set_cpu_sibling_map(int cpu)
{
int i;

for_each_online_cpu(i) {
if ((cpu_data(cpu)->socket_id == cpu_data(i)->socket_id)) {
cpu_set(i, cpu_core_map[cpu]);
cpu_set(cpu, cpu_core_map[i]);
if (cpu_data(cpu)->core_id == cpu_data(i)->core_id) {
cpu_set(i, cpu_sibling_map[cpu]);
cpu_set(cpu, cpu_sibling_map[i]);
}
}
}
}

int __devinit
__cpu_up (unsigned int cpu)
{
Expand All @@ -685,6 +779,15 @@ __cpu_up (unsigned int cpu)
if (ret < 0)
return ret;

if (cpu_data(cpu)->threads_per_core == 1 &&
cpu_data(cpu)->cores_per_socket == 1) {
cpu_set(cpu, cpu_sibling_map[cpu]);
cpu_set(cpu, cpu_core_map[cpu]);
return 0;
}

set_cpu_sibling_map(cpu);

return 0;
}

Expand Down Expand Up @@ -712,3 +815,106 @@ init_smp_config(void)
ia64_sal_strerror(sal_ret));
}

static inline int __devinit
check_for_mtinfo_index(void)
{
int i;

for_each_cpu(i)
if (!mt_info[i].valid)
return i;

return -1;
}

/*
* Search the mt_info to find out if this socket's cid/tid information is
* cached or not. If the socket exists, fill in the core_id and thread_id
* in cpuinfo
*/
static int __devinit
check_for_new_socket(__u16 logical_address, struct cpuinfo_ia64 *c)
{
int i;
__u32 sid = c->socket_id;

for_each_cpu(i) {
if (mt_info[i].valid && mt_info[i].proc_fixed_addr == logical_address
&& mt_info[i].socket_id == sid) {
c->core_id = mt_info[i].core_id;
c->thread_id = mt_info[i].thread_id;
return 1; /* not a new socket */
}
}
return 0;
}

/*
* identify_siblings(cpu) gets called from identify_cpu. This populates the
* information related to logical execution units in per_cpu_data structure.
*/
void __devinit
identify_siblings(struct cpuinfo_ia64 *c)
{
s64 status;
u16 pltid;
u64 proc_fixed_addr;
int count, i;
pal_logical_to_physical_t info;

if (smp_num_cpucores == 1 && smp_num_siblings == 1)
return;

if ((status = ia64_pal_logical_to_phys(0, &info)) != PAL_STATUS_SUCCESS) {
printk(KERN_ERR "ia64_pal_logical_to_phys failed with %ld\n",
status);
return;
}
if ((status = ia64_sal_physical_id_info(&pltid)) != PAL_STATUS_SUCCESS) {
printk(KERN_ERR "ia64_sal_pltid failed with %ld\n", status);
return;
}
if ((status = ia64_pal_fixed_addr(&proc_fixed_addr)) != PAL_STATUS_SUCCESS) {
printk(KERN_ERR "ia64_pal_fixed_addr failed with %ld\n", status);
return;
}

c->socket_id = (pltid << 8) | info.overview_ppid;
c->cores_per_socket = info.overview_cpp;
c->threads_per_core = info.overview_tpc;
count = c->num_log = info.overview_num_log;

/* If the thread and core id information is already cached, then
* we will simply update cpu_info and return. Otherwise, we will
* do the PAL calls and cache core and thread id's of all the siblings.
*/
if (check_for_new_socket(proc_fixed_addr, c))
return;

for (i = 0; i < count; i++) {
int index;

if (i && (status = ia64_pal_logical_to_phys(i, &info))
!= PAL_STATUS_SUCCESS) {
printk(KERN_ERR "ia64_pal_logical_to_phys failed"
" with %ld\n", status);
return;
}
if (info.log2_la == proc_fixed_addr) {
c->core_id = info.log1_cid;
c->thread_id = info.log1_tid;
}

index = check_for_mtinfo_index();
/* We will not do the mt_info caching optimization in this case.
*/
if (index < 0)
continue;

mt_info[index].valid = 1;
mt_info[index].socket_id = c->socket_id;
mt_info[index].core_id = info.log1_cid;
mt_info[index].thread_id = info.log1_tid;
mt_info[index].proc_fixed_addr = info.log2_la;
}
}
Loading

0 comments on commit 270998a

Please sign in to comment.