Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
3384c786
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
3384c786
编写于
6月 03, 2019
作者:
I
Ingo Molnar
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'x86/topology' into perf/core, to prepare for new patches
Signed-off-by:
N
Ingo Molnar
<
mingo@kernel.org
>
上级
6a9f4efe
eb876fbc
变更
19
隐藏空白更改
内联
并排
Showing
19 changed file
with
422 addition
and
214 deletion
+422
-214
Documentation/cputopology.txt
Documentation/cputopology.txt
+33
-15
Documentation/x86/topology.rst
Documentation/x86/topology.rst
+4
-0
arch/x86/events/intel/cstate.c
arch/x86/events/intel/cstate.c
+10
-4
arch/x86/events/intel/rapl.c
arch/x86/events/intel/rapl.c
+10
-10
arch/x86/events/intel/uncore.c
arch/x86/events/intel/uncore.c
+41
-39
arch/x86/events/intel/uncore.h
arch/x86/events/intel/uncore.h
+2
-2
arch/x86/events/intel/uncore_snbep.c
arch/x86/events/intel/uncore_snbep.c
+2
-2
arch/x86/include/asm/processor.h
arch/x86/include/asm/processor.h
+3
-1
arch/x86/include/asm/smp.h
arch/x86/include/asm/smp.h
+1
-0
arch/x86/include/asm/topology.h
arch/x86/include/asm/topology.h
+17
-0
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/common.c
+1
-0
arch/x86/kernel/cpu/topology.c
arch/x86/kernel/cpu/topology.c
+69
-19
arch/x86/kernel/smpboot.c
arch/x86/kernel/smpboot.c
+69
-0
arch/x86/xen/smp_pv.c
arch/x86/xen/smp_pv.c
+1
-0
drivers/base/topology.c
drivers/base/topology.c
+22
-0
drivers/hwmon/coretemp.c
drivers/hwmon/coretemp.c
+18
-18
drivers/powercap/intel_rapl.c
drivers/powercap/intel_rapl.c
+41
-34
drivers/thermal/intel/x86_pkg_temp_thermal.c
drivers/thermal/intel/x86_pkg_temp_thermal.c
+72
-70
include/linux/topology.h
include/linux/topology.h
+6
-0
未找到文件。
Documentation/cputopology.txt
浏览文件 @
3384c786
...
@@ -12,6 +12,12 @@ physical_package_id:
...
@@ -12,6 +12,12 @@ physical_package_id:
socket number, but the actual value is architecture and platform
socket number, but the actual value is architecture and platform
dependent.
dependent.
die_id:
the CPU die ID of cpuX. Typically it is the hardware platform's
identifier (rather than the kernel's). The actual value is
architecture and platform dependent.
core_id:
core_id:
the CPU core ID of cpuX. Typically it is the hardware platform's
the CPU core ID of cpuX. Typically it is the hardware platform's
...
@@ -30,25 +36,33 @@ drawer_id:
...
@@ -30,25 +36,33 @@ drawer_id:
identifier (rather than the kernel's). The actual value is
identifier (rather than the kernel's). The actual value is
architecture and platform dependent.
architecture and platform dependent.
thread_sibling
s:
core_cpu
s:
internal kernel map of
cpuX's hardware threads within the same
internal kernel map of
CPUs within the same core.
core as cpuX.
(deprecated name: "thread_siblings")
thread_sibling
s_list:
core_cpu
s_list:
human-readable list of
cpuX's hardware threads within the same
human-readable list of
CPUs within the same core.
core as cpuX.
(deprecated name: "thread_siblings_list");
core_sibling
s:
package_cpu
s:
internal kernel map of
cpuX's hardware threads within the same
internal kernel map of
the CPUs sharing the same physical_package_id.
physical_package_id.
(deprecated name: "core_siblings")
core_sibling
s_list:
package_cpu
s_list:
human-readable list of cpuX's hardware threads within the same
human-readable list of CPUs sharing the same physical_package_id.
physical_package_id.
(deprecated name: "core_siblings_list")
die_cpus:
internal kernel map of CPUs within the same die.
die_cpus_list:
human-readable list of CPUs within the same die.
book_siblings:
book_siblings:
...
@@ -81,11 +95,13 @@ For an architecture to support this feature, it must define some of
...
@@ -81,11 +95,13 @@ For an architecture to support this feature, it must define some of
these macros in include/asm-XXX/topology.h::
these macros in include/asm-XXX/topology.h::
#define topology_physical_package_id(cpu)
#define topology_physical_package_id(cpu)
#define topology_die_id(cpu)
#define topology_core_id(cpu)
#define topology_core_id(cpu)
#define topology_book_id(cpu)
#define topology_book_id(cpu)
#define topology_drawer_id(cpu)
#define topology_drawer_id(cpu)
#define topology_sibling_cpumask(cpu)
#define topology_sibling_cpumask(cpu)
#define topology_core_cpumask(cpu)
#define topology_core_cpumask(cpu)
#define topology_die_cpumask(cpu)
#define topology_book_cpumask(cpu)
#define topology_book_cpumask(cpu)
#define topology_drawer_cpumask(cpu)
#define topology_drawer_cpumask(cpu)
...
@@ -99,9 +115,11 @@ provides default definitions for any of the above macros that are
...
@@ -99,9 +115,11 @@ provides default definitions for any of the above macros that are
not defined by include/asm-XXX/topology.h:
not defined by include/asm-XXX/topology.h:
1) topology_physical_package_id: -1
1) topology_physical_package_id: -1
2) topology_core_id: 0
2) topology_die_id: -1
3) topology_sibling_cpumask: just the given CPU
3) topology_core_id: 0
4) topology_core_cpumask: just the given CPU
4) topology_sibling_cpumask: just the given CPU
5) topology_core_cpumask: just the given CPU
6) topology_die_cpumask: just the given CPU
For architectures that don't support books (CONFIG_SCHED_BOOK) there are no
For architectures that don't support books (CONFIG_SCHED_BOOK) there are no
default definitions for topology_book_id() and topology_book_cpumask().
default definitions for topology_book_id() and topology_book_cpumask().
...
...
Documentation/x86/topology.rst
浏览文件 @
3384c786
...
@@ -49,6 +49,10 @@ Package-related topology information in the kernel:
...
@@ -49,6 +49,10 @@ Package-related topology information in the kernel:
The number of cores in a package. This information is retrieved via CPUID.
The number of cores in a package. This information is retrieved via CPUID.
- cpuinfo_x86.x86_max_dies:
The number of dies in a package. This information is retrieved via CPUID.
- cpuinfo_x86.phys_proc_id:
- cpuinfo_x86.phys_proc_id:
The physical ID of the package. This information is retrieved via CPUID
The physical ID of the package. This information is retrieved via CPUID
...
...
arch/x86/events/intel/cstate.c
浏览文件 @
3384c786
...
@@ -302,7 +302,7 @@ static int cstate_pmu_event_init(struct perf_event *event)
...
@@ -302,7 +302,7 @@ static int cstate_pmu_event_init(struct perf_event *event)
return
-
EINVAL
;
return
-
EINVAL
;
event
->
hw
.
event_base
=
pkg_msr
[
cfg
].
msr
;
event
->
hw
.
event_base
=
pkg_msr
[
cfg
].
msr
;
cpu
=
cpumask_any_and
(
&
cstate_pkg_cpu_mask
,
cpu
=
cpumask_any_and
(
&
cstate_pkg_cpu_mask
,
topology_
cor
e_cpumask
(
event
->
cpu
));
topology_
di
e_cpumask
(
event
->
cpu
));
}
else
{
}
else
{
return
-
ENOENT
;
return
-
ENOENT
;
}
}
...
@@ -385,7 +385,7 @@ static int cstate_cpu_exit(unsigned int cpu)
...
@@ -385,7 +385,7 @@ static int cstate_cpu_exit(unsigned int cpu)
if
(
has_cstate_pkg
&&
if
(
has_cstate_pkg
&&
cpumask_test_and_clear_cpu
(
cpu
,
&
cstate_pkg_cpu_mask
))
{
cpumask_test_and_clear_cpu
(
cpu
,
&
cstate_pkg_cpu_mask
))
{
target
=
cpumask_any_but
(
topology_
cor
e_cpumask
(
cpu
),
cpu
);
target
=
cpumask_any_but
(
topology_
di
e_cpumask
(
cpu
),
cpu
);
/* Migrate events if there is a valid target */
/* Migrate events if there is a valid target */
if
(
target
<
nr_cpu_ids
)
{
if
(
target
<
nr_cpu_ids
)
{
cpumask_set_cpu
(
target
,
&
cstate_pkg_cpu_mask
);
cpumask_set_cpu
(
target
,
&
cstate_pkg_cpu_mask
);
...
@@ -414,7 +414,7 @@ static int cstate_cpu_init(unsigned int cpu)
...
@@ -414,7 +414,7 @@ static int cstate_cpu_init(unsigned int cpu)
* in the package cpu mask as the designated reader.
* in the package cpu mask as the designated reader.
*/
*/
target
=
cpumask_any_and
(
&
cstate_pkg_cpu_mask
,
target
=
cpumask_any_and
(
&
cstate_pkg_cpu_mask
,
topology_
cor
e_cpumask
(
cpu
));
topology_
di
e_cpumask
(
cpu
));
if
(
has_cstate_pkg
&&
target
>=
nr_cpu_ids
)
if
(
has_cstate_pkg
&&
target
>=
nr_cpu_ids
)
cpumask_set_cpu
(
cpu
,
&
cstate_pkg_cpu_mask
);
cpumask_set_cpu
(
cpu
,
&
cstate_pkg_cpu_mask
);
...
@@ -663,7 +663,13 @@ static int __init cstate_init(void)
...
@@ -663,7 +663,13 @@ static int __init cstate_init(void)
}
}
if
(
has_cstate_pkg
)
{
if
(
has_cstate_pkg
)
{
err
=
perf_pmu_register
(
&
cstate_pkg_pmu
,
cstate_pkg_pmu
.
name
,
-
1
);
if
(
topology_max_die_per_package
()
>
1
)
{
err
=
perf_pmu_register
(
&
cstate_pkg_pmu
,
"cstate_die"
,
-
1
);
}
else
{
err
=
perf_pmu_register
(
&
cstate_pkg_pmu
,
cstate_pkg_pmu
.
name
,
-
1
);
}
if
(
err
)
{
if
(
err
)
{
has_cstate_pkg
=
false
;
has_cstate_pkg
=
false
;
pr_info
(
"Failed to register cstate pkg pmu
\n
"
);
pr_info
(
"Failed to register cstate pkg pmu
\n
"
);
...
...
arch/x86/events/intel/rapl.c
浏览文件 @
3384c786
...
@@ -149,7 +149,7 @@ struct rapl_pmu {
...
@@ -149,7 +149,7 @@ struct rapl_pmu {
struct
rapl_pmus
{
struct
rapl_pmus
{
struct
pmu
pmu
;
struct
pmu
pmu
;
unsigned
int
max
pkg
;
unsigned
int
max
die
;
struct
rapl_pmu
*
pmus
[];
struct
rapl_pmu
*
pmus
[];
};
};
...
@@ -162,13 +162,13 @@ static u64 rapl_timer_ms;
...
@@ -162,13 +162,13 @@ static u64 rapl_timer_ms;
static
inline
struct
rapl_pmu
*
cpu_to_rapl_pmu
(
unsigned
int
cpu
)
static
inline
struct
rapl_pmu
*
cpu_to_rapl_pmu
(
unsigned
int
cpu
)
{
{
unsigned
int
pkgid
=
topology_logical_packag
e_id
(
cpu
);
unsigned
int
dieid
=
topology_logical_di
e_id
(
cpu
);
/*
/*
* The unsigned check also catches the '-1' return value for non
* The unsigned check also catches the '-1' return value for non
* existent mappings in the topology map.
* existent mappings in the topology map.
*/
*/
return
pkgid
<
rapl_pmus
->
maxpkg
?
rapl_pmus
->
pmus
[
pkg
id
]
:
NULL
;
return
dieid
<
rapl_pmus
->
maxdie
?
rapl_pmus
->
pmus
[
die
id
]
:
NULL
;
}
}
static
inline
u64
rapl_read_counter
(
struct
perf_event
*
event
)
static
inline
u64
rapl_read_counter
(
struct
perf_event
*
event
)
...
@@ -572,7 +572,7 @@ static int rapl_cpu_offline(unsigned int cpu)
...
@@ -572,7 +572,7 @@ static int rapl_cpu_offline(unsigned int cpu)
pmu
->
cpu
=
-
1
;
pmu
->
cpu
=
-
1
;
/* Find a new cpu to collect rapl events */
/* Find a new cpu to collect rapl events */
target
=
cpumask_any_but
(
topology_
cor
e_cpumask
(
cpu
),
cpu
);
target
=
cpumask_any_but
(
topology_
di
e_cpumask
(
cpu
),
cpu
);
/* Migrate rapl events to the new target */
/* Migrate rapl events to the new target */
if
(
target
<
nr_cpu_ids
)
{
if
(
target
<
nr_cpu_ids
)
{
...
@@ -599,14 +599,14 @@ static int rapl_cpu_online(unsigned int cpu)
...
@@ -599,14 +599,14 @@ static int rapl_cpu_online(unsigned int cpu)
pmu
->
timer_interval
=
ms_to_ktime
(
rapl_timer_ms
);
pmu
->
timer_interval
=
ms_to_ktime
(
rapl_timer_ms
);
rapl_hrtimer_init
(
pmu
);
rapl_hrtimer_init
(
pmu
);
rapl_pmus
->
pmus
[
topology_logical_
packag
e_id
(
cpu
)]
=
pmu
;
rapl_pmus
->
pmus
[
topology_logical_
di
e_id
(
cpu
)]
=
pmu
;
}
}
/*
/*
* Check if there is an online cpu in the package which collects rapl
* Check if there is an online cpu in the package which collects rapl
* events already.
* events already.
*/
*/
target
=
cpumask_any_and
(
&
rapl_cpu_mask
,
topology_
cor
e_cpumask
(
cpu
));
target
=
cpumask_any_and
(
&
rapl_cpu_mask
,
topology_
di
e_cpumask
(
cpu
));
if
(
target
<
nr_cpu_ids
)
if
(
target
<
nr_cpu_ids
)
return
0
;
return
0
;
...
@@ -669,22 +669,22 @@ static void cleanup_rapl_pmus(void)
...
@@ -669,22 +669,22 @@ static void cleanup_rapl_pmus(void)
{
{
int
i
;
int
i
;
for
(
i
=
0
;
i
<
rapl_pmus
->
max
pkg
;
i
++
)
for
(
i
=
0
;
i
<
rapl_pmus
->
max
die
;
i
++
)
kfree
(
rapl_pmus
->
pmus
[
i
]);
kfree
(
rapl_pmus
->
pmus
[
i
]);
kfree
(
rapl_pmus
);
kfree
(
rapl_pmus
);
}
}
static
int
__init
init_rapl_pmus
(
void
)
static
int
__init
init_rapl_pmus
(
void
)
{
{
int
max
pkg
=
topology_max_packages
();
int
max
die
=
topology_max_packages
()
*
topology_max_die_per_package
();
size_t
size
;
size_t
size
;
size
=
sizeof
(
*
rapl_pmus
)
+
max
pkg
*
sizeof
(
struct
rapl_pmu
*
);
size
=
sizeof
(
*
rapl_pmus
)
+
max
die
*
sizeof
(
struct
rapl_pmu
*
);
rapl_pmus
=
kzalloc
(
size
,
GFP_KERNEL
);
rapl_pmus
=
kzalloc
(
size
,
GFP_KERNEL
);
if
(
!
rapl_pmus
)
if
(
!
rapl_pmus
)
return
-
ENOMEM
;
return
-
ENOMEM
;
rapl_pmus
->
max
pkg
=
maxpkg
;
rapl_pmus
->
max
die
=
maxdie
;
rapl_pmus
->
pmu
.
attr_groups
=
rapl_attr_groups
;
rapl_pmus
->
pmu
.
attr_groups
=
rapl_attr_groups
;
rapl_pmus
->
pmu
.
task_ctx_nr
=
perf_invalid_context
;
rapl_pmus
->
pmu
.
task_ctx_nr
=
perf_invalid_context
;
rapl_pmus
->
pmu
.
event_init
=
rapl_pmu_event_init
;
rapl_pmus
->
pmu
.
event_init
=
rapl_pmu_event_init
;
...
...
arch/x86/events/intel/uncore.c
浏览文件 @
3384c786
...
@@ -15,7 +15,7 @@ struct pci_driver *uncore_pci_driver;
...
@@ -15,7 +15,7 @@ struct pci_driver *uncore_pci_driver;
DEFINE_RAW_SPINLOCK
(
pci2phy_map_lock
);
DEFINE_RAW_SPINLOCK
(
pci2phy_map_lock
);
struct
list_head
pci2phy_map_head
=
LIST_HEAD_INIT
(
pci2phy_map_head
);
struct
list_head
pci2phy_map_head
=
LIST_HEAD_INIT
(
pci2phy_map_head
);
struct
pci_extra_dev
*
uncore_extra_pci_dev
;
struct
pci_extra_dev
*
uncore_extra_pci_dev
;
static
int
max_
packag
es
;
static
int
max_
di
es
;
/* mask of cpus that collect uncore events */
/* mask of cpus that collect uncore events */
static
cpumask_t
uncore_cpu_mask
;
static
cpumask_t
uncore_cpu_mask
;
...
@@ -101,13 +101,13 @@ ssize_t uncore_event_show(struct kobject *kobj,
...
@@ -101,13 +101,13 @@ ssize_t uncore_event_show(struct kobject *kobj,
struct
intel_uncore_box
*
uncore_pmu_to_box
(
struct
intel_uncore_pmu
*
pmu
,
int
cpu
)
struct
intel_uncore_box
*
uncore_pmu_to_box
(
struct
intel_uncore_pmu
*
pmu
,
int
cpu
)
{
{
unsigned
int
pkgid
=
topology_logical_packag
e_id
(
cpu
);
unsigned
int
dieid
=
topology_logical_di
e_id
(
cpu
);
/*
/*
* The unsigned check also catches the '-1' return value for non
* The unsigned check also catches the '-1' return value for non
* existent mappings in the topology map.
* existent mappings in the topology map.
*/
*/
return
pkgid
<
max_packages
?
pmu
->
boxes
[
pkg
id
]
:
NULL
;
return
dieid
<
max_dies
?
pmu
->
boxes
[
die
id
]
:
NULL
;
}
}
u64
uncore_msr_read_counter
(
struct
intel_uncore_box
*
box
,
struct
perf_event
*
event
)
u64
uncore_msr_read_counter
(
struct
intel_uncore_box
*
box
,
struct
perf_event
*
event
)
...
@@ -312,7 +312,7 @@ static struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type,
...
@@ -312,7 +312,7 @@ static struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type,
uncore_pmu_init_hrtimer
(
box
);
uncore_pmu_init_hrtimer
(
box
);
box
->
cpu
=
-
1
;
box
->
cpu
=
-
1
;
box
->
pci_phys_id
=
-
1
;
box
->
pci_phys_id
=
-
1
;
box
->
pkg
id
=
-
1
;
box
->
die
id
=
-
1
;
/* set default hrtimer timeout */
/* set default hrtimer timeout */
box
->
hrtimer_duration
=
UNCORE_PMU_HRTIMER_INTERVAL
;
box
->
hrtimer_duration
=
UNCORE_PMU_HRTIMER_INTERVAL
;
...
@@ -827,10 +827,10 @@ static void uncore_pmu_unregister(struct intel_uncore_pmu *pmu)
...
@@ -827,10 +827,10 @@ static void uncore_pmu_unregister(struct intel_uncore_pmu *pmu)
static
void
uncore_free_boxes
(
struct
intel_uncore_pmu
*
pmu
)
static
void
uncore_free_boxes
(
struct
intel_uncore_pmu
*
pmu
)
{
{
int
pkg
;
int
die
;
for
(
pkg
=
0
;
pkg
<
max_packages
;
pkg
++
)
for
(
die
=
0
;
die
<
max_dies
;
die
++
)
kfree
(
pmu
->
boxes
[
pkg
]);
kfree
(
pmu
->
boxes
[
die
]);
kfree
(
pmu
->
boxes
);
kfree
(
pmu
->
boxes
);
}
}
...
@@ -867,7 +867,7 @@ static int __init uncore_type_init(struct intel_uncore_type *type, bool setid)
...
@@ -867,7 +867,7 @@ static int __init uncore_type_init(struct intel_uncore_type *type, bool setid)
if
(
!
pmus
)
if
(
!
pmus
)
return
-
ENOMEM
;
return
-
ENOMEM
;
size
=
max_
packag
es
*
sizeof
(
struct
intel_uncore_box
*
);
size
=
max_
di
es
*
sizeof
(
struct
intel_uncore_box
*
);
for
(
i
=
0
;
i
<
type
->
num_boxes
;
i
++
)
{
for
(
i
=
0
;
i
<
type
->
num_boxes
;
i
++
)
{
pmus
[
i
].
func_id
=
setid
?
i
:
-
1
;
pmus
[
i
].
func_id
=
setid
?
i
:
-
1
;
...
@@ -937,20 +937,21 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
...
@@ -937,20 +937,21 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
struct
intel_uncore_type
*
type
;
struct
intel_uncore_type
*
type
;
struct
intel_uncore_pmu
*
pmu
=
NULL
;
struct
intel_uncore_pmu
*
pmu
=
NULL
;
struct
intel_uncore_box
*
box
;
struct
intel_uncore_box
*
box
;
int
phys_id
,
pkg
,
ret
;
int
phys_id
,
die
,
ret
;
phys_id
=
uncore_pcibus_to_physid
(
pdev
->
bus
);
phys_id
=
uncore_pcibus_to_physid
(
pdev
->
bus
);
if
(
phys_id
<
0
)
if
(
phys_id
<
0
)
return
-
ENODEV
;
return
-
ENODEV
;
pkg
=
topology_phys_to_logical_pkg
(
phys_id
);
die
=
(
topology_max_die_per_package
()
>
1
)
?
phys_id
:
if
(
pkg
<
0
)
topology_phys_to_logical_pkg
(
phys_id
);
if
(
die
<
0
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
UNCORE_PCI_DEV_TYPE
(
id
->
driver_data
)
==
UNCORE_EXTRA_PCI_DEV
)
{
if
(
UNCORE_PCI_DEV_TYPE
(
id
->
driver_data
)
==
UNCORE_EXTRA_PCI_DEV
)
{
int
idx
=
UNCORE_PCI_DEV_IDX
(
id
->
driver_data
);
int
idx
=
UNCORE_PCI_DEV_IDX
(
id
->
driver_data
);
uncore_extra_pci_dev
[
pkg
].
dev
[
idx
]
=
pdev
;
uncore_extra_pci_dev
[
die
].
dev
[
idx
]
=
pdev
;
pci_set_drvdata
(
pdev
,
NULL
);
pci_set_drvdata
(
pdev
,
NULL
);
return
0
;
return
0
;
}
}
...
@@ -989,7 +990,7 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
...
@@ -989,7 +990,7 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
pmu
=
&
type
->
pmus
[
UNCORE_PCI_DEV_IDX
(
id
->
driver_data
)];
pmu
=
&
type
->
pmus
[
UNCORE_PCI_DEV_IDX
(
id
->
driver_data
)];
}
}
if
(
WARN_ON_ONCE
(
pmu
->
boxes
[
pkg
]
!=
NULL
))
if
(
WARN_ON_ONCE
(
pmu
->
boxes
[
die
]
!=
NULL
))
return
-
EINVAL
;
return
-
EINVAL
;
box
=
uncore_alloc_box
(
type
,
NUMA_NO_NODE
);
box
=
uncore_alloc_box
(
type
,
NUMA_NO_NODE
);
...
@@ -1003,13 +1004,13 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
...
@@ -1003,13 +1004,13 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
atomic_inc
(
&
box
->
refcnt
);
atomic_inc
(
&
box
->
refcnt
);
box
->
pci_phys_id
=
phys_id
;
box
->
pci_phys_id
=
phys_id
;
box
->
pkgid
=
pkg
;
box
->
dieid
=
die
;
box
->
pci_dev
=
pdev
;
box
->
pci_dev
=
pdev
;
box
->
pmu
=
pmu
;
box
->
pmu
=
pmu
;
uncore_box_init
(
box
);
uncore_box_init
(
box
);
pci_set_drvdata
(
pdev
,
box
);
pci_set_drvdata
(
pdev
,
box
);
pmu
->
boxes
[
pkg
]
=
box
;
pmu
->
boxes
[
die
]
=
box
;
if
(
atomic_inc_return
(
&
pmu
->
activeboxes
)
>
1
)
if
(
atomic_inc_return
(
&
pmu
->
activeboxes
)
>
1
)
return
0
;
return
0
;
...
@@ -1017,7 +1018,7 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
...
@@ -1017,7 +1018,7 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
ret
=
uncore_pmu_register
(
pmu
);
ret
=
uncore_pmu_register
(
pmu
);
if
(
ret
)
{
if
(
ret
)
{
pci_set_drvdata
(
pdev
,
NULL
);
pci_set_drvdata
(
pdev
,
NULL
);
pmu
->
boxes
[
pkg
]
=
NULL
;
pmu
->
boxes
[
die
]
=
NULL
;
uncore_box_exit
(
box
);
uncore_box_exit
(
box
);
kfree
(
box
);
kfree
(
box
);
}
}
...
@@ -1028,16 +1029,17 @@ static void uncore_pci_remove(struct pci_dev *pdev)
...
@@ -1028,16 +1029,17 @@ static void uncore_pci_remove(struct pci_dev *pdev)
{
{
struct
intel_uncore_box
*
box
;
struct
intel_uncore_box
*
box
;
struct
intel_uncore_pmu
*
pmu
;
struct
intel_uncore_pmu
*
pmu
;
int
i
,
phys_id
,
pkg
;
int
i
,
phys_id
,
die
;
phys_id
=
uncore_pcibus_to_physid
(
pdev
->
bus
);
phys_id
=
uncore_pcibus_to_physid
(
pdev
->
bus
);
box
=
pci_get_drvdata
(
pdev
);
box
=
pci_get_drvdata
(
pdev
);
if
(
!
box
)
{
if
(
!
box
)
{
pkg
=
topology_phys_to_logical_pkg
(
phys_id
);
die
=
(
topology_max_die_per_package
()
>
1
)
?
phys_id
:
topology_phys_to_logical_pkg
(
phys_id
);
for
(
i
=
0
;
i
<
UNCORE_EXTRA_PCI_DEV_MAX
;
i
++
)
{
for
(
i
=
0
;
i
<
UNCORE_EXTRA_PCI_DEV_MAX
;
i
++
)
{
if
(
uncore_extra_pci_dev
[
pkg
].
dev
[
i
]
==
pdev
)
{
if
(
uncore_extra_pci_dev
[
die
].
dev
[
i
]
==
pdev
)
{
uncore_extra_pci_dev
[
pkg
].
dev
[
i
]
=
NULL
;
uncore_extra_pci_dev
[
die
].
dev
[
i
]
=
NULL
;
break
;
break
;
}
}
}
}
...
@@ -1050,7 +1052,7 @@ static void uncore_pci_remove(struct pci_dev *pdev)
...
@@ -1050,7 +1052,7 @@ static void uncore_pci_remove(struct pci_dev *pdev)
return
;
return
;
pci_set_drvdata
(
pdev
,
NULL
);
pci_set_drvdata
(
pdev
,
NULL
);
pmu
->
boxes
[
box
->
pkg
id
]
=
NULL
;
pmu
->
boxes
[
box
->
die
id
]
=
NULL
;
if
(
atomic_dec_return
(
&
pmu
->
activeboxes
)
==
0
)
if
(
atomic_dec_return
(
&
pmu
->
activeboxes
)
==
0
)
uncore_pmu_unregister
(
pmu
);
uncore_pmu_unregister
(
pmu
);
uncore_box_exit
(
box
);
uncore_box_exit
(
box
);
...
@@ -1062,7 +1064,7 @@ static int __init uncore_pci_init(void)
...
@@ -1062,7 +1064,7 @@ static int __init uncore_pci_init(void)
size_t
size
;
size_t
size
;
int
ret
;
int
ret
;
size
=
max_
packag
es
*
sizeof
(
struct
pci_extra_dev
);
size
=
max_
di
es
*
sizeof
(
struct
pci_extra_dev
);
uncore_extra_pci_dev
=
kzalloc
(
size
,
GFP_KERNEL
);
uncore_extra_pci_dev
=
kzalloc
(
size
,
GFP_KERNEL
);
if
(
!
uncore_extra_pci_dev
)
{
if
(
!
uncore_extra_pci_dev
)
{
ret
=
-
ENOMEM
;
ret
=
-
ENOMEM
;
...
@@ -1109,11 +1111,11 @@ static void uncore_change_type_ctx(struct intel_uncore_type *type, int old_cpu,
...
@@ -1109,11 +1111,11 @@ static void uncore_change_type_ctx(struct intel_uncore_type *type, int old_cpu,
{
{
struct
intel_uncore_pmu
*
pmu
=
type
->
pmus
;
struct
intel_uncore_pmu
*
pmu
=
type
->
pmus
;
struct
intel_uncore_box
*
box
;
struct
intel_uncore_box
*
box
;
int
i
,
pkg
;
int
i
,
die
;
pkg
=
topology_logical_packag
e_id
(
old_cpu
<
0
?
new_cpu
:
old_cpu
);
die
=
topology_logical_di
e_id
(
old_cpu
<
0
?
new_cpu
:
old_cpu
);
for
(
i
=
0
;
i
<
type
->
num_boxes
;
i
++
,
pmu
++
)
{
for
(
i
=
0
;
i
<
type
->
num_boxes
;
i
++
,
pmu
++
)
{
box
=
pmu
->
boxes
[
pkg
];
box
=
pmu
->
boxes
[
die
];
if
(
!
box
)
if
(
!
box
)
continue
;
continue
;
...
@@ -1146,13 +1148,13 @@ static int uncore_event_cpu_offline(unsigned int cpu)
...
@@ -1146,13 +1148,13 @@ static int uncore_event_cpu_offline(unsigned int cpu)
struct
intel_uncore_type
*
type
,
**
types
=
uncore_msr_uncores
;
struct
intel_uncore_type
*
type
,
**
types
=
uncore_msr_uncores
;
struct
intel_uncore_pmu
*
pmu
;
struct
intel_uncore_pmu
*
pmu
;
struct
intel_uncore_box
*
box
;
struct
intel_uncore_box
*
box
;
int
i
,
pkg
,
target
;
int
i
,
die
,
target
;
/* Check if exiting cpu is used for collecting uncore events */
/* Check if exiting cpu is used for collecting uncore events */
if
(
!
cpumask_test_and_clear_cpu
(
cpu
,
&
uncore_cpu_mask
))
if
(
!
cpumask_test_and_clear_cpu
(
cpu
,
&
uncore_cpu_mask
))
goto
unref
;
goto
unref
;
/* Find a new cpu to collect uncore events */
/* Find a new cpu to collect uncore events */
target
=
cpumask_any_but
(
topology_
cor
e_cpumask
(
cpu
),
cpu
);
target
=
cpumask_any_but
(
topology_
di
e_cpumask
(
cpu
),
cpu
);
/* Migrate uncore events to the new target */
/* Migrate uncore events to the new target */
if
(
target
<
nr_cpu_ids
)
if
(
target
<
nr_cpu_ids
)
...
@@ -1165,12 +1167,12 @@ static int uncore_event_cpu_offline(unsigned int cpu)
...
@@ -1165,12 +1167,12 @@ static int uncore_event_cpu_offline(unsigned int cpu)
unref:
unref:
/* Clear the references */
/* Clear the references */
pkg
=
topology_logical_packag
e_id
(
cpu
);
die
=
topology_logical_di
e_id
(
cpu
);
for
(;
*
types
;
types
++
)
{
for
(;
*
types
;
types
++
)
{
type
=
*
types
;
type
=
*
types
;
pmu
=
type
->
pmus
;
pmu
=
type
->
pmus
;
for
(
i
=
0
;
i
<
type
->
num_boxes
;
i
++
,
pmu
++
)
{
for
(
i
=
0
;
i
<
type
->
num_boxes
;
i
++
,
pmu
++
)
{
box
=
pmu
->
boxes
[
pkg
];
box
=
pmu
->
boxes
[
die
];
if
(
box
&&
atomic_dec_return
(
&
box
->
refcnt
)
==
0
)
if
(
box
&&
atomic_dec_return
(
&
box
->
refcnt
)
==
0
)
uncore_box_exit
(
box
);
uncore_box_exit
(
box
);
}
}
...
@@ -1179,7 +1181,7 @@ static int uncore_event_cpu_offline(unsigned int cpu)
...
@@ -1179,7 +1181,7 @@ static int uncore_event_cpu_offline(unsigned int cpu)
}
}
static
int
allocate_boxes
(
struct
intel_uncore_type
**
types
,
static
int
allocate_boxes
(
struct
intel_uncore_type
**
types
,
unsigned
int
pkg
,
unsigned
int
cpu
)
unsigned
int
die
,
unsigned
int
cpu
)
{
{
struct
intel_uncore_box
*
box
,
*
tmp
;
struct
intel_uncore_box
*
box
,
*
tmp
;
struct
intel_uncore_type
*
type
;
struct
intel_uncore_type
*
type
;
...
@@ -1192,20 +1194,20 @@ static int allocate_boxes(struct intel_uncore_type **types,
...
@@ -1192,20 +1194,20 @@ static int allocate_boxes(struct intel_uncore_type **types,
type
=
*
types
;
type
=
*
types
;
pmu
=
type
->
pmus
;
pmu
=
type
->
pmus
;
for
(
i
=
0
;
i
<
type
->
num_boxes
;
i
++
,
pmu
++
)
{
for
(
i
=
0
;
i
<
type
->
num_boxes
;
i
++
,
pmu
++
)
{
if
(
pmu
->
boxes
[
pkg
])
if
(
pmu
->
boxes
[
die
])
continue
;
continue
;
box
=
uncore_alloc_box
(
type
,
cpu_to_node
(
cpu
));
box
=
uncore_alloc_box
(
type
,
cpu_to_node
(
cpu
));
if
(
!
box
)
if
(
!
box
)
goto
cleanup
;
goto
cleanup
;
box
->
pmu
=
pmu
;
box
->
pmu
=
pmu
;
box
->
pkgid
=
pkg
;
box
->
dieid
=
die
;
list_add
(
&
box
->
active_list
,
&
allocated
);
list_add
(
&
box
->
active_list
,
&
allocated
);
}
}
}
}
/* Install them in the pmus */
/* Install them in the pmus */
list_for_each_entry_safe
(
box
,
tmp
,
&
allocated
,
active_list
)
{
list_for_each_entry_safe
(
box
,
tmp
,
&
allocated
,
active_list
)
{
list_del_init
(
&
box
->
active_list
);
list_del_init
(
&
box
->
active_list
);
box
->
pmu
->
boxes
[
pkg
]
=
box
;
box
->
pmu
->
boxes
[
die
]
=
box
;
}
}
return
0
;
return
0
;
...
@@ -1222,10 +1224,10 @@ static int uncore_event_cpu_online(unsigned int cpu)
...
@@ -1222,10 +1224,10 @@ static int uncore_event_cpu_online(unsigned int cpu)
struct
intel_uncore_type
*
type
,
**
types
=
uncore_msr_uncores
;
struct
intel_uncore_type
*
type
,
**
types
=
uncore_msr_uncores
;
struct
intel_uncore_pmu
*
pmu
;
struct
intel_uncore_pmu
*
pmu
;
struct
intel_uncore_box
*
box
;
struct
intel_uncore_box
*
box
;
int
i
,
ret
,
pkg
,
target
;
int
i
,
ret
,
die
,
target
;
pkg
=
topology_logical_packag
e_id
(
cpu
);
die
=
topology_logical_di
e_id
(
cpu
);
ret
=
allocate_boxes
(
types
,
pkg
,
cpu
);
ret
=
allocate_boxes
(
types
,
die
,
cpu
);
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
...
@@ -1233,7 +1235,7 @@ static int uncore_event_cpu_online(unsigned int cpu)
...
@@ -1233,7 +1235,7 @@ static int uncore_event_cpu_online(unsigned int cpu)
type
=
*
types
;
type
=
*
types
;
pmu
=
type
->
pmus
;
pmu
=
type
->
pmus
;
for
(
i
=
0
;
i
<
type
->
num_boxes
;
i
++
,
pmu
++
)
{
for
(
i
=
0
;
i
<
type
->
num_boxes
;
i
++
,
pmu
++
)
{
box
=
pmu
->
boxes
[
pkg
];
box
=
pmu
->
boxes
[
die
];
if
(
box
&&
atomic_inc_return
(
&
box
->
refcnt
)
==
1
)
if
(
box
&&
atomic_inc_return
(
&
box
->
refcnt
)
==
1
)
uncore_box_init
(
box
);
uncore_box_init
(
box
);
}
}
...
@@ -1243,7 +1245,7 @@ static int uncore_event_cpu_online(unsigned int cpu)
...
@@ -1243,7 +1245,7 @@ static int uncore_event_cpu_online(unsigned int cpu)
* Check if there is an online cpu in the package
* Check if there is an online cpu in the package
* which collects uncore events already.
* which collects uncore events already.
*/
*/
target
=
cpumask_any_and
(
&
uncore_cpu_mask
,
topology_
cor
e_cpumask
(
cpu
));
target
=
cpumask_any_and
(
&
uncore_cpu_mask
,
topology_
di
e_cpumask
(
cpu
));
if
(
target
<
nr_cpu_ids
)
if
(
target
<
nr_cpu_ids
)
return
0
;
return
0
;
...
@@ -1418,7 +1420,7 @@ static int __init intel_uncore_init(void)
...
@@ -1418,7 +1420,7 @@ static int __init intel_uncore_init(void)
if
(
boot_cpu_has
(
X86_FEATURE_HYPERVISOR
))
if
(
boot_cpu_has
(
X86_FEATURE_HYPERVISOR
))
return
-
ENODEV
;
return
-
ENODEV
;
max_
packages
=
topology_max_packages
();
max_
dies
=
topology_max_packages
()
*
topology_max_die_per_package
();
uncore_init
=
(
struct
intel_uncore_init_fun
*
)
id
->
driver_data
;
uncore_init
=
(
struct
intel_uncore_init_fun
*
)
id
->
driver_data
;
if
(
uncore_init
->
pci_init
)
{
if
(
uncore_init
->
pci_init
)
{
...
...
arch/x86/events/intel/uncore.h
浏览文件 @
3384c786
...
@@ -108,7 +108,7 @@ struct intel_uncore_extra_reg {
...
@@ -108,7 +108,7 @@ struct intel_uncore_extra_reg {
struct
intel_uncore_box
{
struct
intel_uncore_box
{
int
pci_phys_id
;
int
pci_phys_id
;
int
pkgid
;
/* Logical packag
e ID */
int
dieid
;
/* Logical di
e ID */
int
n_active
;
/* number of active events */
int
n_active
;
/* number of active events */
int
n_events
;
int
n_events
;
int
cpu
;
/* cpu to collect events */
int
cpu
;
/* cpu to collect events */
...
@@ -467,7 +467,7 @@ static inline void uncore_box_exit(struct intel_uncore_box *box)
...
@@ -467,7 +467,7 @@ static inline void uncore_box_exit(struct intel_uncore_box *box)
static
inline
bool
uncore_box_is_fake
(
struct
intel_uncore_box
*
box
)
static
inline
bool
uncore_box_is_fake
(
struct
intel_uncore_box
*
box
)
{
{
return
(
box
->
pkg
id
<
0
);
return
(
box
->
die
id
<
0
);
}
}
static
inline
struct
intel_uncore_pmu
*
uncore_event_to_pmu
(
struct
perf_event
*
event
)
static
inline
struct
intel_uncore_pmu
*
uncore_event_to_pmu
(
struct
perf_event
*
event
)
...
...
arch/x86/events/intel/uncore_snbep.c
浏览文件 @
3384c786
...
@@ -1058,8 +1058,8 @@ static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_eve
...
@@ -1058,8 +1058,8 @@ static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_eve
if
(
reg1
->
idx
!=
EXTRA_REG_NONE
)
{
if
(
reg1
->
idx
!=
EXTRA_REG_NONE
)
{
int
idx
=
box
->
pmu
->
pmu_idx
+
SNBEP_PCI_QPI_PORT0_FILTER
;
int
idx
=
box
->
pmu
->
pmu_idx
+
SNBEP_PCI_QPI_PORT0_FILTER
;
int
pkg
=
box
->
pkg
id
;
int
die
=
box
->
die
id
;
struct
pci_dev
*
filter_pdev
=
uncore_extra_pci_dev
[
pkg
].
dev
[
idx
];
struct
pci_dev
*
filter_pdev
=
uncore_extra_pci_dev
[
die
].
dev
[
idx
];
if
(
filter_pdev
)
{
if
(
filter_pdev
)
{
pci_write_config_dword
(
filter_pdev
,
reg1
->
reg
,
pci_write_config_dword
(
filter_pdev
,
reg1
->
reg
,
...
...
arch/x86/include/asm/processor.h
浏览文件 @
3384c786
...
@@ -105,7 +105,7 @@ struct cpuinfo_x86 {
...
@@ -105,7 +105,7 @@ struct cpuinfo_x86 {
int
x86_power
;
int
x86_power
;
unsigned
long
loops_per_jiffy
;
unsigned
long
loops_per_jiffy
;
/* cpuid returned max cores value: */
/* cpuid returned max cores value: */
u16
x86_max_cores
;
u16
x86_max_cores
;
u16
apicid
;
u16
apicid
;
u16
initial_apicid
;
u16
initial_apicid
;
u16
x86_clflush_size
;
u16
x86_clflush_size
;
...
@@ -117,6 +117,8 @@ struct cpuinfo_x86 {
...
@@ -117,6 +117,8 @@ struct cpuinfo_x86 {
u16
logical_proc_id
;
u16
logical_proc_id
;
/* Core id: */
/* Core id: */
u16
cpu_core_id
;
u16
cpu_core_id
;
u16
cpu_die_id
;
u16
logical_die_id
;
/* Index into per_cpu list: */
/* Index into per_cpu list: */
u16
cpu_index
;
u16
cpu_index
;
u32
microcode
;
u32
microcode
;
...
...
arch/x86/include/asm/smp.h
浏览文件 @
3384c786
...
@@ -23,6 +23,7 @@ extern unsigned int num_processors;
...
@@ -23,6 +23,7 @@ extern unsigned int num_processors;
DECLARE_PER_CPU_READ_MOSTLY
(
cpumask_var_t
,
cpu_sibling_map
);
DECLARE_PER_CPU_READ_MOSTLY
(
cpumask_var_t
,
cpu_sibling_map
);
DECLARE_PER_CPU_READ_MOSTLY
(
cpumask_var_t
,
cpu_core_map
);
DECLARE_PER_CPU_READ_MOSTLY
(
cpumask_var_t
,
cpu_core_map
);
DECLARE_PER_CPU_READ_MOSTLY
(
cpumask_var_t
,
cpu_die_map
);
/* cpus sharing the last level cache: */
/* cpus sharing the last level cache: */
DECLARE_PER_CPU_READ_MOSTLY
(
cpumask_var_t
,
cpu_llc_shared_map
);
DECLARE_PER_CPU_READ_MOSTLY
(
cpumask_var_t
,
cpu_llc_shared_map
);
DECLARE_PER_CPU_READ_MOSTLY
(
u16
,
cpu_llc_id
);
DECLARE_PER_CPU_READ_MOSTLY
(
u16
,
cpu_llc_id
);
...
...
arch/x86/include/asm/topology.h
浏览文件 @
3384c786
...
@@ -106,15 +106,25 @@ extern const struct cpumask *cpu_coregroup_mask(int cpu);
...
@@ -106,15 +106,25 @@ extern const struct cpumask *cpu_coregroup_mask(int cpu);
#define topology_logical_package_id(cpu) (cpu_data(cpu).logical_proc_id)
#define topology_logical_package_id(cpu) (cpu_data(cpu).logical_proc_id)
#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id)
#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id)
#define topology_logical_die_id(cpu) (cpu_data(cpu).logical_die_id)
#define topology_die_id(cpu) (cpu_data(cpu).cpu_die_id)
#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
#define topology_die_cpumask(cpu) (per_cpu(cpu_die_map, cpu))
#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
#define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu))
#define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu))
extern
unsigned
int
__max_logical_packages
;
extern
unsigned
int
__max_logical_packages
;
#define topology_max_packages() (__max_logical_packages)
#define topology_max_packages() (__max_logical_packages)
extern
unsigned
int
__max_die_per_package
;
static
inline
int
topology_max_die_per_package
(
void
)
{
return
__max_die_per_package
;
}
extern
int
__max_smt_threads
;
extern
int
__max_smt_threads
;
static
inline
int
topology_max_smt_threads
(
void
)
static
inline
int
topology_max_smt_threads
(
void
)
...
@@ -123,14 +133,21 @@ static inline int topology_max_smt_threads(void)
...
@@ -123,14 +133,21 @@ static inline int topology_max_smt_threads(void)
}
}
int
topology_update_package_map
(
unsigned
int
apicid
,
unsigned
int
cpu
);
int
topology_update_package_map
(
unsigned
int
apicid
,
unsigned
int
cpu
);
int
topology_update_die_map
(
unsigned
int
dieid
,
unsigned
int
cpu
);
int
topology_phys_to_logical_pkg
(
unsigned
int
pkg
);
int
topology_phys_to_logical_pkg
(
unsigned
int
pkg
);
int
topology_phys_to_logical_die
(
unsigned
int
die
,
unsigned
int
cpu
);
bool
topology_is_primary_thread
(
unsigned
int
cpu
);
bool
topology_is_primary_thread
(
unsigned
int
cpu
);
bool
topology_smt_supported
(
void
);
bool
topology_smt_supported
(
void
);
#else
#else
#define topology_max_packages() (1)
#define topology_max_packages() (1)
static
inline
int
static
inline
int
topology_update_package_map
(
unsigned
int
apicid
,
unsigned
int
cpu
)
{
return
0
;
}
topology_update_package_map
(
unsigned
int
apicid
,
unsigned
int
cpu
)
{
return
0
;
}
static
inline
int
topology_update_die_map
(
unsigned
int
dieid
,
unsigned
int
cpu
)
{
return
0
;
}
static
inline
int
topology_phys_to_logical_pkg
(
unsigned
int
pkg
)
{
return
0
;
}
static
inline
int
topology_phys_to_logical_pkg
(
unsigned
int
pkg
)
{
return
0
;
}
static
inline
int
topology_phys_to_logical_die
(
unsigned
int
die
,
unsigned
int
cpu
)
{
return
0
;
}
static
inline
int
topology_max_die_per_package
(
void
)
{
return
1
;
}
static
inline
int
topology_max_smt_threads
(
void
)
{
return
1
;
}
static
inline
int
topology_max_smt_threads
(
void
)
{
return
1
;
}
static
inline
bool
topology_is_primary_thread
(
unsigned
int
cpu
)
{
return
true
;
}
static
inline
bool
topology_is_primary_thread
(
unsigned
int
cpu
)
{
return
true
;
}
static
inline
bool
topology_smt_supported
(
void
)
{
return
false
;
}
static
inline
bool
topology_smt_supported
(
void
)
{
return
false
;
}
...
...
arch/x86/kernel/cpu/common.c
浏览文件 @
3384c786
...
@@ -1299,6 +1299,7 @@ static void validate_apic_and_package_id(struct cpuinfo_x86 *c)
...
@@ -1299,6 +1299,7 @@ static void validate_apic_and_package_id(struct cpuinfo_x86 *c)
cpu
,
apicid
,
c
->
initial_apicid
);
cpu
,
apicid
,
c
->
initial_apicid
);
}
}
BUG_ON
(
topology_update_package_map
(
c
->
phys_proc_id
,
cpu
));
BUG_ON
(
topology_update_package_map
(
c
->
phys_proc_id
,
cpu
));
BUG_ON
(
topology_update_die_map
(
c
->
cpu_die_id
,
cpu
));
#else
#else
c
->
logical_proc_id
=
0
;
c
->
logical_proc_id
=
0
;
#endif
#endif
...
...
arch/x86/kernel/cpu/topology.c
浏览文件 @
3384c786
...
@@ -15,33 +15,66 @@
...
@@ -15,33 +15,66 @@
/* leaf 0xb SMT level */
/* leaf 0xb SMT level */
#define SMT_LEVEL 0
#define SMT_LEVEL 0
/*
leaf 0xb
sub-leaf types */
/*
extended topology
sub-leaf types */
#define INVALID_TYPE 0
#define INVALID_TYPE 0
#define SMT_TYPE 1
#define SMT_TYPE 1
#define CORE_TYPE 2
#define CORE_TYPE 2
#define DIE_TYPE 5
#define LEAFB_SUBTYPE(ecx) (((ecx) >> 8) & 0xff)
#define LEAFB_SUBTYPE(ecx) (((ecx) >> 8) & 0xff)
#define BITS_SHIFT_NEXT_LEVEL(eax) ((eax) & 0x1f)
#define BITS_SHIFT_NEXT_LEVEL(eax) ((eax) & 0x1f)
#define LEVEL_MAX_SIBLINGS(ebx) ((ebx) & 0xffff)
#define LEVEL_MAX_SIBLINGS(ebx) ((ebx) & 0xffff)
int
detect_extended_topology_early
(
struct
cpuinfo_x86
*
c
)
{
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
unsigned
int
__max_die_per_package
__read_mostly
=
1
;
EXPORT_SYMBOL
(
__max_die_per_package
);
/*
* Check if given CPUID extended toplogy "leaf" is implemented
*/
static
int
check_extended_topology_leaf
(
int
leaf
)
{
unsigned
int
eax
,
ebx
,
ecx
,
edx
;
unsigned
int
eax
,
ebx
,
ecx
,
edx
;
if
(
c
->
cpuid_level
<
0xb
)
cpuid_count
(
leaf
,
SMT_LEVEL
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
if
(
ebx
==
0
||
(
LEAFB_SUBTYPE
(
ecx
)
!=
SMT_TYPE
))
return
-
1
;
return
-
1
;
cpuid_count
(
0xb
,
SMT_LEVEL
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
return
0
;
}
/*
* Return best CPUID Extended Toplogy Leaf supported
*/
static
int
detect_extended_topology_leaf
(
struct
cpuinfo_x86
*
c
)
{
if
(
c
->
cpuid_level
>=
0x1f
)
{
if
(
check_extended_topology_leaf
(
0x1f
)
==
0
)
return
0x1f
;
}
/*
if
(
c
->
cpuid_level
>=
0xb
)
{
* check if the cpuid leaf 0xb is actually implemented.
if
(
check_extended_topology_leaf
(
0xb
)
==
0
)
*/
return
0xb
;
if
(
ebx
==
0
||
(
LEAFB_SUBTYPE
(
ecx
)
!=
SMT_TYPE
))
}
return
-
1
;
}
#endif
int
detect_extended_topology_early
(
struct
cpuinfo_x86
*
c
)
{
#ifdef CONFIG_SMP
unsigned
int
eax
,
ebx
,
ecx
,
edx
;
int
leaf
;
leaf
=
detect_extended_topology_leaf
(
c
);
if
(
leaf
<
0
)
return
-
1
;
return
-
1
;
set_cpu_cap
(
c
,
X86_FEATURE_XTOPOLOGY
);
set_cpu_cap
(
c
,
X86_FEATURE_XTOPOLOGY
);
cpuid_count
(
leaf
,
SMT_LEVEL
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
/*
/*
* initial apic id, which also represents 32-bit extended x2apic id.
* initial apic id, which also represents 32-bit extended x2apic id.
*/
*/
...
@@ -52,7 +85,7 @@ int detect_extended_topology_early(struct cpuinfo_x86 *c)
...
@@ -52,7 +85,7 @@ int detect_extended_topology_early(struct cpuinfo_x86 *c)
}
}
/*
/*
* Check for extended topology enumeration cpuid leaf
0xb
and if it
* Check for extended topology enumeration cpuid leaf
,
and if it
* exists, use it for populating initial_apicid and cpu topology
* exists, use it for populating initial_apicid and cpu topology
* detection.
* detection.
*/
*/
...
@@ -60,22 +93,28 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
...
@@ -60,22 +93,28 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
{
{
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
unsigned
int
eax
,
ebx
,
ecx
,
edx
,
sub_index
;
unsigned
int
eax
,
ebx
,
ecx
,
edx
,
sub_index
;
unsigned
int
ht_mask_width
,
core_plus_mask_width
;
unsigned
int
ht_mask_width
,
core_plus_mask_width
,
die_plus_mask_width
;
unsigned
int
core_select_mask
,
core_level_siblings
;
unsigned
int
core_select_mask
,
core_level_siblings
;
unsigned
int
die_select_mask
,
die_level_siblings
;
int
leaf
;
if
(
detect_extended_topology_early
(
c
)
<
0
)
leaf
=
detect_extended_topology_leaf
(
c
);
if
(
leaf
<
0
)
return
-
1
;
return
-
1
;
/*
/*
* Populate HT related information from sub-leaf level 0.
* Populate HT related information from sub-leaf level 0.
*/
*/
cpuid_count
(
0xb
,
SMT_LEVEL
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
cpuid_count
(
leaf
,
SMT_LEVEL
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
c
->
initial_apicid
=
edx
;
core_level_siblings
=
smp_num_siblings
=
LEVEL_MAX_SIBLINGS
(
ebx
);
core_level_siblings
=
smp_num_siblings
=
LEVEL_MAX_SIBLINGS
(
ebx
);
core_plus_mask_width
=
ht_mask_width
=
BITS_SHIFT_NEXT_LEVEL
(
eax
);
core_plus_mask_width
=
ht_mask_width
=
BITS_SHIFT_NEXT_LEVEL
(
eax
);
die_level_siblings
=
LEVEL_MAX_SIBLINGS
(
ebx
);
die_plus_mask_width
=
BITS_SHIFT_NEXT_LEVEL
(
eax
);
sub_index
=
1
;
sub_index
=
1
;
do
{
do
{
cpuid_count
(
0xb
,
sub_index
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
cpuid_count
(
leaf
,
sub_index
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
/*
/*
* Check for the Core type in the implemented sub leaves.
* Check for the Core type in the implemented sub leaves.
...
@@ -83,23 +122,34 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
...
@@ -83,23 +122,34 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
if
(
LEAFB_SUBTYPE
(
ecx
)
==
CORE_TYPE
)
{
if
(
LEAFB_SUBTYPE
(
ecx
)
==
CORE_TYPE
)
{
core_level_siblings
=
LEVEL_MAX_SIBLINGS
(
ebx
);
core_level_siblings
=
LEVEL_MAX_SIBLINGS
(
ebx
);
core_plus_mask_width
=
BITS_SHIFT_NEXT_LEVEL
(
eax
);
core_plus_mask_width
=
BITS_SHIFT_NEXT_LEVEL
(
eax
);
break
;
die_level_siblings
=
core_level_siblings
;
die_plus_mask_width
=
BITS_SHIFT_NEXT_LEVEL
(
eax
);
}
if
(
LEAFB_SUBTYPE
(
ecx
)
==
DIE_TYPE
)
{
die_level_siblings
=
LEVEL_MAX_SIBLINGS
(
ebx
);
die_plus_mask_width
=
BITS_SHIFT_NEXT_LEVEL
(
eax
);
}
}
sub_index
++
;
sub_index
++
;
}
while
(
LEAFB_SUBTYPE
(
ecx
)
!=
INVALID_TYPE
);
}
while
(
LEAFB_SUBTYPE
(
ecx
)
!=
INVALID_TYPE
);
core_select_mask
=
(
~
(
-
1
<<
core_plus_mask_width
))
>>
ht_mask_width
;
core_select_mask
=
(
~
(
-
1
<<
core_plus_mask_width
))
>>
ht_mask_width
;
die_select_mask
=
(
~
(
-
1
<<
die_plus_mask_width
))
>>
c
->
cpu_core_id
=
apic
->
phys_pkg_id
(
c
->
initial_apicid
,
ht_mask_width
)
core_plus_mask_width
;
&
core_select_mask
;
c
->
phys_proc_id
=
apic
->
phys_pkg_id
(
c
->
initial_apicid
,
core_plus_mask_width
);
c
->
cpu_core_id
=
apic
->
phys_pkg_id
(
c
->
initial_apicid
,
ht_mask_width
)
&
core_select_mask
;
c
->
cpu_die_id
=
apic
->
phys_pkg_id
(
c
->
initial_apicid
,
core_plus_mask_width
)
&
die_select_mask
;
c
->
phys_proc_id
=
apic
->
phys_pkg_id
(
c
->
initial_apicid
,
die_plus_mask_width
);
/*
/*
* Reinit the apicid, now that we have extended initial_apicid.
* Reinit the apicid, now that we have extended initial_apicid.
*/
*/
c
->
apicid
=
apic
->
phys_pkg_id
(
c
->
initial_apicid
,
0
);
c
->
apicid
=
apic
->
phys_pkg_id
(
c
->
initial_apicid
,
0
);
c
->
x86_max_cores
=
(
core_level_siblings
/
smp_num_siblings
);
c
->
x86_max_cores
=
(
core_level_siblings
/
smp_num_siblings
);
__max_die_per_package
=
(
die_level_siblings
/
core_level_siblings
);
#endif
#endif
return
0
;
return
0
;
}
}
arch/x86/kernel/smpboot.c
浏览文件 @
3384c786
...
@@ -89,6 +89,10 @@ EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
...
@@ -89,6 +89,10 @@ EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
DEFINE_PER_CPU_READ_MOSTLY
(
cpumask_var_t
,
cpu_core_map
);
DEFINE_PER_CPU_READ_MOSTLY
(
cpumask_var_t
,
cpu_core_map
);
EXPORT_PER_CPU_SYMBOL
(
cpu_core_map
);
EXPORT_PER_CPU_SYMBOL
(
cpu_core_map
);
/* representing HT, core, and die siblings of each logical CPU */
DEFINE_PER_CPU_READ_MOSTLY
(
cpumask_var_t
,
cpu_die_map
);
EXPORT_PER_CPU_SYMBOL
(
cpu_die_map
);
DEFINE_PER_CPU_READ_MOSTLY
(
cpumask_var_t
,
cpu_llc_shared_map
);
DEFINE_PER_CPU_READ_MOSTLY
(
cpumask_var_t
,
cpu_llc_shared_map
);
/* Per CPU bogomips and other parameters */
/* Per CPU bogomips and other parameters */
...
@@ -99,6 +103,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_info);
...
@@ -99,6 +103,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_info);
unsigned
int
__max_logical_packages
__read_mostly
;
unsigned
int
__max_logical_packages
__read_mostly
;
EXPORT_SYMBOL
(
__max_logical_packages
);
EXPORT_SYMBOL
(
__max_logical_packages
);
static
unsigned
int
logical_packages
__read_mostly
;
static
unsigned
int
logical_packages
__read_mostly
;
static
unsigned
int
logical_die
__read_mostly
;
/* Maximum number of SMT threads on any online core */
/* Maximum number of SMT threads on any online core */
int
__read_mostly
__max_smt_threads
=
1
;
int
__read_mostly
__max_smt_threads
=
1
;
...
@@ -300,6 +305,26 @@ int topology_phys_to_logical_pkg(unsigned int phys_pkg)
...
@@ -300,6 +305,26 @@ int topology_phys_to_logical_pkg(unsigned int phys_pkg)
return
-
1
;
return
-
1
;
}
}
EXPORT_SYMBOL
(
topology_phys_to_logical_pkg
);
EXPORT_SYMBOL
(
topology_phys_to_logical_pkg
);
/**
* topology_phys_to_logical_die - Map a physical die id to logical
*
* Returns logical die id or -1 if not found
*/
int
topology_phys_to_logical_die
(
unsigned
int
die_id
,
unsigned
int
cur_cpu
)
{
int
cpu
;
int
proc_id
=
cpu_data
(
cur_cpu
).
phys_proc_id
;
for_each_possible_cpu
(
cpu
)
{
struct
cpuinfo_x86
*
c
=
&
cpu_data
(
cpu
);
if
(
c
->
initialized
&&
c
->
cpu_die_id
==
die_id
&&
c
->
phys_proc_id
==
proc_id
)
return
c
->
logical_die_id
;
}
return
-
1
;
}
EXPORT_SYMBOL
(
topology_phys_to_logical_die
);
/**
/**
* topology_update_package_map - Update the physical to logical package map
* topology_update_package_map - Update the physical to logical package map
...
@@ -324,6 +349,29 @@ int topology_update_package_map(unsigned int pkg, unsigned int cpu)
...
@@ -324,6 +349,29 @@ int topology_update_package_map(unsigned int pkg, unsigned int cpu)
cpu_data
(
cpu
).
logical_proc_id
=
new
;
cpu_data
(
cpu
).
logical_proc_id
=
new
;
return
0
;
return
0
;
}
}
/**
* topology_update_die_map - Update the physical to logical die map
* @die: The die id as retrieved via CPUID
* @cpu: The cpu for which this is updated
*/
int
topology_update_die_map
(
unsigned
int
die
,
unsigned
int
cpu
)
{
int
new
;
/* Already available somewhere? */
new
=
topology_phys_to_logical_die
(
die
,
cpu
);
if
(
new
>=
0
)
goto
found
;
new
=
logical_die
++
;
if
(
new
!=
die
)
{
pr_info
(
"CPU %u Converting physical %u to logical die %u
\n
"
,
cpu
,
die
,
new
);
}
found:
cpu_data
(
cpu
).
logical_die_id
=
new
;
return
0
;
}
void
__init
smp_store_boot_cpu_info
(
void
)
void
__init
smp_store_boot_cpu_info
(
void
)
{
{
...
@@ -333,6 +381,7 @@ void __init smp_store_boot_cpu_info(void)
...
@@ -333,6 +381,7 @@ void __init smp_store_boot_cpu_info(void)
*
c
=
boot_cpu_data
;
*
c
=
boot_cpu_data
;
c
->
cpu_index
=
id
;
c
->
cpu_index
=
id
;
topology_update_package_map
(
c
->
phys_proc_id
,
id
);
topology_update_package_map
(
c
->
phys_proc_id
,
id
);
topology_update_die_map
(
c
->
cpu_die_id
,
id
);
c
->
initialized
=
true
;
c
->
initialized
=
true
;
}
}
...
@@ -387,6 +436,7 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
...
@@ -387,6 +436,7 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
int
cpu1
=
c
->
cpu_index
,
cpu2
=
o
->
cpu_index
;
int
cpu1
=
c
->
cpu_index
,
cpu2
=
o
->
cpu_index
;
if
(
c
->
phys_proc_id
==
o
->
phys_proc_id
&&
if
(
c
->
phys_proc_id
==
o
->
phys_proc_id
&&
c
->
cpu_die_id
==
o
->
cpu_die_id
&&
per_cpu
(
cpu_llc_id
,
cpu1
)
==
per_cpu
(
cpu_llc_id
,
cpu2
))
{
per_cpu
(
cpu_llc_id
,
cpu1
)
==
per_cpu
(
cpu_llc_id
,
cpu2
))
{
if
(
c
->
cpu_core_id
==
o
->
cpu_core_id
)
if
(
c
->
cpu_core_id
==
o
->
cpu_core_id
)
return
topology_sane
(
c
,
o
,
"smt"
);
return
topology_sane
(
c
,
o
,
"smt"
);
...
@@ -398,6 +448,7 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
...
@@ -398,6 +448,7 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
}
}
}
else
if
(
c
->
phys_proc_id
==
o
->
phys_proc_id
&&
}
else
if
(
c
->
phys_proc_id
==
o
->
phys_proc_id
&&
c
->
cpu_die_id
==
o
->
cpu_die_id
&&
c
->
cpu_core_id
==
o
->
cpu_core_id
)
{
c
->
cpu_core_id
==
o
->
cpu_core_id
)
{
return
topology_sane
(
c
,
o
,
"smt"
);
return
topology_sane
(
c
,
o
,
"smt"
);
}
}
...
@@ -460,6 +511,15 @@ static bool match_pkg(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
...
@@ -460,6 +511,15 @@ static bool match_pkg(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
return
false
;
return
false
;
}
}
static
bool
match_die
(
struct
cpuinfo_x86
*
c
,
struct
cpuinfo_x86
*
o
)
{
if
((
c
->
phys_proc_id
==
o
->
phys_proc_id
)
&&
(
c
->
cpu_die_id
==
o
->
cpu_die_id
))
return
true
;
return
false
;
}
#if defined(CONFIG_SCHED_SMT) || defined(CONFIG_SCHED_MC)
#if defined(CONFIG_SCHED_SMT) || defined(CONFIG_SCHED_MC)
static
inline
int
x86_sched_itmt_flags
(
void
)
static
inline
int
x86_sched_itmt_flags
(
void
)
{
{
...
@@ -522,6 +582,7 @@ void set_cpu_sibling_map(int cpu)
...
@@ -522,6 +582,7 @@ void set_cpu_sibling_map(int cpu)
cpumask_set_cpu
(
cpu
,
topology_sibling_cpumask
(
cpu
));
cpumask_set_cpu
(
cpu
,
topology_sibling_cpumask
(
cpu
));
cpumask_set_cpu
(
cpu
,
cpu_llc_shared_mask
(
cpu
));
cpumask_set_cpu
(
cpu
,
cpu_llc_shared_mask
(
cpu
));
cpumask_set_cpu
(
cpu
,
topology_core_cpumask
(
cpu
));
cpumask_set_cpu
(
cpu
,
topology_core_cpumask
(
cpu
));
cpumask_set_cpu
(
cpu
,
topology_die_cpumask
(
cpu
));
c
->
booted_cores
=
1
;
c
->
booted_cores
=
1
;
return
;
return
;
}
}
...
@@ -570,6 +631,9 @@ void set_cpu_sibling_map(int cpu)
...
@@ -570,6 +631,9 @@ void set_cpu_sibling_map(int cpu)
}
}
if
(
match_pkg
(
c
,
o
)
&&
!
topology_same_node
(
c
,
o
))
if
(
match_pkg
(
c
,
o
)
&&
!
topology_same_node
(
c
,
o
))
x86_has_numa_in_package
=
true
;
x86_has_numa_in_package
=
true
;
if
((
i
==
cpu
)
||
(
has_mp
&&
match_die
(
c
,
o
)))
link_mask
(
topology_die_cpumask
,
cpu
,
i
);
}
}
threads
=
cpumask_weight
(
topology_sibling_cpumask
(
cpu
));
threads
=
cpumask_weight
(
topology_sibling_cpumask
(
cpu
));
...
@@ -1174,6 +1238,7 @@ static __init void disable_smp(void)
...
@@ -1174,6 +1238,7 @@ static __init void disable_smp(void)
physid_set_mask_of_physid
(
0
,
&
phys_cpu_present_map
);
physid_set_mask_of_physid
(
0
,
&
phys_cpu_present_map
);
cpumask_set_cpu
(
0
,
topology_sibling_cpumask
(
0
));
cpumask_set_cpu
(
0
,
topology_sibling_cpumask
(
0
));
cpumask_set_cpu
(
0
,
topology_core_cpumask
(
0
));
cpumask_set_cpu
(
0
,
topology_core_cpumask
(
0
));
cpumask_set_cpu
(
0
,
topology_die_cpumask
(
0
));
}
}
/*
/*
...
@@ -1269,6 +1334,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
...
@@ -1269,6 +1334,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
for_each_possible_cpu
(
i
)
{
for_each_possible_cpu
(
i
)
{
zalloc_cpumask_var
(
&
per_cpu
(
cpu_sibling_map
,
i
),
GFP_KERNEL
);
zalloc_cpumask_var
(
&
per_cpu
(
cpu_sibling_map
,
i
),
GFP_KERNEL
);
zalloc_cpumask_var
(
&
per_cpu
(
cpu_core_map
,
i
),
GFP_KERNEL
);
zalloc_cpumask_var
(
&
per_cpu
(
cpu_core_map
,
i
),
GFP_KERNEL
);
zalloc_cpumask_var
(
&
per_cpu
(
cpu_die_map
,
i
),
GFP_KERNEL
);
zalloc_cpumask_var
(
&
per_cpu
(
cpu_llc_shared_map
,
i
),
GFP_KERNEL
);
zalloc_cpumask_var
(
&
per_cpu
(
cpu_llc_shared_map
,
i
),
GFP_KERNEL
);
}
}
...
@@ -1489,6 +1555,8 @@ static void remove_siblinginfo(int cpu)
...
@@ -1489,6 +1555,8 @@ static void remove_siblinginfo(int cpu)
cpu_data
(
sibling
).
booted_cores
--
;
cpu_data
(
sibling
).
booted_cores
--
;
}
}
for_each_cpu
(
sibling
,
topology_die_cpumask
(
cpu
))
cpumask_clear_cpu
(
cpu
,
topology_die_cpumask
(
sibling
));
for_each_cpu
(
sibling
,
topology_sibling_cpumask
(
cpu
))
for_each_cpu
(
sibling
,
topology_sibling_cpumask
(
cpu
))
cpumask_clear_cpu
(
cpu
,
topology_sibling_cpumask
(
sibling
));
cpumask_clear_cpu
(
cpu
,
topology_sibling_cpumask
(
sibling
));
for_each_cpu
(
sibling
,
cpu_llc_shared_mask
(
cpu
))
for_each_cpu
(
sibling
,
cpu_llc_shared_mask
(
cpu
))
...
@@ -1496,6 +1564,7 @@ static void remove_siblinginfo(int cpu)
...
@@ -1496,6 +1564,7 @@ static void remove_siblinginfo(int cpu)
cpumask_clear
(
cpu_llc_shared_mask
(
cpu
));
cpumask_clear
(
cpu_llc_shared_mask
(
cpu
));
cpumask_clear
(
topology_sibling_cpumask
(
cpu
));
cpumask_clear
(
topology_sibling_cpumask
(
cpu
));
cpumask_clear
(
topology_core_cpumask
(
cpu
));
cpumask_clear
(
topology_core_cpumask
(
cpu
));
cpumask_clear
(
topology_die_cpumask
(
cpu
));
c
->
cpu_core_id
=
0
;
c
->
cpu_core_id
=
0
;
c
->
booted_cores
=
0
;
c
->
booted_cores
=
0
;
cpumask_clear_cpu
(
cpu
,
cpu_sibling_setup_mask
);
cpumask_clear_cpu
(
cpu
,
cpu_sibling_setup_mask
);
...
...
arch/x86/xen/smp_pv.c
浏览文件 @
3384c786
...
@@ -251,6 +251,7 @@ static void __init xen_pv_smp_prepare_cpus(unsigned int max_cpus)
...
@@ -251,6 +251,7 @@ static void __init xen_pv_smp_prepare_cpus(unsigned int max_cpus)
for_each_possible_cpu
(
i
)
{
for_each_possible_cpu
(
i
)
{
zalloc_cpumask_var
(
&
per_cpu
(
cpu_sibling_map
,
i
),
GFP_KERNEL
);
zalloc_cpumask_var
(
&
per_cpu
(
cpu_sibling_map
,
i
),
GFP_KERNEL
);
zalloc_cpumask_var
(
&
per_cpu
(
cpu_core_map
,
i
),
GFP_KERNEL
);
zalloc_cpumask_var
(
&
per_cpu
(
cpu_core_map
,
i
),
GFP_KERNEL
);
zalloc_cpumask_var
(
&
per_cpu
(
cpu_die_map
,
i
),
GFP_KERNEL
);
zalloc_cpumask_var
(
&
per_cpu
(
cpu_llc_shared_map
,
i
),
GFP_KERNEL
);
zalloc_cpumask_var
(
&
per_cpu
(
cpu_llc_shared_map
,
i
),
GFP_KERNEL
);
}
}
set_cpu_sibling_map
(
0
);
set_cpu_sibling_map
(
0
);
...
...
drivers/base/topology.c
浏览文件 @
3384c786
...
@@ -43,6 +43,9 @@ static ssize_t name##_list_show(struct device *dev, \
...
@@ -43,6 +43,9 @@ static ssize_t name##_list_show(struct device *dev, \
define_id_show_func
(
physical_package_id
);
define_id_show_func
(
physical_package_id
);
static
DEVICE_ATTR_RO
(
physical_package_id
);
static
DEVICE_ATTR_RO
(
physical_package_id
);
define_id_show_func
(
die_id
);
static
DEVICE_ATTR_RO
(
die_id
);
define_id_show_func
(
core_id
);
define_id_show_func
(
core_id
);
static
DEVICE_ATTR_RO
(
core_id
);
static
DEVICE_ATTR_RO
(
core_id
);
...
@@ -50,10 +53,22 @@ define_siblings_show_func(thread_siblings, sibling_cpumask);
...
@@ -50,10 +53,22 @@ define_siblings_show_func(thread_siblings, sibling_cpumask);
static
DEVICE_ATTR_RO
(
thread_siblings
);
static
DEVICE_ATTR_RO
(
thread_siblings
);
static
DEVICE_ATTR_RO
(
thread_siblings_list
);
static
DEVICE_ATTR_RO
(
thread_siblings_list
);
define_siblings_show_func
(
core_cpus
,
sibling_cpumask
);
static
DEVICE_ATTR_RO
(
core_cpus
);
static
DEVICE_ATTR_RO
(
core_cpus_list
);
define_siblings_show_func
(
core_siblings
,
core_cpumask
);
define_siblings_show_func
(
core_siblings
,
core_cpumask
);
static
DEVICE_ATTR_RO
(
core_siblings
);
static
DEVICE_ATTR_RO
(
core_siblings
);
static
DEVICE_ATTR_RO
(
core_siblings_list
);
static
DEVICE_ATTR_RO
(
core_siblings_list
);
define_siblings_show_func
(
die_cpus
,
die_cpumask
);
static
DEVICE_ATTR_RO
(
die_cpus
);
static
DEVICE_ATTR_RO
(
die_cpus_list
);
define_siblings_show_func
(
package_cpus
,
core_cpumask
);
static
DEVICE_ATTR_RO
(
package_cpus
);
static
DEVICE_ATTR_RO
(
package_cpus_list
);
#ifdef CONFIG_SCHED_BOOK
#ifdef CONFIG_SCHED_BOOK
define_id_show_func
(
book_id
);
define_id_show_func
(
book_id
);
static
DEVICE_ATTR_RO
(
book_id
);
static
DEVICE_ATTR_RO
(
book_id
);
...
@@ -72,11 +87,18 @@ static DEVICE_ATTR_RO(drawer_siblings_list);
...
@@ -72,11 +87,18 @@ static DEVICE_ATTR_RO(drawer_siblings_list);
static
struct
attribute
*
default_attrs
[]
=
{
static
struct
attribute
*
default_attrs
[]
=
{
&
dev_attr_physical_package_id
.
attr
,
&
dev_attr_physical_package_id
.
attr
,
&
dev_attr_die_id
.
attr
,
&
dev_attr_core_id
.
attr
,
&
dev_attr_core_id
.
attr
,
&
dev_attr_thread_siblings
.
attr
,
&
dev_attr_thread_siblings
.
attr
,
&
dev_attr_thread_siblings_list
.
attr
,
&
dev_attr_thread_siblings_list
.
attr
,
&
dev_attr_core_cpus
.
attr
,
&
dev_attr_core_cpus_list
.
attr
,
&
dev_attr_core_siblings
.
attr
,
&
dev_attr_core_siblings
.
attr
,
&
dev_attr_core_siblings_list
.
attr
,
&
dev_attr_core_siblings_list
.
attr
,
&
dev_attr_die_cpus
.
attr
,
&
dev_attr_die_cpus_list
.
attr
,
&
dev_attr_package_cpus
.
attr
,
&
dev_attr_package_cpus_list
.
attr
,
#ifdef CONFIG_SCHED_BOOK
#ifdef CONFIG_SCHED_BOOK
&
dev_attr_book_id
.
attr
,
&
dev_attr_book_id
.
attr
,
&
dev_attr_book_siblings
.
attr
,
&
dev_attr_book_siblings
.
attr
,
...
...
drivers/hwmon/coretemp.c
浏览文件 @
3384c786
...
@@ -96,10 +96,10 @@ struct platform_data {
...
@@ -96,10 +96,10 @@ struct platform_data {
struct
device_attribute
name_attr
;
struct
device_attribute
name_attr
;
};
};
/* Keep track of how many
packag
e pointers we allocated in init() */
/* Keep track of how many
zon
e pointers we allocated in init() */
static
int
max_
packag
es
__read_mostly
;
static
int
max_
zon
es
__read_mostly
;
/* Array of
packag
e pointers. Serialized by cpu hotplug lock */
/* Array of
zon
e pointers. Serialized by cpu hotplug lock */
static
struct
platform_device
**
pkg
_devices
;
static
struct
platform_device
**
zone
_devices
;
static
ssize_t
show_label
(
struct
device
*
dev
,
static
ssize_t
show_label
(
struct
device
*
dev
,
struct
device_attribute
*
devattr
,
char
*
buf
)
struct
device_attribute
*
devattr
,
char
*
buf
)
...
@@ -422,10 +422,10 @@ static int chk_ucode_version(unsigned int cpu)
...
@@ -422,10 +422,10 @@ static int chk_ucode_version(unsigned int cpu)
static
struct
platform_device
*
coretemp_get_pdev
(
unsigned
int
cpu
)
static
struct
platform_device
*
coretemp_get_pdev
(
unsigned
int
cpu
)
{
{
int
pkgid
=
topology_logical_packag
e_id
(
cpu
);
int
id
=
topology_logical_di
e_id
(
cpu
);
if
(
pkgid
>=
0
&&
pkgid
<
max_packag
es
)
if
(
id
>=
0
&&
id
<
max_zon
es
)
return
pkg_devices
[
pkg
id
];
return
zone_devices
[
id
];
return
NULL
;
return
NULL
;
}
}
...
@@ -531,7 +531,7 @@ static int coretemp_probe(struct platform_device *pdev)
...
@@ -531,7 +531,7 @@ static int coretemp_probe(struct platform_device *pdev)
struct
device
*
dev
=
&
pdev
->
dev
;
struct
device
*
dev
=
&
pdev
->
dev
;
struct
platform_data
*
pdata
;
struct
platform_data
*
pdata
;
/* Initialize the per-
packag
e data structures */
/* Initialize the per-
zon
e data structures */
pdata
=
devm_kzalloc
(
dev
,
sizeof
(
struct
platform_data
),
GFP_KERNEL
);
pdata
=
devm_kzalloc
(
dev
,
sizeof
(
struct
platform_data
),
GFP_KERNEL
);
if
(
!
pdata
)
if
(
!
pdata
)
return
-
ENOMEM
;
return
-
ENOMEM
;
...
@@ -566,13 +566,13 @@ static struct platform_driver coretemp_driver = {
...
@@ -566,13 +566,13 @@ static struct platform_driver coretemp_driver = {
static
struct
platform_device
*
coretemp_device_add
(
unsigned
int
cpu
)
static
struct
platform_device
*
coretemp_device_add
(
unsigned
int
cpu
)
{
{
int
err
,
pkgid
=
topology_logical_packag
e_id
(
cpu
);
int
err
,
zoneid
=
topology_logical_di
e_id
(
cpu
);
struct
platform_device
*
pdev
;
struct
platform_device
*
pdev
;
if
(
pkg
id
<
0
)
if
(
zone
id
<
0
)
return
ERR_PTR
(
-
ENOMEM
);
return
ERR_PTR
(
-
ENOMEM
);
pdev
=
platform_device_alloc
(
DRVNAME
,
pkg
id
);
pdev
=
platform_device_alloc
(
DRVNAME
,
zone
id
);
if
(
!
pdev
)
if
(
!
pdev
)
return
ERR_PTR
(
-
ENOMEM
);
return
ERR_PTR
(
-
ENOMEM
);
...
@@ -582,7 +582,7 @@ static struct platform_device *coretemp_device_add(unsigned int cpu)
...
@@ -582,7 +582,7 @@ static struct platform_device *coretemp_device_add(unsigned int cpu)
return
ERR_PTR
(
err
);
return
ERR_PTR
(
err
);
}
}
pkg_devices
[
pkg
id
]
=
pdev
;
zone_devices
[
zone
id
]
=
pdev
;
return
pdev
;
return
pdev
;
}
}
...
@@ -690,7 +690,7 @@ static int coretemp_cpu_offline(unsigned int cpu)
...
@@ -690,7 +690,7 @@ static int coretemp_cpu_offline(unsigned int cpu)
* the rest.
* the rest.
*/
*/
if
(
cpumask_empty
(
&
pd
->
cpumask
))
{
if
(
cpumask_empty
(
&
pd
->
cpumask
))
{
pkg_devices
[
topology_logical_packag
e_id
(
cpu
)]
=
NULL
;
zone_devices
[
topology_logical_di
e_id
(
cpu
)]
=
NULL
;
platform_device_unregister
(
pdev
);
platform_device_unregister
(
pdev
);
return
0
;
return
0
;
}
}
...
@@ -728,10 +728,10 @@ static int __init coretemp_init(void)
...
@@ -728,10 +728,10 @@ static int __init coretemp_init(void)
if
(
!
x86_match_cpu
(
coretemp_ids
))
if
(
!
x86_match_cpu
(
coretemp_ids
))
return
-
ENODEV
;
return
-
ENODEV
;
max_
packages
=
topology_max_packages
();
max_
zones
=
topology_max_packages
()
*
topology_max_die_per_package
();
pkg_devices
=
kcalloc
(
max_packag
es
,
sizeof
(
struct
platform_device
*
),
zone_devices
=
kcalloc
(
max_zon
es
,
sizeof
(
struct
platform_device
*
),
GFP_KERNEL
);
GFP_KERNEL
);
if
(
!
pkg
_devices
)
if
(
!
zone
_devices
)
return
-
ENOMEM
;
return
-
ENOMEM
;
err
=
platform_driver_register
(
&
coretemp_driver
);
err
=
platform_driver_register
(
&
coretemp_driver
);
...
@@ -747,7 +747,7 @@ static int __init coretemp_init(void)
...
@@ -747,7 +747,7 @@ static int __init coretemp_init(void)
outdrv:
outdrv:
platform_driver_unregister
(
&
coretemp_driver
);
platform_driver_unregister
(
&
coretemp_driver
);
kfree
(
pkg
_devices
);
kfree
(
zone
_devices
);
return
err
;
return
err
;
}
}
module_init
(
coretemp_init
)
module_init
(
coretemp_init
)
...
@@ -756,7 +756,7 @@ static void __exit coretemp_exit(void)
...
@@ -756,7 +756,7 @@ static void __exit coretemp_exit(void)
{
{
cpuhp_remove_state
(
coretemp_hp_online
);
cpuhp_remove_state
(
coretemp_hp_online
);
platform_driver_unregister
(
&
coretemp_driver
);
platform_driver_unregister
(
&
coretemp_driver
);
kfree
(
pkg
_devices
);
kfree
(
zone
_devices
);
}
}
module_exit
(
coretemp_exit
)
module_exit
(
coretemp_exit
)
...
...
drivers/powercap/intel_rapl.c
浏览文件 @
3384c786
...
@@ -178,12 +178,15 @@ struct rapl_domain {
...
@@ -178,12 +178,15 @@ struct rapl_domain {
#define power_zone_to_rapl_domain(_zone) \
#define power_zone_to_rapl_domain(_zone) \
container_of(_zone, struct rapl_domain, power_zone)
container_of(_zone, struct rapl_domain, power_zone)
/* maximum rapl package domain name: package-%d-die-%d */
#define PACKAGE_DOMAIN_NAME_LENGTH 30
/* Each physical package contains multiple domains, these are the common
/* Each rapl package contains multiple domains, these are the common
* data across RAPL domains within a package.
* data across RAPL domains within a package.
*/
*/
struct
rapl_package
{
struct
rapl_package
{
unsigned
int
id
;
/*
physical package/socket id
*/
unsigned
int
id
;
/*
logical die id, equals physical 1-die systems
*/
unsigned
int
nr_domains
;
unsigned
int
nr_domains
;
unsigned
long
domain_map
;
/* bit map of active domains */
unsigned
long
domain_map
;
/* bit map of active domains */
unsigned
int
power_unit
;
unsigned
int
power_unit
;
...
@@ -198,6 +201,7 @@ struct rapl_package {
...
@@ -198,6 +201,7 @@ struct rapl_package {
int
lead_cpu
;
/* one active cpu per package for access */
int
lead_cpu
;
/* one active cpu per package for access */
/* Track active cpus */
/* Track active cpus */
struct
cpumask
cpumask
;
struct
cpumask
cpumask
;
char
name
[
PACKAGE_DOMAIN_NAME_LENGTH
];
};
};
struct
rapl_defaults
{
struct
rapl_defaults
{
...
@@ -264,8 +268,9 @@ static struct powercap_control_type *control_type; /* PowerCap Controller */
...
@@ -264,8 +268,9 @@ static struct powercap_control_type *control_type; /* PowerCap Controller */
static
struct
rapl_domain
*
platform_rapl_domain
;
/* Platform (PSys) domain */
static
struct
rapl_domain
*
platform_rapl_domain
;
/* Platform (PSys) domain */
/* caller to ensure CPU hotplug lock is held */
/* caller to ensure CPU hotplug lock is held */
static
struct
rapl_package
*
find_package_by_id
(
int
id
)
static
struct
rapl_package
*
rapl_find_package_domain
(
int
cpu
)
{
{
int
id
=
topology_logical_die_id
(
cpu
);
struct
rapl_package
*
rp
;
struct
rapl_package
*
rp
;
list_for_each_entry
(
rp
,
&
rapl_packages
,
plist
)
{
list_for_each_entry
(
rp
,
&
rapl_packages
,
plist
)
{
...
@@ -925,8 +930,8 @@ static int rapl_check_unit_core(struct rapl_package *rp, int cpu)
...
@@ -925,8 +930,8 @@ static int rapl_check_unit_core(struct rapl_package *rp, int cpu)
value
=
(
msr_val
&
TIME_UNIT_MASK
)
>>
TIME_UNIT_OFFSET
;
value
=
(
msr_val
&
TIME_UNIT_MASK
)
>>
TIME_UNIT_OFFSET
;
rp
->
time_unit
=
1000000
/
(
1
<<
value
);
rp
->
time_unit
=
1000000
/
(
1
<<
value
);
pr_debug
(
"Core CPU
package %d
energy=%dpJ, time=%dus, power=%duW
\n
"
,
pr_debug
(
"Core CPU
%s
energy=%dpJ, time=%dus, power=%duW
\n
"
,
rp
->
id
,
rp
->
energy_unit
,
rp
->
time_unit
,
rp
->
power_unit
);
rp
->
name
,
rp
->
energy_unit
,
rp
->
time_unit
,
rp
->
power_unit
);
return
0
;
return
0
;
}
}
...
@@ -950,8 +955,8 @@ static int rapl_check_unit_atom(struct rapl_package *rp, int cpu)
...
@@ -950,8 +955,8 @@ static int rapl_check_unit_atom(struct rapl_package *rp, int cpu)
value
=
(
msr_val
&
TIME_UNIT_MASK
)
>>
TIME_UNIT_OFFSET
;
value
=
(
msr_val
&
TIME_UNIT_MASK
)
>>
TIME_UNIT_OFFSET
;
rp
->
time_unit
=
1000000
/
(
1
<<
value
);
rp
->
time_unit
=
1000000
/
(
1
<<
value
);
pr_debug
(
"Atom
package %d
energy=%dpJ, time=%dus, power=%duW
\n
"
,
pr_debug
(
"Atom
%s
energy=%dpJ, time=%dus, power=%duW
\n
"
,
rp
->
id
,
rp
->
energy_unit
,
rp
->
time_unit
,
rp
->
power_unit
);
rp
->
name
,
rp
->
energy_unit
,
rp
->
time_unit
,
rp
->
power_unit
);
return
0
;
return
0
;
}
}
...
@@ -1180,7 +1185,7 @@ static void rapl_update_domain_data(struct rapl_package *rp)
...
@@ -1180,7 +1185,7 @@ static void rapl_update_domain_data(struct rapl_package *rp)
u64
val
;
u64
val
;
for
(
dmn
=
0
;
dmn
<
rp
->
nr_domains
;
dmn
++
)
{
for
(
dmn
=
0
;
dmn
<
rp
->
nr_domains
;
dmn
++
)
{
pr_debug
(
"update
package %d domain %s data
\n
"
,
rp
->
id
,
pr_debug
(
"update
%s domain %s data
\n
"
,
rp
->
name
,
rp
->
domains
[
dmn
].
name
);
rp
->
domains
[
dmn
].
name
);
/* exclude non-raw primitives */
/* exclude non-raw primitives */
for
(
prim
=
0
;
prim
<
NR_RAW_PRIMITIVES
;
prim
++
)
{
for
(
prim
=
0
;
prim
<
NR_RAW_PRIMITIVES
;
prim
++
)
{
...
@@ -1205,7 +1210,6 @@ static void rapl_unregister_powercap(void)
...
@@ -1205,7 +1210,6 @@ static void rapl_unregister_powercap(void)
static
int
rapl_package_register_powercap
(
struct
rapl_package
*
rp
)
static
int
rapl_package_register_powercap
(
struct
rapl_package
*
rp
)
{
{
struct
rapl_domain
*
rd
;
struct
rapl_domain
*
rd
;
char
dev_name
[
17
];
/* max domain name = 7 + 1 + 8 for int + 1 for null*/
struct
powercap_zone
*
power_zone
=
NULL
;
struct
powercap_zone
*
power_zone
=
NULL
;
int
nr_pl
,
ret
;
int
nr_pl
,
ret
;
...
@@ -1216,20 +1220,16 @@ static int rapl_package_register_powercap(struct rapl_package *rp)
...
@@ -1216,20 +1220,16 @@ static int rapl_package_register_powercap(struct rapl_package *rp)
for
(
rd
=
rp
->
domains
;
rd
<
rp
->
domains
+
rp
->
nr_domains
;
rd
++
)
{
for
(
rd
=
rp
->
domains
;
rd
<
rp
->
domains
+
rp
->
nr_domains
;
rd
++
)
{
if
(
rd
->
id
==
RAPL_DOMAIN_PACKAGE
)
{
if
(
rd
->
id
==
RAPL_DOMAIN_PACKAGE
)
{
nr_pl
=
find_nr_power_limit
(
rd
);
nr_pl
=
find_nr_power_limit
(
rd
);
pr_debug
(
"register socket %d package domain %s
\n
"
,
pr_debug
(
"register package domain %s
\n
"
,
rp
->
name
);
rp
->
id
,
rd
->
name
);
memset
(
dev_name
,
0
,
sizeof
(
dev_name
));
snprintf
(
dev_name
,
sizeof
(
dev_name
),
"%s-%d"
,
rd
->
name
,
rp
->
id
);
power_zone
=
powercap_register_zone
(
&
rd
->
power_zone
,
power_zone
=
powercap_register_zone
(
&
rd
->
power_zone
,
control_type
,
control_type
,
dev_
name
,
NULL
,
rp
->
name
,
NULL
,
&
zone_ops
[
rd
->
id
],
&
zone_ops
[
rd
->
id
],
nr_pl
,
nr_pl
,
&
constraint_ops
);
&
constraint_ops
);
if
(
IS_ERR
(
power_zone
))
{
if
(
IS_ERR
(
power_zone
))
{
pr_debug
(
"failed to register p
ackage, %d
\n
"
,
pr_debug
(
"failed to register p
ower zone %s
\n
"
,
rp
->
id
);
rp
->
name
);
return
PTR_ERR
(
power_zone
);
return
PTR_ERR
(
power_zone
);
}
}
/* track parent zone in per package/socket data */
/* track parent zone in per package/socket data */
...
@@ -1255,8 +1255,8 @@ static int rapl_package_register_powercap(struct rapl_package *rp)
...
@@ -1255,8 +1255,8 @@ static int rapl_package_register_powercap(struct rapl_package *rp)
&
constraint_ops
);
&
constraint_ops
);
if
(
IS_ERR
(
power_zone
))
{
if
(
IS_ERR
(
power_zone
))
{
pr_debug
(
"failed to register power_zone, %
d:%
s:%s
\n
"
,
pr_debug
(
"failed to register power_zone, %s:%s
\n
"
,
rp
->
id
,
rd
->
name
,
dev_
name
);
rp
->
name
,
rd
->
name
);
ret
=
PTR_ERR
(
power_zone
);
ret
=
PTR_ERR
(
power_zone
);
goto
err_cleanup
;
goto
err_cleanup
;
}
}
...
@@ -1269,7 +1269,7 @@ static int rapl_package_register_powercap(struct rapl_package *rp)
...
@@ -1269,7 +1269,7 @@ static int rapl_package_register_powercap(struct rapl_package *rp)
* failed after the first domain setup.
* failed after the first domain setup.
*/
*/
while
(
--
rd
>=
rp
->
domains
)
{
while
(
--
rd
>=
rp
->
domains
)
{
pr_debug
(
"unregister
package %d domain %s
\n
"
,
rp
->
id
,
rd
->
name
);
pr_debug
(
"unregister
%s domain %s
\n
"
,
rp
->
name
,
rd
->
name
);
powercap_unregister_zone
(
control_type
,
&
rd
->
power_zone
);
powercap_unregister_zone
(
control_type
,
&
rd
->
power_zone
);
}
}
...
@@ -1300,7 +1300,7 @@ static int __init rapl_register_psys(void)
...
@@ -1300,7 +1300,7 @@ static int __init rapl_register_psys(void)
rd
->
rpl
[
0
].
name
=
pl1_name
;
rd
->
rpl
[
0
].
name
=
pl1_name
;
rd
->
rpl
[
1
].
prim_id
=
PL2_ENABLE
;
rd
->
rpl
[
1
].
prim_id
=
PL2_ENABLE
;
rd
->
rpl
[
1
].
name
=
pl2_name
;
rd
->
rpl
[
1
].
name
=
pl2_name
;
rd
->
rp
=
find_package_by_id
(
0
);
rd
->
rp
=
rapl_find_package_domain
(
0
);
power_zone
=
powercap_register_zone
(
&
rd
->
power_zone
,
control_type
,
power_zone
=
powercap_register_zone
(
&
rd
->
power_zone
,
control_type
,
"psys"
,
NULL
,
"psys"
,
NULL
,
...
@@ -1379,8 +1379,8 @@ static void rapl_detect_powerlimit(struct rapl_domain *rd)
...
@@ -1379,8 +1379,8 @@ static void rapl_detect_powerlimit(struct rapl_domain *rd)
/* check if the domain is locked by BIOS, ignore if MSR doesn't exist */
/* check if the domain is locked by BIOS, ignore if MSR doesn't exist */
if
(
!
rapl_read_data_raw
(
rd
,
FW_LOCK
,
false
,
&
val64
))
{
if
(
!
rapl_read_data_raw
(
rd
,
FW_LOCK
,
false
,
&
val64
))
{
if
(
val64
)
{
if
(
val64
)
{
pr_info
(
"RAPL
package %d
domain %s locked by BIOS
\n
"
,
pr_info
(
"RAPL
%s
domain %s locked by BIOS
\n
"
,
rd
->
rp
->
id
,
rd
->
name
);
rd
->
rp
->
name
,
rd
->
name
);
rd
->
state
|=
DOMAIN_STATE_BIOS_LOCKED
;
rd
->
state
|=
DOMAIN_STATE_BIOS_LOCKED
;
}
}
}
}
...
@@ -1409,10 +1409,10 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu)
...
@@ -1409,10 +1409,10 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu)
}
}
rp
->
nr_domains
=
bitmap_weight
(
&
rp
->
domain_map
,
RAPL_DOMAIN_MAX
);
rp
->
nr_domains
=
bitmap_weight
(
&
rp
->
domain_map
,
RAPL_DOMAIN_MAX
);
if
(
!
rp
->
nr_domains
)
{
if
(
!
rp
->
nr_domains
)
{
pr_debug
(
"no valid rapl domains found in
package %d
\n
"
,
rp
->
id
);
pr_debug
(
"no valid rapl domains found in
%s
\n
"
,
rp
->
name
);
return
-
ENODEV
;
return
-
ENODEV
;
}
}
pr_debug
(
"found %d domains on
package %d
\n
"
,
rp
->
nr_domains
,
rp
->
id
);
pr_debug
(
"found %d domains on
%s
\n
"
,
rp
->
nr_domains
,
rp
->
name
);
rp
->
domains
=
kcalloc
(
rp
->
nr_domains
+
1
,
sizeof
(
struct
rapl_domain
),
rp
->
domains
=
kcalloc
(
rp
->
nr_domains
+
1
,
sizeof
(
struct
rapl_domain
),
GFP_KERNEL
);
GFP_KERNEL
);
...
@@ -1445,8 +1445,8 @@ static void rapl_remove_package(struct rapl_package *rp)
...
@@ -1445,8 +1445,8 @@ static void rapl_remove_package(struct rapl_package *rp)
rd_package
=
rd
;
rd_package
=
rd
;
continue
;
continue
;
}
}
pr_debug
(
"remove package, undo power limit on %
d
: %s
\n
"
,
pr_debug
(
"remove package, undo power limit on %
s
: %s
\n
"
,
rp
->
id
,
rd
->
name
);
rp
->
name
,
rd
->
name
);
powercap_unregister_zone
(
control_type
,
&
rd
->
power_zone
);
powercap_unregister_zone
(
control_type
,
&
rd
->
power_zone
);
}
}
/* do parent zone last */
/* do parent zone last */
...
@@ -1456,9 +1456,11 @@ static void rapl_remove_package(struct rapl_package *rp)
...
@@ -1456,9 +1456,11 @@ static void rapl_remove_package(struct rapl_package *rp)
}
}
/* called from CPU hotplug notifier, hotplug lock held */
/* called from CPU hotplug notifier, hotplug lock held */
static
struct
rapl_package
*
rapl_add_package
(
int
cpu
,
int
pkgid
)
static
struct
rapl_package
*
rapl_add_package
(
int
cpu
)
{
{
int
id
=
topology_logical_die_id
(
cpu
);
struct
rapl_package
*
rp
;
struct
rapl_package
*
rp
;
struct
cpuinfo_x86
*
c
=
&
cpu_data
(
cpu
);
int
ret
;
int
ret
;
rp
=
kzalloc
(
sizeof
(
struct
rapl_package
),
GFP_KERNEL
);
rp
=
kzalloc
(
sizeof
(
struct
rapl_package
),
GFP_KERNEL
);
...
@@ -1466,9 +1468,16 @@ static struct rapl_package *rapl_add_package(int cpu, int pkgid)
...
@@ -1466,9 +1468,16 @@ static struct rapl_package *rapl_add_package(int cpu, int pkgid)
return
ERR_PTR
(
-
ENOMEM
);
return
ERR_PTR
(
-
ENOMEM
);
/* add the new package to the list */
/* add the new package to the list */
rp
->
id
=
pkg
id
;
rp
->
id
=
id
;
rp
->
lead_cpu
=
cpu
;
rp
->
lead_cpu
=
cpu
;
if
(
topology_max_die_per_package
()
>
1
)
snprintf
(
rp
->
name
,
PACKAGE_DOMAIN_NAME_LENGTH
,
"package-%d-die-%d"
,
c
->
phys_proc_id
,
c
->
cpu_die_id
);
else
snprintf
(
rp
->
name
,
PACKAGE_DOMAIN_NAME_LENGTH
,
"package-%d"
,
c
->
phys_proc_id
);
/* check if the package contains valid domains */
/* check if the package contains valid domains */
if
(
rapl_detect_domains
(
rp
,
cpu
)
||
if
(
rapl_detect_domains
(
rp
,
cpu
)
||
rapl_defaults
->
check_unit
(
rp
,
cpu
))
{
rapl_defaults
->
check_unit
(
rp
,
cpu
))
{
...
@@ -1497,12 +1506,11 @@ static struct rapl_package *rapl_add_package(int cpu, int pkgid)
...
@@ -1497,12 +1506,11 @@ static struct rapl_package *rapl_add_package(int cpu, int pkgid)
*/
*/
static
int
rapl_cpu_online
(
unsigned
int
cpu
)
static
int
rapl_cpu_online
(
unsigned
int
cpu
)
{
{
int
pkgid
=
topology_physical_package_id
(
cpu
);
struct
rapl_package
*
rp
;
struct
rapl_package
*
rp
;
rp
=
find_package_by_id
(
pkgid
);
rp
=
rapl_find_package_domain
(
cpu
);
if
(
!
rp
)
{
if
(
!
rp
)
{
rp
=
rapl_add_package
(
cpu
,
pkgid
);
rp
=
rapl_add_package
(
cpu
);
if
(
IS_ERR
(
rp
))
if
(
IS_ERR
(
rp
))
return
PTR_ERR
(
rp
);
return
PTR_ERR
(
rp
);
}
}
...
@@ -1512,11 +1520,10 @@ static int rapl_cpu_online(unsigned int cpu)
...
@@ -1512,11 +1520,10 @@ static int rapl_cpu_online(unsigned int cpu)
static
int
rapl_cpu_down_prep
(
unsigned
int
cpu
)
static
int
rapl_cpu_down_prep
(
unsigned
int
cpu
)
{
{
int
pkgid
=
topology_physical_package_id
(
cpu
);
struct
rapl_package
*
rp
;
struct
rapl_package
*
rp
;
int
lead_cpu
;
int
lead_cpu
;
rp
=
find_package_by_id
(
pkgid
);
rp
=
rapl_find_package_domain
(
cpu
);
if
(
!
rp
)
if
(
!
rp
)
return
0
;
return
0
;
...
...
drivers/thermal/intel/x86_pkg_temp_thermal.c
浏览文件 @
3384c786
...
@@ -55,7 +55,7 @@ MODULE_PARM_DESC(notify_delay_ms,
...
@@ -55,7 +55,7 @@ MODULE_PARM_DESC(notify_delay_ms,
*/
*/
#define MAX_NUMBER_OF_TRIPS 2
#define MAX_NUMBER_OF_TRIPS 2
struct
pkg
_device
{
struct
zone
_device
{
int
cpu
;
int
cpu
;
bool
work_scheduled
;
bool
work_scheduled
;
u32
tj_max
;
u32
tj_max
;
...
@@ -70,10 +70,10 @@ static struct thermal_zone_params pkg_temp_tz_params = {
...
@@ -70,10 +70,10 @@ static struct thermal_zone_params pkg_temp_tz_params = {
.
no_hwmon
=
true
,
.
no_hwmon
=
true
,
};
};
/* Keep track of how many
packag
e pointers we allocated in init() */
/* Keep track of how many
zon
e pointers we allocated in init() */
static
int
max_
packages
__read_mostly
;
static
int
max_
id
__read_mostly
;
/* Array of
packag
e pointers */
/* Array of
zon
e pointers */
static
struct
pkg_device
**
packag
es
;
static
struct
zone_device
**
zon
es
;
/* Serializes interrupt notification, work and hotplug */
/* Serializes interrupt notification, work and hotplug */
static
DEFINE_SPINLOCK
(
pkg_temp_lock
);
static
DEFINE_SPINLOCK
(
pkg_temp_lock
);
/* Protects zone operation in the work function against hotplug removal */
/* Protects zone operation in the work function against hotplug removal */
...
@@ -120,12 +120,12 @@ static int pkg_temp_debugfs_init(void)
...
@@ -120,12 +120,12 @@ static int pkg_temp_debugfs_init(void)
*
*
* - Other callsites: Must hold pkg_temp_lock
* - Other callsites: Must hold pkg_temp_lock
*/
*/
static
struct
pkg
_device
*
pkg_temp_thermal_get_dev
(
unsigned
int
cpu
)
static
struct
zone
_device
*
pkg_temp_thermal_get_dev
(
unsigned
int
cpu
)
{
{
int
pkgid
=
topology_logical_packag
e_id
(
cpu
);
int
id
=
topology_logical_di
e_id
(
cpu
);
if
(
pkgid
>=
0
&&
pkgid
<
max_packages
)
if
(
id
>=
0
&&
id
<
max_id
)
return
packages
[
pkg
id
];
return
zones
[
id
];
return
NULL
;
return
NULL
;
}
}
...
@@ -150,12 +150,13 @@ static int get_tj_max(int cpu, u32 *tj_max)
...
@@ -150,12 +150,13 @@ static int get_tj_max(int cpu, u32 *tj_max)
static
int
sys_get_curr_temp
(
struct
thermal_zone_device
*
tzd
,
int
*
temp
)
static
int
sys_get_curr_temp
(
struct
thermal_zone_device
*
tzd
,
int
*
temp
)
{
{
struct
pkg_device
*
pkg
dev
=
tzd
->
devdata
;
struct
zone_device
*
zone
dev
=
tzd
->
devdata
;
u32
eax
,
edx
;
u32
eax
,
edx
;
rdmsr_on_cpu
(
pkgdev
->
cpu
,
MSR_IA32_PACKAGE_THERM_STATUS
,
&
eax
,
&
edx
);
rdmsr_on_cpu
(
zonedev
->
cpu
,
MSR_IA32_PACKAGE_THERM_STATUS
,
&
eax
,
&
edx
);
if
(
eax
&
0x80000000
)
{
if
(
eax
&
0x80000000
)
{
*
temp
=
pkg
dev
->
tj_max
-
((
eax
>>
16
)
&
0x7f
)
*
1000
;
*
temp
=
zone
dev
->
tj_max
-
((
eax
>>
16
)
&
0x7f
)
*
1000
;
pr_debug
(
"sys_get_curr_temp %d
\n
"
,
*
temp
);
pr_debug
(
"sys_get_curr_temp %d
\n
"
,
*
temp
);
return
0
;
return
0
;
}
}
...
@@ -165,7 +166,7 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
...
@@ -165,7 +166,7 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
static
int
sys_get_trip_temp
(
struct
thermal_zone_device
*
tzd
,
static
int
sys_get_trip_temp
(
struct
thermal_zone_device
*
tzd
,
int
trip
,
int
*
temp
)
int
trip
,
int
*
temp
)
{
{
struct
pkg_device
*
pkg
dev
=
tzd
->
devdata
;
struct
zone_device
*
zone
dev
=
tzd
->
devdata
;
unsigned
long
thres_reg_value
;
unsigned
long
thres_reg_value
;
u32
mask
,
shift
,
eax
,
edx
;
u32
mask
,
shift
,
eax
,
edx
;
int
ret
;
int
ret
;
...
@@ -181,14 +182,14 @@ static int sys_get_trip_temp(struct thermal_zone_device *tzd,
...
@@ -181,14 +182,14 @@ static int sys_get_trip_temp(struct thermal_zone_device *tzd,
shift
=
THERM_SHIFT_THRESHOLD0
;
shift
=
THERM_SHIFT_THRESHOLD0
;
}
}
ret
=
rdmsr_on_cpu
(
pkg
dev
->
cpu
,
MSR_IA32_PACKAGE_THERM_INTERRUPT
,
ret
=
rdmsr_on_cpu
(
zone
dev
->
cpu
,
MSR_IA32_PACKAGE_THERM_INTERRUPT
,
&
eax
,
&
edx
);
&
eax
,
&
edx
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
thres_reg_value
=
(
eax
&
mask
)
>>
shift
;
thres_reg_value
=
(
eax
&
mask
)
>>
shift
;
if
(
thres_reg_value
)
if
(
thres_reg_value
)
*
temp
=
pkg
dev
->
tj_max
-
thres_reg_value
*
1000
;
*
temp
=
zone
dev
->
tj_max
-
thres_reg_value
*
1000
;
else
else
*
temp
=
0
;
*
temp
=
0
;
pr_debug
(
"sys_get_trip_temp %d
\n
"
,
*
temp
);
pr_debug
(
"sys_get_trip_temp %d
\n
"
,
*
temp
);
...
@@ -199,14 +200,14 @@ static int sys_get_trip_temp(struct thermal_zone_device *tzd,
...
@@ -199,14 +200,14 @@ static int sys_get_trip_temp(struct thermal_zone_device *tzd,
static
int
static
int
sys_set_trip_temp
(
struct
thermal_zone_device
*
tzd
,
int
trip
,
int
temp
)
sys_set_trip_temp
(
struct
thermal_zone_device
*
tzd
,
int
trip
,
int
temp
)
{
{
struct
pkg_device
*
pkg
dev
=
tzd
->
devdata
;
struct
zone_device
*
zone
dev
=
tzd
->
devdata
;
u32
l
,
h
,
mask
,
shift
,
intr
;
u32
l
,
h
,
mask
,
shift
,
intr
;
int
ret
;
int
ret
;
if
(
trip
>=
MAX_NUMBER_OF_TRIPS
||
temp
>=
pkg
dev
->
tj_max
)
if
(
trip
>=
MAX_NUMBER_OF_TRIPS
||
temp
>=
zone
dev
->
tj_max
)
return
-
EINVAL
;
return
-
EINVAL
;
ret
=
rdmsr_on_cpu
(
pkg
dev
->
cpu
,
MSR_IA32_PACKAGE_THERM_INTERRUPT
,
ret
=
rdmsr_on_cpu
(
zone
dev
->
cpu
,
MSR_IA32_PACKAGE_THERM_INTERRUPT
,
&
l
,
&
h
);
&
l
,
&
h
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
...
@@ -228,11 +229,12 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
...
@@ -228,11 +229,12 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
if
(
!
temp
)
{
if
(
!
temp
)
{
l
&=
~
intr
;
l
&=
~
intr
;
}
else
{
}
else
{
l
|=
(
pkg
dev
->
tj_max
-
temp
)
/
1000
<<
shift
;
l
|=
(
zone
dev
->
tj_max
-
temp
)
/
1000
<<
shift
;
l
|=
intr
;
l
|=
intr
;
}
}
return
wrmsr_on_cpu
(
pkgdev
->
cpu
,
MSR_IA32_PACKAGE_THERM_INTERRUPT
,
l
,
h
);
return
wrmsr_on_cpu
(
zonedev
->
cpu
,
MSR_IA32_PACKAGE_THERM_INTERRUPT
,
l
,
h
);
}
}
static
int
sys_get_trip_type
(
struct
thermal_zone_device
*
thermal
,
int
trip
,
static
int
sys_get_trip_type
(
struct
thermal_zone_device
*
thermal
,
int
trip
,
...
@@ -287,26 +289,26 @@ static void pkg_temp_thermal_threshold_work_fn(struct work_struct *work)
...
@@ -287,26 +289,26 @@ static void pkg_temp_thermal_threshold_work_fn(struct work_struct *work)
{
{
struct
thermal_zone_device
*
tzone
=
NULL
;
struct
thermal_zone_device
*
tzone
=
NULL
;
int
cpu
=
smp_processor_id
();
int
cpu
=
smp_processor_id
();
struct
pkg_device
*
pkg
dev
;
struct
zone_device
*
zone
dev
;
u64
msr_val
,
wr_val
;
u64
msr_val
,
wr_val
;
mutex_lock
(
&
thermal_zone_mutex
);
mutex_lock
(
&
thermal_zone_mutex
);
spin_lock_irq
(
&
pkg_temp_lock
);
spin_lock_irq
(
&
pkg_temp_lock
);
++
pkg_work_cnt
;
++
pkg_work_cnt
;
pkg
dev
=
pkg_temp_thermal_get_dev
(
cpu
);
zone
dev
=
pkg_temp_thermal_get_dev
(
cpu
);
if
(
!
pkg
dev
)
{
if
(
!
zone
dev
)
{
spin_unlock_irq
(
&
pkg_temp_lock
);
spin_unlock_irq
(
&
pkg_temp_lock
);
mutex_unlock
(
&
thermal_zone_mutex
);
mutex_unlock
(
&
thermal_zone_mutex
);
return
;
return
;
}
}
pkg
dev
->
work_scheduled
=
false
;
zone
dev
->
work_scheduled
=
false
;
rdmsrl
(
MSR_IA32_PACKAGE_THERM_STATUS
,
msr_val
);
rdmsrl
(
MSR_IA32_PACKAGE_THERM_STATUS
,
msr_val
);
wr_val
=
msr_val
&
~
(
THERM_LOG_THRESHOLD0
|
THERM_LOG_THRESHOLD1
);
wr_val
=
msr_val
&
~
(
THERM_LOG_THRESHOLD0
|
THERM_LOG_THRESHOLD1
);
if
(
wr_val
!=
msr_val
)
{
if
(
wr_val
!=
msr_val
)
{
wrmsrl
(
MSR_IA32_PACKAGE_THERM_STATUS
,
wr_val
);
wrmsrl
(
MSR_IA32_PACKAGE_THERM_STATUS
,
wr_val
);
tzone
=
pkg
dev
->
tzone
;
tzone
=
zone
dev
->
tzone
;
}
}
enable_pkg_thres_interrupt
();
enable_pkg_thres_interrupt
();
...
@@ -332,7 +334,7 @@ static void pkg_thermal_schedule_work(int cpu, struct delayed_work *work)
...
@@ -332,7 +334,7 @@ static void pkg_thermal_schedule_work(int cpu, struct delayed_work *work)
static
int
pkg_thermal_notify
(
u64
msr_val
)
static
int
pkg_thermal_notify
(
u64
msr_val
)
{
{
int
cpu
=
smp_processor_id
();
int
cpu
=
smp_processor_id
();
struct
pkg_device
*
pkg
dev
;
struct
zone_device
*
zone
dev
;
unsigned
long
flags
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
pkg_temp_lock
,
flags
);
spin_lock_irqsave
(
&
pkg_temp_lock
,
flags
);
...
@@ -341,10 +343,10 @@ static int pkg_thermal_notify(u64 msr_val)
...
@@ -341,10 +343,10 @@ static int pkg_thermal_notify(u64 msr_val)
disable_pkg_thres_interrupt
();
disable_pkg_thres_interrupt
();
/* Work is per package, so scheduling it once is enough. */
/* Work is per package, so scheduling it once is enough. */
pkg
dev
=
pkg_temp_thermal_get_dev
(
cpu
);
zone
dev
=
pkg_temp_thermal_get_dev
(
cpu
);
if
(
pkgdev
&&
!
pkg
dev
->
work_scheduled
)
{
if
(
zonedev
&&
!
zone
dev
->
work_scheduled
)
{
pkg
dev
->
work_scheduled
=
true
;
zone
dev
->
work_scheduled
=
true
;
pkg_thermal_schedule_work
(
pkgdev
->
cpu
,
&
pkg
dev
->
work
);
pkg_thermal_schedule_work
(
zonedev
->
cpu
,
&
zone
dev
->
work
);
}
}
spin_unlock_irqrestore
(
&
pkg_temp_lock
,
flags
);
spin_unlock_irqrestore
(
&
pkg_temp_lock
,
flags
);
...
@@ -353,12 +355,12 @@ static int pkg_thermal_notify(u64 msr_val)
...
@@ -353,12 +355,12 @@ static int pkg_thermal_notify(u64 msr_val)
static
int
pkg_temp_thermal_device_add
(
unsigned
int
cpu
)
static
int
pkg_temp_thermal_device_add
(
unsigned
int
cpu
)
{
{
int
pkgid
=
topology_logical_packag
e_id
(
cpu
);
int
id
=
topology_logical_di
e_id
(
cpu
);
u32
tj_max
,
eax
,
ebx
,
ecx
,
edx
;
u32
tj_max
,
eax
,
ebx
,
ecx
,
edx
;
struct
pkg_device
*
pkg
dev
;
struct
zone_device
*
zone
dev
;
int
thres_count
,
err
;
int
thres_count
,
err
;
if
(
pkgid
>=
max_packages
)
if
(
id
>=
max_id
)
return
-
ENOMEM
;
return
-
ENOMEM
;
cpuid
(
6
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
cpuid
(
6
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
...
@@ -372,51 +374,51 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
...
@@ -372,51 +374,51 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
if
(
err
)
if
(
err
)
return
err
;
return
err
;
pkgdev
=
kzalloc
(
sizeof
(
*
pkg
dev
),
GFP_KERNEL
);
zonedev
=
kzalloc
(
sizeof
(
*
zone
dev
),
GFP_KERNEL
);
if
(
!
pkg
dev
)
if
(
!
zone
dev
)
return
-
ENOMEM
;
return
-
ENOMEM
;
INIT_DELAYED_WORK
(
&
pkg
dev
->
work
,
pkg_temp_thermal_threshold_work_fn
);
INIT_DELAYED_WORK
(
&
zone
dev
->
work
,
pkg_temp_thermal_threshold_work_fn
);
pkg
dev
->
cpu
=
cpu
;
zone
dev
->
cpu
=
cpu
;
pkg
dev
->
tj_max
=
tj_max
;
zone
dev
->
tj_max
=
tj_max
;
pkg
dev
->
tzone
=
thermal_zone_device_register
(
"x86_pkg_temp"
,
zone
dev
->
tzone
=
thermal_zone_device_register
(
"x86_pkg_temp"
,
thres_count
,
thres_count
,
(
thres_count
==
MAX_NUMBER_OF_TRIPS
)
?
0x03
:
0x01
,
(
thres_count
==
MAX_NUMBER_OF_TRIPS
)
?
0x03
:
0x01
,
pkg
dev
,
&
tzone_ops
,
&
pkg_temp_tz_params
,
0
,
0
);
zone
dev
,
&
tzone_ops
,
&
pkg_temp_tz_params
,
0
,
0
);
if
(
IS_ERR
(
pkg
dev
->
tzone
))
{
if
(
IS_ERR
(
zone
dev
->
tzone
))
{
err
=
PTR_ERR
(
pkg
dev
->
tzone
);
err
=
PTR_ERR
(
zone
dev
->
tzone
);
kfree
(
pkg
dev
);
kfree
(
zone
dev
);
return
err
;
return
err
;
}
}
/* Store MSR value for package thermal interrupt, to restore at exit */
/* Store MSR value for package thermal interrupt, to restore at exit */
rdmsr
(
MSR_IA32_PACKAGE_THERM_INTERRUPT
,
pkg
dev
->
msr_pkg_therm_low
,
rdmsr
(
MSR_IA32_PACKAGE_THERM_INTERRUPT
,
zone
dev
->
msr_pkg_therm_low
,
pkg
dev
->
msr_pkg_therm_high
);
zone
dev
->
msr_pkg_therm_high
);
cpumask_set_cpu
(
cpu
,
&
pkg
dev
->
cpumask
);
cpumask_set_cpu
(
cpu
,
&
zone
dev
->
cpumask
);
spin_lock_irq
(
&
pkg_temp_lock
);
spin_lock_irq
(
&
pkg_temp_lock
);
packages
[
pkgid
]
=
pkg
dev
;
zones
[
id
]
=
zone
dev
;
spin_unlock_irq
(
&
pkg_temp_lock
);
spin_unlock_irq
(
&
pkg_temp_lock
);
return
0
;
return
0
;
}
}
static
int
pkg_thermal_cpu_offline
(
unsigned
int
cpu
)
static
int
pkg_thermal_cpu_offline
(
unsigned
int
cpu
)
{
{
struct
pkg_device
*
pkg
dev
=
pkg_temp_thermal_get_dev
(
cpu
);
struct
zone_device
*
zone
dev
=
pkg_temp_thermal_get_dev
(
cpu
);
bool
lastcpu
,
was_target
;
bool
lastcpu
,
was_target
;
int
target
;
int
target
;
if
(
!
pkg
dev
)
if
(
!
zone
dev
)
return
0
;
return
0
;
target
=
cpumask_any_but
(
&
pkg
dev
->
cpumask
,
cpu
);
target
=
cpumask_any_but
(
&
zone
dev
->
cpumask
,
cpu
);
cpumask_clear_cpu
(
cpu
,
&
pkg
dev
->
cpumask
);
cpumask_clear_cpu
(
cpu
,
&
zone
dev
->
cpumask
);
lastcpu
=
target
>=
nr_cpu_ids
;
lastcpu
=
target
>=
nr_cpu_ids
;
/*
/*
* Remove the sysfs files, if this is the last cpu in the package
* Remove the sysfs files, if this is the last cpu in the package
* before doing further cleanups.
* before doing further cleanups.
*/
*/
if
(
lastcpu
)
{
if
(
lastcpu
)
{
struct
thermal_zone_device
*
tzone
=
pkg
dev
->
tzone
;
struct
thermal_zone_device
*
tzone
=
zone
dev
->
tzone
;
/*
/*
* We must protect against a work function calling
* We must protect against a work function calling
...
@@ -425,7 +427,7 @@ static int pkg_thermal_cpu_offline(unsigned int cpu)
...
@@ -425,7 +427,7 @@ static int pkg_thermal_cpu_offline(unsigned int cpu)
* won't try to call.
* won't try to call.
*/
*/
mutex_lock
(
&
thermal_zone_mutex
);
mutex_lock
(
&
thermal_zone_mutex
);
pkg
dev
->
tzone
=
NULL
;
zone
dev
->
tzone
=
NULL
;
mutex_unlock
(
&
thermal_zone_mutex
);
mutex_unlock
(
&
thermal_zone_mutex
);
thermal_zone_device_unregister
(
tzone
);
thermal_zone_device_unregister
(
tzone
);
...
@@ -439,8 +441,8 @@ static int pkg_thermal_cpu_offline(unsigned int cpu)
...
@@ -439,8 +441,8 @@ static int pkg_thermal_cpu_offline(unsigned int cpu)
* one. When we drop the lock, then the interrupt notify function
* one. When we drop the lock, then the interrupt notify function
* will see the new target.
* will see the new target.
*/
*/
was_target
=
pkg
dev
->
cpu
==
cpu
;
was_target
=
zone
dev
->
cpu
==
cpu
;
pkg
dev
->
cpu
=
target
;
zone
dev
->
cpu
=
target
;
/*
/*
* If this is the last CPU in the package remove the package
* If this is the last CPU in the package remove the package
...
@@ -449,23 +451,23 @@ static int pkg_thermal_cpu_offline(unsigned int cpu)
...
@@ -449,23 +451,23 @@ static int pkg_thermal_cpu_offline(unsigned int cpu)
* worker will see the package anymore.
* worker will see the package anymore.
*/
*/
if
(
lastcpu
)
{
if
(
lastcpu
)
{
packages
[
topology_logical_packag
e_id
(
cpu
)]
=
NULL
;
zones
[
topology_logical_di
e_id
(
cpu
)]
=
NULL
;
/* After this point nothing touches the MSR anymore. */
/* After this point nothing touches the MSR anymore. */
wrmsr
(
MSR_IA32_PACKAGE_THERM_INTERRUPT
,
wrmsr
(
MSR_IA32_PACKAGE_THERM_INTERRUPT
,
pkgdev
->
msr_pkg_therm_low
,
pkg
dev
->
msr_pkg_therm_high
);
zonedev
->
msr_pkg_therm_low
,
zone
dev
->
msr_pkg_therm_high
);
}
}
/*
/*
* Check whether there is work scheduled and whether the work is
* Check whether there is work scheduled and whether the work is
* targeted at the outgoing CPU.
* targeted at the outgoing CPU.
*/
*/
if
(
pkg
dev
->
work_scheduled
&&
was_target
)
{
if
(
zone
dev
->
work_scheduled
&&
was_target
)
{
/*
/*
* To cancel the work we need to drop the lock, otherwise
* To cancel the work we need to drop the lock, otherwise
* we might deadlock if the work needs to be flushed.
* we might deadlock if the work needs to be flushed.
*/
*/
spin_unlock_irq
(
&
pkg_temp_lock
);
spin_unlock_irq
(
&
pkg_temp_lock
);
cancel_delayed_work_sync
(
&
pkg
dev
->
work
);
cancel_delayed_work_sync
(
&
zone
dev
->
work
);
spin_lock_irq
(
&
pkg_temp_lock
);
spin_lock_irq
(
&
pkg_temp_lock
);
/*
/*
* If this is not the last cpu in the package and the work
* If this is not the last cpu in the package and the work
...
@@ -473,21 +475,21 @@ static int pkg_thermal_cpu_offline(unsigned int cpu)
...
@@ -473,21 +475,21 @@ static int pkg_thermal_cpu_offline(unsigned int cpu)
* need to reschedule the work, otherwise the interrupt
* need to reschedule the work, otherwise the interrupt
* stays disabled forever.
* stays disabled forever.
*/
*/
if
(
!
lastcpu
&&
pkg
dev
->
work_scheduled
)
if
(
!
lastcpu
&&
zone
dev
->
work_scheduled
)
pkg_thermal_schedule_work
(
target
,
&
pkg
dev
->
work
);
pkg_thermal_schedule_work
(
target
,
&
zone
dev
->
work
);
}
}
spin_unlock_irq
(
&
pkg_temp_lock
);
spin_unlock_irq
(
&
pkg_temp_lock
);
/* Final cleanup if this is the last cpu */
/* Final cleanup if this is the last cpu */
if
(
lastcpu
)
if
(
lastcpu
)
kfree
(
pkg
dev
);
kfree
(
zone
dev
);
return
0
;
return
0
;
}
}
static
int
pkg_thermal_cpu_online
(
unsigned
int
cpu
)
static
int
pkg_thermal_cpu_online
(
unsigned
int
cpu
)
{
{
struct
pkg_device
*
pkg
dev
=
pkg_temp_thermal_get_dev
(
cpu
);
struct
zone_device
*
zone
dev
=
pkg_temp_thermal_get_dev
(
cpu
);
struct
cpuinfo_x86
*
c
=
&
cpu_data
(
cpu
);
struct
cpuinfo_x86
*
c
=
&
cpu_data
(
cpu
);
/* Paranoia check */
/* Paranoia check */
...
@@ -495,8 +497,8 @@ static int pkg_thermal_cpu_online(unsigned int cpu)
...
@@ -495,8 +497,8 @@ static int pkg_thermal_cpu_online(unsigned int cpu)
return
-
ENODEV
;
return
-
ENODEV
;
/* If the package exists, nothing to do */
/* If the package exists, nothing to do */
if
(
pkg
dev
)
{
if
(
zone
dev
)
{
cpumask_set_cpu
(
cpu
,
&
pkg
dev
->
cpumask
);
cpumask_set_cpu
(
cpu
,
&
zone
dev
->
cpumask
);
return
0
;
return
0
;
}
}
return
pkg_temp_thermal_device_add
(
cpu
);
return
pkg_temp_thermal_device_add
(
cpu
);
...
@@ -515,10 +517,10 @@ static int __init pkg_temp_thermal_init(void)
...
@@ -515,10 +517,10 @@ static int __init pkg_temp_thermal_init(void)
if
(
!
x86_match_cpu
(
pkg_temp_thermal_ids
))
if
(
!
x86_match_cpu
(
pkg_temp_thermal_ids
))
return
-
ENODEV
;
return
-
ENODEV
;
max_
packages
=
topology_max_packages
();
max_
id
=
topology_max_packages
()
*
topology_max_die_per_package
();
packages
=
kcalloc
(
max_packages
,
sizeof
(
struct
pkg
_device
*
),
zones
=
kcalloc
(
max_id
,
sizeof
(
struct
zone
_device
*
),
GFP_KERNEL
);
GFP_KERNEL
);
if
(
!
packag
es
)
if
(
!
zon
es
)
return
-
ENOMEM
;
return
-
ENOMEM
;
ret
=
cpuhp_setup_state
(
CPUHP_AP_ONLINE_DYN
,
"thermal/x86_pkg:online"
,
ret
=
cpuhp_setup_state
(
CPUHP_AP_ONLINE_DYN
,
"thermal/x86_pkg:online"
,
...
@@ -537,7 +539,7 @@ static int __init pkg_temp_thermal_init(void)
...
@@ -537,7 +539,7 @@ static int __init pkg_temp_thermal_init(void)
return
0
;
return
0
;
err:
err:
kfree
(
packag
es
);
kfree
(
zon
es
);
return
ret
;
return
ret
;
}
}
module_init
(
pkg_temp_thermal_init
)
module_init
(
pkg_temp_thermal_init
)
...
@@ -549,7 +551,7 @@ static void __exit pkg_temp_thermal_exit(void)
...
@@ -549,7 +551,7 @@ static void __exit pkg_temp_thermal_exit(void)
cpuhp_remove_state
(
pkg_thermal_hp_state
);
cpuhp_remove_state
(
pkg_thermal_hp_state
);
debugfs_remove_recursive
(
debugfs
);
debugfs_remove_recursive
(
debugfs
);
kfree
(
packag
es
);
kfree
(
zon
es
);
}
}
module_exit
(
pkg_temp_thermal_exit
)
module_exit
(
pkg_temp_thermal_exit
)
...
...
include/linux/topology.h
浏览文件 @
3384c786
...
@@ -184,6 +184,9 @@ static inline int cpu_to_mem(int cpu)
...
@@ -184,6 +184,9 @@ static inline int cpu_to_mem(int cpu)
#ifndef topology_physical_package_id
#ifndef topology_physical_package_id
#define topology_physical_package_id(cpu) ((void)(cpu), -1)
#define topology_physical_package_id(cpu) ((void)(cpu), -1)
#endif
#endif
#ifndef topology_die_id
#define topology_die_id(cpu) ((void)(cpu), -1)
#endif
#ifndef topology_core_id
#ifndef topology_core_id
#define topology_core_id(cpu) ((void)(cpu), 0)
#define topology_core_id(cpu) ((void)(cpu), 0)
#endif
#endif
...
@@ -193,6 +196,9 @@ static inline int cpu_to_mem(int cpu)
...
@@ -193,6 +196,9 @@ static inline int cpu_to_mem(int cpu)
#ifndef topology_core_cpumask
#ifndef topology_core_cpumask
#define topology_core_cpumask(cpu) cpumask_of(cpu)
#define topology_core_cpumask(cpu) cpumask_of(cpu)
#endif
#endif
#ifndef topology_die_cpumask
#define topology_die_cpumask(cpu) cpumask_of(cpu)
#endif
#ifdef CONFIG_SCHED_SMT
#ifdef CONFIG_SCHED_SMT
static
inline
const
struct
cpumask
*
cpu_smt_mask
(
int
cpu
)
static
inline
const
struct
cpumask
*
cpu_smt_mask
(
int
cpu
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录