aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/smpboot.c
diff options
context:
space:
mode:
authorFenghua Yu <fenghua.yu@intel.com>2006-02-27 19:16:22 -0500
committerTony Luck <tony.luck@intel.com>2006-03-24 16:15:23 -0500
commit4129a953ad4db379d8e07b0dd2157998653a1325 (patch)
tree84c6d310953044caa420410165adcd0dfb2ac55f /arch/ia64/kernel/smpboot.c
parent4d357acadd7a5e60767c748ed7807e11c4387bdf (diff)
[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: Fenghua Yu <fenghua.yu@intel.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/kernel/smpboot.c')
-rw-r--r--arch/ia64/kernel/smpboot.c109
1 files changed, 4 insertions, 105 deletions
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index c4b633b36dab..44e9547878ac 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -624,32 +624,8 @@ void __devinit smp_prepare_boot_cpu(void)
624 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; 624 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
625} 625}
626 626
627/*
628 * mt_info[] is a temporary store for all info returned by
629 * PAL_LOGICAL_TO_PHYSICAL, to be copied into cpuinfo_ia64 when the
630 * specific cpu comes.
631 */
632static struct {
633 __u32 socket_id;
634 __u16 core_id;
635 __u16 thread_id;
636 __u16 proc_fixed_addr;
637 __u8 valid;
638} mt_info[NR_CPUS] __devinitdata;
639
640#ifdef CONFIG_HOTPLUG_CPU 627#ifdef CONFIG_HOTPLUG_CPU
641static inline void 628static inline void
642remove_from_mtinfo(int cpu)
643{
644 int i;
645
646 for_each_cpu(i)
647 if (mt_info[i].valid && mt_info[i].socket_id ==
648 cpu_data(cpu)->socket_id)
649 mt_info[i].valid = 0;
650}
651
652static inline void
653clear_cpu_sibling_map(int cpu) 629clear_cpu_sibling_map(int cpu)
654{ 630{
655 int i; 631 int i;
@@ -678,12 +654,6 @@ remove_siblinginfo(int cpu)
678 654
679 /* remove it from all sibling map's */ 655 /* remove it from all sibling map's */
680 clear_cpu_sibling_map(cpu); 656 clear_cpu_sibling_map(cpu);
681
682 /* if this cpu is the last in the core group, remove all its info
683 * from mt_info structure
684 */
685 if (last)
686 remove_from_mtinfo(cpu);
687} 657}
688 658
689extern void fixup_irqs(void); 659extern void fixup_irqs(void);
@@ -878,40 +848,6 @@ init_smp_config(void)
878 ia64_sal_strerror(sal_ret)); 848 ia64_sal_strerror(sal_ret));
879} 849}
880 850
881static inline int __devinit
882check_for_mtinfo_index(void)
883{
884 int i;
885
886 for_each_cpu(i)
887 if (!mt_info[i].valid)
888 return i;
889
890 return -1;
891}
892
893/*
894 * Search the mt_info to find out if this socket's cid/tid information is
895 * cached or not. If the socket exists, fill in the core_id and thread_id
896 * in cpuinfo
897 */
898static int __devinit
899check_for_new_socket(__u16 logical_address, struct cpuinfo_ia64 *c)
900{
901 int i;
902 __u32 sid = c->socket_id;
903
904 for_each_cpu(i) {
905 if (mt_info[i].valid && mt_info[i].proc_fixed_addr == logical_address
906 && mt_info[i].socket_id == sid) {
907 c->core_id = mt_info[i].core_id;
908 c->thread_id = mt_info[i].thread_id;
909 return 1; /* not a new socket */
910 }
911 }
912 return 0;
913}
914
915/* 851/*
916 * identify_siblings(cpu) gets called from identify_cpu. This populates the 852 * identify_siblings(cpu) gets called from identify_cpu. This populates the
917 * information related to logical execution units in per_cpu_data structure. 853 * information related to logical execution units in per_cpu_data structure.
@@ -921,14 +857,12 @@ identify_siblings(struct cpuinfo_ia64 *c)
921{ 857{
922 s64 status; 858 s64 status;
923 u16 pltid; 859 u16 pltid;
924 u64 proc_fixed_addr;
925 int count, i;
926 pal_logical_to_physical_t info; 860 pal_logical_to_physical_t info;
927 861
928 if (smp_num_cpucores == 1 && smp_num_siblings == 1) 862 if (smp_num_cpucores == 1 && smp_num_siblings == 1)
929 return; 863 return;
930 864
931 if ((status = ia64_pal_logical_to_phys(0, &info)) != PAL_STATUS_SUCCESS) { 865 if ((status = ia64_pal_logical_to_phys(-1, &info)) != PAL_STATUS_SUCCESS) {
932 printk(KERN_ERR "ia64_pal_logical_to_phys failed with %ld\n", 866 printk(KERN_ERR "ia64_pal_logical_to_phys failed with %ld\n",
933 status); 867 status);
934 return; 868 return;
@@ -937,47 +871,12 @@ identify_siblings(struct cpuinfo_ia64 *c)
937 printk(KERN_ERR "ia64_sal_pltid failed with %ld\n", status); 871 printk(KERN_ERR "ia64_sal_pltid failed with %ld\n", status);
938 return; 872 return;
939 } 873 }
940 if ((status = ia64_pal_fixed_addr(&proc_fixed_addr)) != PAL_STATUS_SUCCESS) {
941 printk(KERN_ERR "ia64_pal_fixed_addr failed with %ld\n", status);
942 return;
943 }
944 874
945 c->socket_id = (pltid << 8) | info.overview_ppid; 875 c->socket_id = (pltid << 8) | info.overview_ppid;
946 c->cores_per_socket = info.overview_cpp; 876 c->cores_per_socket = info.overview_cpp;
947 c->threads_per_core = info.overview_tpc; 877 c->threads_per_core = info.overview_tpc;
948 count = c->num_log = info.overview_num_log; 878 c->num_log = info.overview_num_log;
949 879
950 /* If the thread and core id information is already cached, then 880 c->core_id = info.log1_cid;
951 * we will simply update cpu_info and return. Otherwise, we will 881 c->thread_id = info.log1_tid;
952 * do the PAL calls and cache core and thread id's of all the siblings.
953 */
954 if (check_for_new_socket(proc_fixed_addr, c))
955 return;
956
957 for (i = 0; i < count; i++) {
958 int index;
959
960 if (i && (status = ia64_pal_logical_to_phys(i, &info))
961 != PAL_STATUS_SUCCESS) {
962 printk(KERN_ERR "ia64_pal_logical_to_phys failed"
963 " with %ld\n", status);
964 return;
965 }
966 if (info.log2_la == proc_fixed_addr) {
967 c->core_id = info.log1_cid;
968 c->thread_id = info.log1_tid;
969 }
970
971 index = check_for_mtinfo_index();
972 /* We will not do the mt_info caching optimization in this case.
973 */
974 if (index < 0)
975 continue;
976
977 mt_info[index].valid = 1;
978 mt_info[index].socket_id = c->socket_id;
979 mt_info[index].core_id = info.log1_cid;
980 mt_info[index].thread_id = info.log1_tid;
981 mt_info[index].proc_fixed_addr = info.log2_la;
982 }
983} 882}