Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4129a953 authored by Fenghua Yu's avatar Fenghua Yu Committed by Tony Luck
Browse files

[IA64] New IA64 core/thread detection patch



IPF SDM 2.2 changes definition of PAL_LOGICAL_TO_PHYSICAL to add
proc_number=-1 to get core/thread mapping info on the running processer.

Based on this change, we had better to update existing core/thread
detection in IA64 kernel correspondingly. The attached patch implements
this change. It simplifies detection code and eliminates potential race
condition. It also runs a bit faster and has better scalability especially
when cores and threads number grows up in one package.

Signed-off-by: default avatarFenghua Yu <fenghua.yu@intel.com>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent 4d357aca
Loading
Loading
Loading
Loading
+4 −105
Original line number Diff line number Diff line
@@ -624,31 +624,7 @@ void __devinit smp_prepare_boot_cpu(void)
	per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
}

/*
 * 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] __devinitdata;

#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)
{
@@ -678,12 +654,6 @@ remove_siblinginfo(int cpu)

	/* 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);
@@ -878,40 +848,6 @@ 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.
@@ -921,14 +857,12 @@ 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) {
	if ((status = ia64_pal_logical_to_phys(-1, &info)) != PAL_STATUS_SUCCESS) {
		printk(KERN_ERR "ia64_pal_logical_to_phys failed with %ld\n",
		       status);
		return;
@@ -937,47 +871,12 @@ identify_siblings(struct cpuinfo_ia64 *c)
		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;
	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;
	}
}
+1 −2
Original line number Diff line number Diff line
@@ -1640,7 +1640,6 @@ ia64_pal_logical_to_phys(u64 proc_number, pal_logical_to_physical_t *mapping)

	if (iprv.status == PAL_STATUS_SUCCESS)
	{
		if (proc_number == 0)
		mapping->overview.overview_data = iprv.v0;
		mapping->ppli1.ppli1_data = iprv.v1;
		mapping->ppli2.ppli2_data = iprv.v2;