Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
79ba0db6
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
79ba0db6
编写于
1月 18, 2012
作者:
L
Len Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge branches 'einj', 'intel_idle', 'misc', 'srat' and 'turbostat-ivb' into release
上级
cb797175
c130bd6f
5c2a9f06
65b7f839
9f10f6a5
553575f1
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
345 addition
and
111 deletion
+345
-111
Documentation/acpi/apei/einj.txt
Documentation/acpi/apei/einj.txt
+44
-11
Documentation/kernel-parameters.txt
Documentation/kernel-parameters.txt
+5
-0
arch/ia64/kernel/acpi.c
arch/ia64/kernel/acpi.c
+6
-4
arch/x86/mm/srat.c
arch/x86/mm/srat.c
+4
-0
drivers/acpi/apei/einj.c
drivers/acpi/apei/einj.c
+188
-36
drivers/acpi/numa.c
drivers/acpi/numa.c
+6
-0
drivers/acpi/processor_core.c
drivers/acpi/processor_core.c
+24
-2
drivers/acpi/processor_driver.c
drivers/acpi/processor_driver.c
+9
-11
drivers/idle/intel_idle.c
drivers/idle/intel_idle.c
+49
-47
include/acpi/acpi_numa.h
include/acpi/acpi_numa.h
+1
-0
include/linux/cpuidle.h
include/linux/cpuidle.h
+7
-0
tools/power/x86/turbostat/turbostat.c
tools/power/x86/turbostat/turbostat.c
+2
-0
未找到文件。
Documentation/acpi/apei/einj.txt
浏览文件 @
79ba0db6
...
@@ -47,20 +47,53 @@ directory apei/einj. The following files are provided.
...
@@ -47,20 +47,53 @@ directory apei/einj. The following files are provided.
- param1
- param1
This file is used to set the first error parameter value. Effect of
This file is used to set the first error parameter value. Effect of
parameter depends on error_type specified. For memory error, this is
parameter depends on error_type specified.
physical memory address. Only available if param_extension module
parameter is specified.
- param2
- param2
This file is used to set the second error parameter value. Effect of
This file is used to set the second error parameter value. Effect of
parameter depends on error_type specified. For memory error, this is
parameter depends on error_type specified.
physical memory address mask. Only available if param_extension
module parameter is specified.
BIOS versions based in the ACPI 4.0 specification have limited options
to control where the errors are injected. Your BIOS may support an
extension (enabled with the param_extension=1 module parameter, or
boot command line einj.param_extension=1). This allows the address
and mask for memory injections to be specified by the param1 and
param2 files in apei/einj.
BIOS versions using the ACPI 5.0 specification have more control over
the target of the injection. For processor related errors (type 0x1,
0x2 and 0x4) the APICID of the target should be provided using the
param1 file in apei/einj. For memory errors (type 0x8, 0x10 and 0x20)
the address is set using param1 with a mask in param2 (0x0 is equivalent
to all ones). For PCI express errors (type 0x40, 0x80 and 0x100) the
segment, bus, device and function are specified using param1:
31 24 23 16 15 11 10 8 7 0
+-------------------------------------------------+
| segment | bus | device | function | reserved |
+-------------------------------------------------+
An ACPI 5.0 BIOS may also allow vendor specific errors to be injected.
In this case a file named vendor will contain identifying information
from the BIOS that hopefully will allow an application wishing to use
the vendor specific extension to tell that they are running on a BIOS
that supports it. All vendor extensions have the 0x80000000 bit set in
error_type. A file vendor_flags controls the interpretation of param1
and param2 (1 = PROCESSOR, 2 = MEMORY, 4 = PCI). See your BIOS vendor
documentation for details (and expect changes to this API if vendors
creativity in using this feature expands beyond our expectations).
Example:
# cd /sys/kernel/debug/apei/einj
# cat available_error_type # See which errors can be injected
0x00000002 Processor Uncorrectable non-fatal
0x00000008 Memory Correctable
0x00000010 Memory Uncorrectable non-fatal
# echo 0x12345000 > param1 # Set memory address for injection
# echo 0xfffffffffffff000 > param2 # Mask - anywhere in this page
# echo 0x8 > error_type # Choose correctable memory error
# echo 1 > error_inject # Inject now
Injecting parameter support is a BIOS version specific extension, that
is, it only works on some BIOS version. If you want to use it, please
make sure your BIOS version has the proper support and specify
"param_extension=y" in module parameter.
For more information about EINJ, please refer to ACPI specification
For more information about EINJ, please refer to ACPI specification
version 4.0, section 17.5.
version 4.0, section 17.5
and ACPI 5.0, section 18.6
.
Documentation/kernel-parameters.txt
浏览文件 @
79ba0db6
...
@@ -1035,6 +1035,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
...
@@ -1035,6 +1035,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
By default, super page will be supported if Intel IOMMU
By default, super page will be supported if Intel IOMMU
has the capability. With this option, super page will
has the capability. With this option, super page will
not be supported.
not be supported.
intel_idle.max_cstate= [KNL,HW,ACPI,X86]
0 disables intel_idle and fall back on acpi_idle.
1 to 6 specify maximum depth of C-state.
intremap= [X86-64, Intel-IOMMU]
intremap= [X86-64, Intel-IOMMU]
on enable Interrupt Remapping (default)
on enable Interrupt Remapping (default)
off disable Interrupt Remapping
off disable Interrupt Remapping
...
...
arch/ia64/kernel/acpi.c
浏览文件 @
79ba0db6
...
@@ -429,22 +429,24 @@ static u32 __devinitdata pxm_flag[PXM_FLAG_LEN];
...
@@ -429,22 +429,24 @@ static u32 __devinitdata pxm_flag[PXM_FLAG_LEN];
static
struct
acpi_table_slit
__initdata
*
slit_table
;
static
struct
acpi_table_slit
__initdata
*
slit_table
;
cpumask_t
early_cpu_possible_map
=
CPU_MASK_NONE
;
cpumask_t
early_cpu_possible_map
=
CPU_MASK_NONE
;
static
int
get_processor_proximity_domain
(
struct
acpi_srat_cpu_affinity
*
pa
)
static
int
__init
get_processor_proximity_domain
(
struct
acpi_srat_cpu_affinity
*
pa
)
{
{
int
pxm
;
int
pxm
;
pxm
=
pa
->
proximity_domain_lo
;
pxm
=
pa
->
proximity_domain_lo
;
if
(
ia64_platform_is
(
"sn2"
))
if
(
ia64_platform_is
(
"sn2"
)
||
acpi_srat_revision
>=
2
)
pxm
+=
pa
->
proximity_domain_hi
[
0
]
<<
8
;
pxm
+=
pa
->
proximity_domain_hi
[
0
]
<<
8
;
return
pxm
;
return
pxm
;
}
}
static
int
get_memory_proximity_domain
(
struct
acpi_srat_mem_affinity
*
ma
)
static
int
__init
get_memory_proximity_domain
(
struct
acpi_srat_mem_affinity
*
ma
)
{
{
int
pxm
;
int
pxm
;
pxm
=
ma
->
proximity_domain
;
pxm
=
ma
->
proximity_domain
;
if
(
!
ia64_platform_is
(
"sn2"
))
if
(
!
ia64_platform_is
(
"sn2"
)
&&
acpi_srat_revision
<=
1
)
pxm
&=
0xff
;
pxm
&=
0xff
;
return
pxm
;
return
pxm
;
...
...
arch/x86/mm/srat.c
浏览文件 @
79ba0db6
...
@@ -104,6 +104,8 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
...
@@ -104,6 +104,8 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
if
((
pa
->
flags
&
ACPI_SRAT_CPU_ENABLED
)
==
0
)
if
((
pa
->
flags
&
ACPI_SRAT_CPU_ENABLED
)
==
0
)
return
;
return
;
pxm
=
pa
->
proximity_domain_lo
;
pxm
=
pa
->
proximity_domain_lo
;
if
(
acpi_srat_revision
>=
2
)
pxm
|=
*
((
unsigned
int
*
)
pa
->
proximity_domain_hi
)
<<
8
;
node
=
setup_node
(
pxm
);
node
=
setup_node
(
pxm
);
if
(
node
<
0
)
{
if
(
node
<
0
)
{
printk
(
KERN_ERR
"SRAT: Too many proximity domains %x
\n
"
,
pxm
);
printk
(
KERN_ERR
"SRAT: Too many proximity domains %x
\n
"
,
pxm
);
...
@@ -155,6 +157,8 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
...
@@ -155,6 +157,8 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
start
=
ma
->
base_address
;
start
=
ma
->
base_address
;
end
=
start
+
ma
->
length
;
end
=
start
+
ma
->
length
;
pxm
=
ma
->
proximity_domain
;
pxm
=
ma
->
proximity_domain
;
if
(
acpi_srat_revision
<=
1
)
pxm
&=
0xff
;
node
=
setup_node
(
pxm
);
node
=
setup_node
(
pxm
);
if
(
node
<
0
)
{
if
(
node
<
0
)
{
printk
(
KERN_ERR
"SRAT: Too many proximity domains.
\n
"
);
printk
(
KERN_ERR
"SRAT: Too many proximity domains.
\n
"
);
...
...
drivers/acpi/apei/einj.c
浏览文件 @
79ba0db6
...
@@ -42,6 +42,42 @@
...
@@ -42,6 +42,42 @@
/* Firmware should respond within 1 milliseconds */
/* Firmware should respond within 1 milliseconds */
#define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC)
#define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC)
/*
* ACPI version 5 provides a SET_ERROR_TYPE_WITH_ADDRESS action.
*/
static
int
acpi5
;
struct
set_error_type_with_address
{
u32
type
;
u32
vendor_extension
;
u32
flags
;
u32
apicid
;
u64
memory_address
;
u64
memory_address_range
;
u32
pcie_sbdf
;
};
enum
{
SETWA_FLAGS_APICID
=
1
,
SETWA_FLAGS_MEM
=
2
,
SETWA_FLAGS_PCIE_SBDF
=
4
,
};
/*
* Vendor extensions for platform specific operations
*/
struct
vendor_error_type_extension
{
u32
length
;
u32
pcie_sbdf
;
u16
vendor_id
;
u16
device_id
;
u8
rev_id
;
u8
reserved
[
3
];
};
static
u32
vendor_flags
;
static
struct
debugfs_blob_wrapper
vendor_blob
;
static
char
vendor_dev
[
64
];
/*
/*
* Some BIOSes allow parameters to the SET_ERROR_TYPE entries in the
* Some BIOSes allow parameters to the SET_ERROR_TYPE entries in the
* EINJ table through an unpublished extension. Use with caution as
* EINJ table through an unpublished extension. Use with caution as
...
@@ -103,7 +139,14 @@ static struct apei_exec_ins_type einj_ins_type[] = {
...
@@ -103,7 +139,14 @@ static struct apei_exec_ins_type einj_ins_type[] = {
*/
*/
static
DEFINE_MUTEX
(
einj_mutex
);
static
DEFINE_MUTEX
(
einj_mutex
);
static
struct
einj_parameter
*
einj_param
;
static
void
*
einj_param
;
#ifndef readq
static
inline
__u64
readq
(
volatile
void
__iomem
*
addr
)
{
return
((
__u64
)
readl
(
addr
+
4
)
<<
32
)
+
readl
(
addr
);
}
#endif
#ifndef writeq
#ifndef writeq
static
inline
void
writeq
(
__u64
val
,
volatile
void
__iomem
*
addr
)
static
inline
void
writeq
(
__u64
val
,
volatile
void
__iomem
*
addr
)
...
@@ -158,10 +201,31 @@ static int einj_timedout(u64 *t)
...
@@ -158,10 +201,31 @@ static int einj_timedout(u64 *t)
return
0
;
return
0
;
}
}
static
u64
einj_get_parameter_address
(
void
)
static
void
check_vendor_extension
(
u64
paddr
,
struct
set_error_type_with_address
*
v5param
)
{
int
offset
=
readl
(
&
v5param
->
vendor_extension
);
struct
vendor_error_type_extension
*
v
;
u32
sbdf
;
if
(
!
offset
)
return
;
v
=
ioremap
(
paddr
+
offset
,
sizeof
(
*
v
));
if
(
!
v
)
return
;
sbdf
=
readl
(
&
v
->
pcie_sbdf
);
sprintf
(
vendor_dev
,
"%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x
\n
"
,
sbdf
>>
24
,
(
sbdf
>>
16
)
&
0xff
,
(
sbdf
>>
11
)
&
0x1f
,
(
sbdf
>>
8
)
&
0x7
,
readw
(
&
v
->
vendor_id
),
readw
(
&
v
->
device_id
),
readb
(
&
v
->
rev_id
));
iounmap
(
v
);
}
static
void
*
einj_get_parameter_address
(
void
)
{
{
int
i
;
int
i
;
u64
paddr
=
0
;
u64
paddr
v4
=
0
,
paddrv5
=
0
;
struct
acpi_whea_header
*
entry
;
struct
acpi_whea_header
*
entry
;
entry
=
EINJ_TAB_ENTRY
(
einj_tab
);
entry
=
EINJ_TAB_ENTRY
(
einj_tab
);
...
@@ -170,12 +234,40 @@ static u64 einj_get_parameter_address(void)
...
@@ -170,12 +234,40 @@ static u64 einj_get_parameter_address(void)
entry
->
instruction
==
ACPI_EINJ_WRITE_REGISTER
&&
entry
->
instruction
==
ACPI_EINJ_WRITE_REGISTER
&&
entry
->
register_region
.
space_id
==
entry
->
register_region
.
space_id
==
ACPI_ADR_SPACE_SYSTEM_MEMORY
)
ACPI_ADR_SPACE_SYSTEM_MEMORY
)
memcpy
(
&
paddr
,
&
entry
->
register_region
.
address
,
memcpy
(
&
paddrv4
,
&
entry
->
register_region
.
address
,
sizeof
(
paddr
));
sizeof
(
paddrv4
));
if
(
entry
->
action
==
ACPI_EINJ_SET_ERROR_TYPE_WITH_ADDRESS
&&
entry
->
instruction
==
ACPI_EINJ_WRITE_REGISTER
&&
entry
->
register_region
.
space_id
==
ACPI_ADR_SPACE_SYSTEM_MEMORY
)
memcpy
(
&
paddrv5
,
&
entry
->
register_region
.
address
,
sizeof
(
paddrv5
));
entry
++
;
entry
++
;
}
}
if
(
paddrv5
)
{
struct
set_error_type_with_address
*
v5param
;
v5param
=
ioremap
(
paddrv5
,
sizeof
(
*
v5param
));
if
(
v5param
)
{
acpi5
=
1
;
check_vendor_extension
(
paddrv5
,
v5param
);
return
v5param
;
}
}
if
(
paddrv4
)
{
struct
einj_parameter
*
v4param
;
v4param
=
ioremap
(
paddrv4
,
sizeof
(
*
v4param
));
if
(
!
v4param
)
return
0
;
if
(
readq
(
&
v4param
->
reserved1
)
||
readq
(
&
v4param
->
reserved2
))
{
iounmap
(
v4param
);
return
0
;
}
return
v4param
;
}
return
paddr
;
return
0
;
}
}
/* do sanity check to trigger table */
/* do sanity check to trigger table */
...
@@ -340,12 +432,56 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
...
@@ -340,12 +432,56 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
if
(
rc
)
if
(
rc
)
return
rc
;
return
rc
;
apei_exec_ctx_set_input
(
&
ctx
,
type
);
apei_exec_ctx_set_input
(
&
ctx
,
type
);
rc
=
apei_exec_run
(
&
ctx
,
ACPI_EINJ_SET_ERROR_TYPE
);
if
(
acpi5
)
{
if
(
rc
)
struct
set_error_type_with_address
*
v5param
=
einj_param
;
return
rc
;
if
(
einj_param
)
{
writel
(
type
,
&
v5param
->
type
);
writeq
(
param1
,
&
einj_param
->
param1
);
if
(
type
&
0x80000000
)
{
writeq
(
param2
,
&
einj_param
->
param2
);
switch
(
vendor_flags
)
{
case
SETWA_FLAGS_APICID
:
writel
(
param1
,
&
v5param
->
apicid
);
break
;
case
SETWA_FLAGS_MEM
:
writeq
(
param1
,
&
v5param
->
memory_address
);
writeq
(
param2
,
&
v5param
->
memory_address_range
);
break
;
case
SETWA_FLAGS_PCIE_SBDF
:
writel
(
param1
,
&
v5param
->
pcie_sbdf
);
break
;
}
writel
(
vendor_flags
,
&
v5param
->
flags
);
}
else
{
switch
(
type
)
{
case
ACPI_EINJ_PROCESSOR_CORRECTABLE
:
case
ACPI_EINJ_PROCESSOR_UNCORRECTABLE
:
case
ACPI_EINJ_PROCESSOR_FATAL
:
writel
(
param1
,
&
v5param
->
apicid
);
writel
(
SETWA_FLAGS_APICID
,
&
v5param
->
flags
);
break
;
case
ACPI_EINJ_MEMORY_CORRECTABLE
:
case
ACPI_EINJ_MEMORY_UNCORRECTABLE
:
case
ACPI_EINJ_MEMORY_FATAL
:
writeq
(
param1
,
&
v5param
->
memory_address
);
writeq
(
param2
,
&
v5param
->
memory_address_range
);
writel
(
SETWA_FLAGS_MEM
,
&
v5param
->
flags
);
break
;
case
ACPI_EINJ_PCIX_CORRECTABLE
:
case
ACPI_EINJ_PCIX_UNCORRECTABLE
:
case
ACPI_EINJ_PCIX_FATAL
:
writel
(
param1
,
&
v5param
->
pcie_sbdf
);
writel
(
SETWA_FLAGS_PCIE_SBDF
,
&
v5param
->
flags
);
break
;
}
}
}
else
{
rc
=
apei_exec_run
(
&
ctx
,
ACPI_EINJ_SET_ERROR_TYPE
);
if
(
rc
)
return
rc
;
if
(
einj_param
)
{
struct
einj_parameter
*
v4param
=
einj_param
;
writeq
(
param1
,
&
v4param
->
param1
);
writeq
(
param2
,
&
v4param
->
param2
);
}
}
}
rc
=
apei_exec_run
(
&
ctx
,
ACPI_EINJ_EXECUTE_OPERATION
);
rc
=
apei_exec_run
(
&
ctx
,
ACPI_EINJ_EXECUTE_OPERATION
);
if
(
rc
)
if
(
rc
)
...
@@ -455,15 +591,25 @@ static int error_type_set(void *data, u64 val)
...
@@ -455,15 +591,25 @@ static int error_type_set(void *data, u64 val)
{
{
int
rc
;
int
rc
;
u32
available_error_type
=
0
;
u32
available_error_type
=
0
;
u32
tval
,
vendor
;
/*
* Vendor defined types have 0x80000000 bit set, and
* are not enumerated by ACPI_EINJ_GET_ERROR_TYPE
*/
vendor
=
val
&
0x80000000
;
tval
=
val
&
0x7fffffff
;
/* Only one error type can be specified */
/* Only one error type can be specified */
if
(
val
&
(
val
-
1
))
if
(
tval
&
(
tval
-
1
))
return
-
EINVAL
;
rc
=
einj_get_available_error_type
(
&
available_error_type
);
if
(
rc
)
return
rc
;
if
(
!
(
val
&
available_error_type
))
return
-
EINVAL
;
return
-
EINVAL
;
if
(
!
vendor
)
{
rc
=
einj_get_available_error_type
(
&
available_error_type
);
if
(
rc
)
return
rc
;
if
(
!
(
val
&
available_error_type
))
return
-
EINVAL
;
}
error_type
=
val
;
error_type
=
val
;
return
0
;
return
0
;
...
@@ -502,7 +648,6 @@ static int einj_check_table(struct acpi_table_einj *einj_tab)
...
@@ -502,7 +648,6 @@ static int einj_check_table(struct acpi_table_einj *einj_tab)
static
int
__init
einj_init
(
void
)
static
int
__init
einj_init
(
void
)
{
{
int
rc
;
int
rc
;
u64
param_paddr
;
acpi_status
status
;
acpi_status
status
;
struct
dentry
*
fentry
;
struct
dentry
*
fentry
;
struct
apei_exec_context
ctx
;
struct
apei_exec_context
ctx
;
...
@@ -555,23 +700,30 @@ static int __init einj_init(void)
...
@@ -555,23 +700,30 @@ static int __init einj_init(void)
rc
=
apei_exec_pre_map_gars
(
&
ctx
);
rc
=
apei_exec_pre_map_gars
(
&
ctx
);
if
(
rc
)
if
(
rc
)
goto
err_release
;
goto
err_release
;
if
(
param_extension
)
{
param_paddr
=
einj_get_parameter_address
();
einj_param
=
einj_get_parameter_address
();
if
(
param_paddr
)
{
if
((
param_extension
||
acpi5
)
&&
einj_param
)
{
einj_param
=
ioremap
(
param_paddr
,
sizeof
(
*
einj_param
));
fentry
=
debugfs_create_x64
(
"param1"
,
S_IRUSR
|
S_IWUSR
,
rc
=
-
ENOMEM
;
einj_debug_dir
,
&
error_param1
);
if
(
!
einj_param
)
if
(
!
fentry
)
goto
err_unmap
;
goto
err_unmap
;
fentry
=
debugfs_create_x64
(
"param1"
,
S_IRUSR
|
S_IWUSR
,
fentry
=
debugfs_create_x64
(
"param2"
,
S_IRUSR
|
S_IWUSR
,
einj_debug_dir
,
&
error_param1
);
einj_debug_dir
,
&
error_param2
);
if
(
!
fentry
)
if
(
!
fentry
)
goto
err_unmap
;
goto
err_unmap
;
fentry
=
debugfs_create_x64
(
"param2"
,
S_IRUSR
|
S_IWUSR
,
}
einj_debug_dir
,
&
error_param2
);
if
(
!
fentry
)
if
(
vendor_dev
[
0
])
{
goto
err_unmap
;
vendor_blob
.
data
=
vendor_dev
;
}
else
vendor_blob
.
size
=
strlen
(
vendor_dev
);
pr_warn
(
EINJ_PFX
"Parameter extension is not supported.
\n
"
);
fentry
=
debugfs_create_blob
(
"vendor"
,
S_IRUSR
,
einj_debug_dir
,
&
vendor_blob
);
if
(
!
fentry
)
goto
err_unmap
;
fentry
=
debugfs_create_x32
(
"vendor_flags"
,
S_IRUSR
|
S_IWUSR
,
einj_debug_dir
,
&
vendor_flags
);
if
(
!
fentry
)
goto
err_unmap
;
}
}
pr_info
(
EINJ_PFX
"Error INJection is initialized.
\n
"
);
pr_info
(
EINJ_PFX
"Error INJection is initialized.
\n
"
);
...
...
drivers/acpi/numa.c
浏览文件 @
79ba0db6
...
@@ -45,6 +45,8 @@ static int pxm_to_node_map[MAX_PXM_DOMAINS]
...
@@ -45,6 +45,8 @@ static int pxm_to_node_map[MAX_PXM_DOMAINS]
static
int
node_to_pxm_map
[
MAX_NUMNODES
]
static
int
node_to_pxm_map
[
MAX_NUMNODES
]
=
{
[
0
...
MAX_NUMNODES
-
1
]
=
PXM_INVAL
};
=
{
[
0
...
MAX_NUMNODES
-
1
]
=
PXM_INVAL
};
unsigned
char
acpi_srat_revision
__initdata
;
int
pxm_to_node
(
int
pxm
)
int
pxm_to_node
(
int
pxm
)
{
{
if
(
pxm
<
0
)
if
(
pxm
<
0
)
...
@@ -255,9 +257,13 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header,
...
@@ -255,9 +257,13 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header,
static
int
__init
acpi_parse_srat
(
struct
acpi_table_header
*
table
)
static
int
__init
acpi_parse_srat
(
struct
acpi_table_header
*
table
)
{
{
struct
acpi_table_srat
*
srat
;
if
(
!
table
)
if
(
!
table
)
return
-
EINVAL
;
return
-
EINVAL
;
srat
=
(
struct
acpi_table_srat
*
)
table
;
acpi_srat_revision
=
srat
->
header
.
revision
;
/* Real work done in acpi_table_parse_srat below. */
/* Real work done in acpi_table_parse_srat below. */
return
0
;
return
0
;
...
...
drivers/acpi/processor_core.c
浏览文件 @
79ba0db6
...
@@ -173,8 +173,30 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
...
@@ -173,8 +173,30 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
apic_id
=
map_mat_entry
(
handle
,
type
,
acpi_id
);
apic_id
=
map_mat_entry
(
handle
,
type
,
acpi_id
);
if
(
apic_id
==
-
1
)
if
(
apic_id
==
-
1
)
apic_id
=
map_madt_entry
(
type
,
acpi_id
);
apic_id
=
map_madt_entry
(
type
,
acpi_id
);
if
(
apic_id
==
-
1
)
if
(
apic_id
==
-
1
)
{
return
apic_id
;
/*
* On UP processor, there is no _MAT or MADT table.
* So above apic_id is always set to -1.
*
* BIOS may define multiple CPU handles even for UP processor.
* For example,
*
* Scope (_PR)
* {
* Processor (CPU0, 0x00, 0x00000410, 0x06) {}
* Processor (CPU1, 0x01, 0x00000410, 0x06) {}
* Processor (CPU2, 0x02, 0x00000410, 0x06) {}
* Processor (CPU3, 0x03, 0x00000410, 0x06) {}
* }
*
* Ignores apic_id and always return 0 for CPU0's handle.
* Return -1 for other CPU's handle.
*/
if
(
acpi_id
==
0
)
return
acpi_id
;
else
return
apic_id
;
}
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
for_each_possible_cpu
(
i
)
{
for_each_possible_cpu
(
i
)
{
...
...
drivers/acpi/processor_driver.c
浏览文件 @
79ba0db6
...
@@ -82,7 +82,7 @@ MODULE_LICENSE("GPL");
...
@@ -82,7 +82,7 @@ MODULE_LICENSE("GPL");
static
int
acpi_processor_add
(
struct
acpi_device
*
device
);
static
int
acpi_processor_add
(
struct
acpi_device
*
device
);
static
int
acpi_processor_remove
(
struct
acpi_device
*
device
,
int
type
);
static
int
acpi_processor_remove
(
struct
acpi_device
*
device
,
int
type
);
static
void
acpi_processor_notify
(
struct
acpi_device
*
device
,
u32
event
);
static
void
acpi_processor_notify
(
struct
acpi_device
*
device
,
u32
event
);
static
acpi_status
acpi_processor_hotadd_init
(
acpi_handle
handle
,
int
*
p_cpu
);
static
acpi_status
acpi_processor_hotadd_init
(
struct
acpi_processor
*
pr
);
static
int
acpi_processor_handle_eject
(
struct
acpi_processor
*
pr
);
static
int
acpi_processor_handle_eject
(
struct
acpi_processor
*
pr
);
...
@@ -324,10 +324,8 @@ static int acpi_processor_get_info(struct acpi_device *device)
...
@@ -324,10 +324,8 @@ static int acpi_processor_get_info(struct acpi_device *device)
* they are physically not present.
* they are physically not present.
*/
*/
if
(
pr
->
id
==
-
1
)
{
if
(
pr
->
id
==
-
1
)
{
if
(
ACPI_FAILURE
if
(
ACPI_FAILURE
(
acpi_processor_hotadd_init
(
pr
)))
(
acpi_processor_hotadd_init
(
pr
->
handle
,
&
pr
->
id
)))
{
return
-
ENODEV
;
return
-
ENODEV
;
}
}
}
/*
/*
* On some boxes several processors use the same processor bus id.
* On some boxes several processors use the same processor bus id.
...
@@ -539,6 +537,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
...
@@ -539,6 +537,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
thermal_cooling_device_unregister
(
pr
->
cdev
);
thermal_cooling_device_unregister
(
pr
->
cdev
);
err_power_exit:
err_power_exit:
acpi_processor_power_exit
(
pr
,
device
);
acpi_processor_power_exit
(
pr
,
device
);
sysfs_remove_link
(
&
device
->
dev
.
kobj
,
"sysdev"
);
err_free_cpumask:
err_free_cpumask:
free_cpumask_var
(
pr
->
throttling
.
shared_cpu_map
);
free_cpumask_var
(
pr
->
throttling
.
shared_cpu_map
);
...
@@ -720,18 +719,19 @@ processor_walk_namespace_cb(acpi_handle handle,
...
@@ -720,18 +719,19 @@ processor_walk_namespace_cb(acpi_handle handle,
return
(
AE_OK
);
return
(
AE_OK
);
}
}
static
acpi_status
acpi_processor_hotadd_init
(
acpi_handle
handle
,
int
*
p_cpu
)
static
acpi_status
acpi_processor_hotadd_init
(
struct
acpi_processor
*
pr
)
{
{
acpi_handle
handle
=
pr
->
handle
;
if
(
!
is_processor_present
(
handle
))
{
if
(
!
is_processor_present
(
handle
))
{
return
AE_ERROR
;
return
AE_ERROR
;
}
}
if
(
acpi_map_lsapic
(
handle
,
p_cpu
))
if
(
acpi_map_lsapic
(
handle
,
&
pr
->
id
))
return
AE_ERROR
;
return
AE_ERROR
;
if
(
arch_register_cpu
(
*
p_cpu
))
{
if
(
arch_register_cpu
(
pr
->
id
))
{
acpi_unmap_lsapic
(
*
p_cpu
);
acpi_unmap_lsapic
(
pr
->
id
);
return
AE_ERROR
;
return
AE_ERROR
;
}
}
...
@@ -748,7 +748,7 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr)
...
@@ -748,7 +748,7 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr)
return
(
0
);
return
(
0
);
}
}
#else
#else
static
acpi_status
acpi_processor_hotadd_init
(
acpi_handle
handle
,
int
*
p_cpu
)
static
acpi_status
acpi_processor_hotadd_init
(
struct
acpi_processor
*
pr
)
{
{
return
AE_ERROR
;
return
AE_ERROR
;
}
}
...
@@ -827,8 +827,6 @@ static void __exit acpi_processor_exit(void)
...
@@ -827,8 +827,6 @@ static void __exit acpi_processor_exit(void)
acpi_bus_unregister_driver
(
&
acpi_processor_driver
);
acpi_bus_unregister_driver
(
&
acpi_processor_driver
);
cpuidle_unregister_driver
(
&
acpi_idle_driver
);
return
;
return
;
}
}
...
...
drivers/idle/intel_idle.c
浏览文件 @
79ba0db6
...
@@ -197,7 +197,7 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
...
@@ -197,7 +197,7 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
};
};
static
int
get_driver_data
(
int
cstate
)
static
long
get_driver_data
(
int
cstate
)
{
{
int
driver_data
;
int
driver_data
;
switch
(
cstate
)
{
switch
(
cstate
)
{
...
@@ -232,6 +232,7 @@ static int get_driver_data(int cstate)
...
@@ -232,6 +232,7 @@ static int get_driver_data(int cstate)
* @drv: cpuidle driver
* @drv: cpuidle driver
* @index: index of cpuidle state
* @index: index of cpuidle state
*
*
* Must be called under local_irq_disable().
*/
*/
static
int
intel_idle
(
struct
cpuidle_device
*
dev
,
static
int
intel_idle
(
struct
cpuidle_device
*
dev
,
struct
cpuidle_driver
*
drv
,
int
index
)
struct
cpuidle_driver
*
drv
,
int
index
)
...
@@ -247,8 +248,6 @@ static int intel_idle(struct cpuidle_device *dev,
...
@@ -247,8 +248,6 @@ static int intel_idle(struct cpuidle_device *dev,
cstate
=
(((
eax
)
>>
MWAIT_SUBSTATE_SIZE
)
&
MWAIT_CSTATE_MASK
)
+
1
;
cstate
=
(((
eax
)
>>
MWAIT_SUBSTATE_SIZE
)
&
MWAIT_CSTATE_MASK
)
+
1
;
local_irq_disable
();
/*
/*
* leave_mm() to avoid costly and often unnecessary wakeups
* leave_mm() to avoid costly and often unnecessary wakeups
* for flushing the user TLB's associated with the active mm.
* for flushing the user TLB's associated with the active mm.
...
@@ -348,7 +347,8 @@ static int intel_idle_probe(void)
...
@@ -348,7 +347,8 @@ static int intel_idle_probe(void)
cpuid
(
CPUID_MWAIT_LEAF
,
&
eax
,
&
ebx
,
&
ecx
,
&
mwait_substates
);
cpuid
(
CPUID_MWAIT_LEAF
,
&
eax
,
&
ebx
,
&
ecx
,
&
mwait_substates
);
if
(
!
(
ecx
&
CPUID5_ECX_EXTENSIONS_SUPPORTED
)
||
if
(
!
(
ecx
&
CPUID5_ECX_EXTENSIONS_SUPPORTED
)
||
!
(
ecx
&
CPUID5_ECX_INTERRUPT_BREAK
))
!
(
ecx
&
CPUID5_ECX_INTERRUPT_BREAK
)
||
!
mwait_substates
)
return
-
ENODEV
;
return
-
ENODEV
;
pr_debug
(
PREFIX
"MWAIT substates: 0x%x
\n
"
,
mwait_substates
);
pr_debug
(
PREFIX
"MWAIT substates: 0x%x
\n
"
,
mwait_substates
);
...
@@ -394,7 +394,7 @@ static int intel_idle_probe(void)
...
@@ -394,7 +394,7 @@ static int intel_idle_probe(void)
if
(
boot_cpu_has
(
X86_FEATURE_ARAT
))
/* Always Reliable APIC Timer */
if
(
boot_cpu_has
(
X86_FEATURE_ARAT
))
/* Always Reliable APIC Timer */
lapic_timer_reliable_states
=
LAPIC_TIMER_ALWAYS_RELIABLE
;
lapic_timer_reliable_states
=
LAPIC_TIMER_ALWAYS_RELIABLE
;
else
{
else
{
smp_call_function
(
__setup_broadcast_timer
,
(
void
*
)
true
,
1
);
on_each_cpu
(
__setup_broadcast_timer
,
(
void
*
)
true
,
1
);
register_cpu_notifier
(
&
setup_broadcast_notifier
);
register_cpu_notifier
(
&
setup_broadcast_notifier
);
}
}
...
@@ -471,71 +471,67 @@ static int intel_idle_cpuidle_driver_init(void)
...
@@ -471,71 +471,67 @@ static int intel_idle_cpuidle_driver_init(void)
}
}
if
(
auto_demotion_disable_flags
)
if
(
auto_demotion_disable_flags
)
smp_call_function
(
auto_demotion_disable
,
NULL
,
1
);
on_each_cpu
(
auto_demotion_disable
,
NULL
,
1
);
return
0
;
return
0
;
}
}
/*
/*
* intel_idle_cpu
idle_devices
_init()
* intel_idle_cpu_init()
* allocate, initialize, register cpuidle_devices
* allocate, initialize, register cpuidle_devices
* @cpu: cpu/core to initialize
*/
*/
static
int
intel_idle_cpuidle_devices_init
(
void
)
int
intel_idle_cpu_init
(
int
cpu
)
{
{
int
i
,
cstate
;
int
cstate
;
struct
cpuidle_device
*
dev
;
struct
cpuidle_device
*
dev
;
intel_idle_cpuidle_devices
=
alloc_percpu
(
struct
cpuidle_device
);
dev
=
per_cpu_ptr
(
intel_idle_cpuidle_devices
,
cpu
);
if
(
intel_idle_cpuidle_devices
==
NULL
)
return
-
ENOMEM
;
for_each_online_cpu
(
i
)
{
dev
=
per_cpu_ptr
(
intel_idle_cpuidle_devices
,
i
);
dev
->
state_count
=
1
;
dev
->
state_count
=
1
;
for
(
cstate
=
1
;
cstate
<
MWAIT_MAX_NUM_CSTATES
;
++
cstate
)
{
for
(
cstate
=
1
;
cstate
<
MWAIT_MAX_NUM_CSTATES
;
++
cstate
)
{
int
num_substates
;
int
num_substates
;
if
(
cstate
>
max_cstate
)
{
if
(
cstate
>
max_cstate
)
{
printk
(
PREFIX
"max_cstate %d reached
\n
"
,
printk
(
PREFIX
"max_cstate %d reached
\n
"
,
max_cstate
);
max_cstate
);
break
;
break
;
}
}
/* does the state exist in CPUID.MWAIT? */
/* does the state exist in CPUID.MWAIT? */
num_substates
=
(
mwait_substates
>>
((
cstate
)
*
4
))
num_substates
=
(
mwait_substates
>>
((
cstate
)
*
4
))
&
MWAIT_SUBSTATE_MASK
;
&
MWAIT_SUBSTATE_MASK
;
if
(
num_substates
==
0
)
if
(
num_substates
==
0
)
continue
;
continue
;
/* is the state not enabled? */
/* is the state not enabled? */
if
(
cpuidle_state_table
[
cstate
].
enter
==
NULL
)
{
if
(
cpuidle_state_table
[
cstate
].
enter
==
NULL
)
continue
;
continue
;
}
dev
->
states_usage
[
dev
->
state_count
].
driver_data
=
dev
->
states_usage
[
dev
->
state_count
].
driver_data
=
(
void
*
)
get_driver_data
(
cstate
);
(
void
*
)
get_driver_data
(
cstate
);
dev
->
state_count
+=
1
;
dev
->
state_count
+=
1
;
}
}
dev
->
cpu
=
cpu
;
dev
->
cpu
=
i
;
if
(
cpuidle_register_device
(
dev
))
{
if
(
cpuidle_register_device
(
dev
))
{
pr_debug
(
PREFIX
"cpuidle_register_device %d failed!
\n
"
,
cpu
);
pr_debug
(
PREFIX
"cpuidle_register_device %d failed!
\n
"
,
intel_idle_cpuidle_devices_uninit
();
i
);
return
-
EIO
;
intel_idle_cpuidle_devices_uninit
();
return
-
EIO
;
}
}
}
if
(
auto_demotion_disable_flags
)
smp_call_function_single
(
cpu
,
auto_demotion_disable
,
NULL
,
1
);
return
0
;
return
0
;
}
}
static
int
__init
intel_idle_init
(
void
)
static
int
__init
intel_idle_init
(
void
)
{
{
int
retval
;
int
retval
,
i
;
/* Do not load intel_idle at all for now if idle= is passed */
/* Do not load intel_idle at all for now if idle= is passed */
if
(
boot_option_idle_override
!=
IDLE_NO_OVERRIDE
)
if
(
boot_option_idle_override
!=
IDLE_NO_OVERRIDE
)
...
@@ -553,10 +549,16 @@ static int __init intel_idle_init(void)
...
@@ -553,10 +549,16 @@ static int __init intel_idle_init(void)
return
retval
;
return
retval
;
}
}
retval
=
intel_idle_cpuidle_devices_init
();
intel_idle_cpuidle_devices
=
alloc_percpu
(
struct
cpuidle_device
);
if
(
retval
)
{
if
(
intel_idle_cpuidle_devices
==
NULL
)
cpuidle_unregister_driver
(
&
intel_idle_driver
);
return
-
ENOMEM
;
return
retval
;
for_each_online_cpu
(
i
)
{
retval
=
intel_idle_cpu_init
(
i
);
if
(
retval
)
{
cpuidle_unregister_driver
(
&
intel_idle_driver
);
return
retval
;
}
}
}
return
0
;
return
0
;
...
@@ -568,7 +570,7 @@ static void __exit intel_idle_exit(void)
...
@@ -568,7 +570,7 @@ static void __exit intel_idle_exit(void)
cpuidle_unregister_driver
(
&
intel_idle_driver
);
cpuidle_unregister_driver
(
&
intel_idle_driver
);
if
(
lapic_timer_reliable_states
!=
LAPIC_TIMER_ALWAYS_RELIABLE
)
{
if
(
lapic_timer_reliable_states
!=
LAPIC_TIMER_ALWAYS_RELIABLE
)
{
smp_call_function
(
__setup_broadcast_timer
,
(
void
*
)
false
,
1
);
on_each_cpu
(
__setup_broadcast_timer
,
(
void
*
)
false
,
1
);
unregister_cpu_notifier
(
&
setup_broadcast_notifier
);
unregister_cpu_notifier
(
&
setup_broadcast_notifier
);
}
}
...
...
include/acpi/acpi_numa.h
浏览文件 @
79ba0db6
...
@@ -15,6 +15,7 @@ extern int pxm_to_node(int);
...
@@ -15,6 +15,7 @@ extern int pxm_to_node(int);
extern
int
node_to_pxm
(
int
);
extern
int
node_to_pxm
(
int
);
extern
void
__acpi_map_pxm_to_node
(
int
,
int
);
extern
void
__acpi_map_pxm_to_node
(
int
,
int
);
extern
int
acpi_map_pxm_to_node
(
int
);
extern
int
acpi_map_pxm_to_node
(
int
);
extern
unsigned
char
acpi_srat_revision
;
#endif
/* CONFIG_ACPI_NUMA */
#endif
/* CONFIG_ACPI_NUMA */
#endif
/* __ACP_NUMA_H */
#endif
/* __ACP_NUMA_H */
include/linux/cpuidle.h
浏览文件 @
79ba0db6
...
@@ -188,7 +188,14 @@ struct cpuidle_governor {
...
@@ -188,7 +188,14 @@ struct cpuidle_governor {
extern
int
cpuidle_register_governor
(
struct
cpuidle_governor
*
gov
);
extern
int
cpuidle_register_governor
(
struct
cpuidle_governor
*
gov
);
extern
void
cpuidle_unregister_governor
(
struct
cpuidle_governor
*
gov
);
extern
void
cpuidle_unregister_governor
(
struct
cpuidle_governor
*
gov
);
#ifdef CONFIG_INTEL_IDLE
extern
int
intel_idle_cpu_init
(
int
cpu
);
#else
#else
static
inline
int
intel_idle_cpu_init
(
int
cpu
)
{
return
-
1
;
}
#endif
#else
static
inline
int
intel_idle_cpu_init
(
int
cpu
)
{
return
-
1
;
}
static
inline
int
cpuidle_register_governor
(
struct
cpuidle_governor
*
gov
)
static
inline
int
cpuidle_register_governor
(
struct
cpuidle_governor
*
gov
)
{
return
0
;}
{
return
0
;}
...
...
tools/power/x86/turbostat/turbostat.c
浏览文件 @
79ba0db6
...
@@ -811,6 +811,8 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
...
@@ -811,6 +811,8 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
case
0x2C
:
/* Westmere EP - Gulftown */
case
0x2C
:
/* Westmere EP - Gulftown */
case
0x2A
:
/* SNB */
case
0x2A
:
/* SNB */
case
0x2D
:
/* SNB Xeon */
case
0x2D
:
/* SNB Xeon */
case
0x3A
:
/* IVB */
case
0x3D
:
/* IVB Xeon */
return
1
;
return
1
;
case
0x2E
:
/* Nehalem-EX Xeon - Beckton */
case
0x2E
:
/* Nehalem-EX Xeon - Beckton */
case
0x2F
:
/* Westmere-EX Xeon - Eagleton */
case
0x2F
:
/* Westmere-EX Xeon - Eagleton */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录