diff options
author | Fenghua Yu <fenghua.yu@intel.com> | 2006-02-27 19:16:22 -0500 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2006-03-24 16:15:23 -0500 |
commit | 4129a953ad4db379d8e07b0dd2157998653a1325 (patch) | |
tree | 84c6d310953044caa420410165adcd0dfb2ac55f /arch/ia64/kernel | |
parent | 4d357acadd7a5e60767c748ed7807e11c4387bdf (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')
-rw-r--r-- | arch/ia64/kernel/smpboot.c | 109 |
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 | */ | ||
632 | static 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 |
641 | static inline void | 628 | static inline void |
642 | remove_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 | |||
652 | static inline void | ||
653 | clear_cpu_sibling_map(int cpu) | 629 | clear_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 | ||
689 | extern void fixup_irqs(void); | 659 | extern 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 | ||
881 | static inline int __devinit | ||
882 | check_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 | */ | ||
898 | static int __devinit | ||
899 | check_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 | } |