Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
916ca14a
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
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看板
提交
916ca14a
编写于
10月 16, 2012
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
sparc64: Add global PMU register dumping via sysrq.
Signed-off-by:
N
David S. Miller
<
davem@davemloft.net
>
上级
08280e6c
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
189 addition
and
23 deletion
+189
-23
Documentation/sysrq.txt
Documentation/sysrq.txt
+1
-0
arch/sparc/include/asm/ptrace.h
arch/sparc/include/asm/ptrace.h
+12
-1
arch/sparc/include/asm/smp_64.h
arch/sparc/include/asm/smp_64.h
+2
-0
arch/sparc/kernel/process_64.c
arch/sparc/kernel/process_64.c
+100
-20
arch/sparc/kernel/smp_64.c
arch/sparc/kernel/smp_64.c
+11
-0
arch/sparc/mm/ultra.S
arch/sparc/mm/ultra.S
+62
-2
drivers/tty/sysrq.c
drivers/tty/sysrq.c
+1
-0
未找到文件。
Documentation/sysrq.txt
浏览文件 @
916ca14a
...
@@ -116,6 +116,7 @@ On all - write a character to /proc/sysrq-trigger. e.g.:
...
@@ -116,6 +116,7 @@ On all - write a character to /proc/sysrq-trigger. e.g.:
'w' - Dumps tasks that are in uninterruptable (blocked) state.
'w' - Dumps tasks that are in uninterruptable (blocked) state.
'x' - Used by xmon interface on ppc/powerpc platforms.
'x' - Used by xmon interface on ppc/powerpc platforms.
Show global PMU Registers on sparc64.
'y' - Show global CPU Registers [SPARC-64 specific]
'y' - Show global CPU Registers [SPARC-64 specific]
...
...
arch/sparc/include/asm/ptrace.h
浏览文件 @
916ca14a
...
@@ -42,7 +42,18 @@ struct global_reg_snapshot {
...
@@ -42,7 +42,18 @@ struct global_reg_snapshot {
struct
thread_info
*
thread
;
struct
thread_info
*
thread
;
unsigned
long
pad1
;
unsigned
long
pad1
;
};
};
extern
struct
global_reg_snapshot
global_reg_snapshot
[
NR_CPUS
];
struct
global_pmu_snapshot
{
unsigned
long
pcr
[
4
];
unsigned
long
pic
[
4
];
};
union
global_cpu_snapshot
{
struct
global_reg_snapshot
reg
;
struct
global_pmu_snapshot
pmu
;
};
extern
union
global_cpu_snapshot
global_cpu_snapshot
[
NR_CPUS
];
#define force_successful_syscall_return() \
#define force_successful_syscall_return() \
do { current_thread_info()->syscall_noerror = 1; \
do { current_thread_info()->syscall_noerror = 1; \
...
...
arch/sparc/include/asm/smp_64.h
浏览文件 @
916ca14a
...
@@ -48,6 +48,7 @@ extern void smp_fill_in_sib_core_maps(void);
...
@@ -48,6 +48,7 @@ extern void smp_fill_in_sib_core_maps(void);
extern
void
cpu_play_dead
(
void
);
extern
void
cpu_play_dead
(
void
);
extern
void
smp_fetch_global_regs
(
void
);
extern
void
smp_fetch_global_regs
(
void
);
extern
void
smp_fetch_global_pmu
(
void
);
struct
seq_file
;
struct
seq_file
;
void
smp_bogo
(
struct
seq_file
*
);
void
smp_bogo
(
struct
seq_file
*
);
...
@@ -65,6 +66,7 @@ extern void __cpu_die(unsigned int cpu);
...
@@ -65,6 +66,7 @@ extern void __cpu_die(unsigned int cpu);
#define hard_smp_processor_id() 0
#define hard_smp_processor_id() 0
#define smp_fill_in_sib_core_maps() do { } while (0)
#define smp_fill_in_sib_core_maps() do { } while (0)
#define smp_fetch_global_regs() do { } while (0)
#define smp_fetch_global_regs() do { } while (0)
#define smp_fetch_global_pmu() do { } while (0)
#endif
/* !(CONFIG_SMP) */
#endif
/* !(CONFIG_SMP) */
...
...
arch/sparc/kernel/process_64.c
浏览文件 @
916ca14a
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include <linux/tick.h>
#include <linux/tick.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/cpu.h>
#include <linux/cpu.h>
#include <linux/perf_event.h>
#include <linux/elfcore.h>
#include <linux/elfcore.h>
#include <linux/sysrq.h>
#include <linux/sysrq.h>
#include <linux/nmi.h>
#include <linux/nmi.h>
...
@@ -47,6 +48,7 @@
...
@@ -47,6 +48,7 @@
#include <asm/syscalls.h>
#include <asm/syscalls.h>
#include <asm/irq_regs.h>
#include <asm/irq_regs.h>
#include <asm/smp.h>
#include <asm/smp.h>
#include <asm/pcr.h>
#include "kstack.h"
#include "kstack.h"
...
@@ -204,18 +206,22 @@ void show_regs(struct pt_regs *regs)
...
@@ -204,18 +206,22 @@ void show_regs(struct pt_regs *regs)
show_stack
(
current
,
(
unsigned
long
*
)
regs
->
u_regs
[
UREG_FP
]);
show_stack
(
current
,
(
unsigned
long
*
)
regs
->
u_regs
[
UREG_FP
]);
}
}
struct
global_reg_snapshot
global_reg
_snapshot
[
NR_CPUS
];
union
global_cpu_snapshot
global_cpu
_snapshot
[
NR_CPUS
];
static
DEFINE_SPINLOCK
(
global_
reg
_snapshot_lock
);
static
DEFINE_SPINLOCK
(
global_
cpu
_snapshot_lock
);
static
void
__global_reg_self
(
struct
thread_info
*
tp
,
struct
pt_regs
*
regs
,
static
void
__global_reg_self
(
struct
thread_info
*
tp
,
struct
pt_regs
*
regs
,
int
this_cpu
)
int
this_cpu
)
{
{
struct
global_reg_snapshot
*
rp
;
flushw_all
();
flushw_all
();
global_reg_snapshot
[
this_cpu
].
tstate
=
regs
->
tstate
;
rp
=
&
global_cpu_snapshot
[
this_cpu
].
reg
;
global_reg_snapshot
[
this_cpu
].
tpc
=
regs
->
tpc
;
global_reg_snapshot
[
this_cpu
].
tnpc
=
regs
->
tnpc
;
rp
->
tstate
=
regs
->
tstate
;
global_reg_snapshot
[
this_cpu
].
o7
=
regs
->
u_regs
[
UREG_I7
];
rp
->
tpc
=
regs
->
tpc
;
rp
->
tnpc
=
regs
->
tnpc
;
rp
->
o7
=
regs
->
u_regs
[
UREG_I7
];
if
(
regs
->
tstate
&
TSTATE_PRIV
)
{
if
(
regs
->
tstate
&
TSTATE_PRIV
)
{
struct
reg_window
*
rw
;
struct
reg_window
*
rw
;
...
@@ -223,17 +229,17 @@ static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs,
...
@@ -223,17 +229,17 @@ static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs,
rw
=
(
struct
reg_window
*
)
rw
=
(
struct
reg_window
*
)
(
regs
->
u_regs
[
UREG_FP
]
+
STACK_BIAS
);
(
regs
->
u_regs
[
UREG_FP
]
+
STACK_BIAS
);
if
(
kstack_valid
(
tp
,
(
unsigned
long
)
rw
))
{
if
(
kstack_valid
(
tp
,
(
unsigned
long
)
rw
))
{
global_reg_snapshot
[
this_cpu
].
i7
=
rw
->
ins
[
7
];
rp
->
i7
=
rw
->
ins
[
7
];
rw
=
(
struct
reg_window
*
)
rw
=
(
struct
reg_window
*
)
(
rw
->
ins
[
6
]
+
STACK_BIAS
);
(
rw
->
ins
[
6
]
+
STACK_BIAS
);
if
(
kstack_valid
(
tp
,
(
unsigned
long
)
rw
))
if
(
kstack_valid
(
tp
,
(
unsigned
long
)
rw
))
global_reg_snapshot
[
this_cpu
].
rpc
=
rw
->
ins
[
7
];
rp
->
rpc
=
rw
->
ins
[
7
];
}
}
}
else
{
}
else
{
global_reg_snapshot
[
this_cpu
].
i7
=
0
;
rp
->
i7
=
0
;
global_reg_snapshot
[
this_cpu
].
rpc
=
0
;
rp
->
rpc
=
0
;
}
}
global_reg_snapshot
[
this_cpu
].
thread
=
tp
;
rp
->
thread
=
tp
;
}
}
/* In order to avoid hangs we do not try to synchronize with the
/* In order to avoid hangs we do not try to synchronize with the
...
@@ -261,9 +267,9 @@ void arch_trigger_all_cpu_backtrace(void)
...
@@ -261,9 +267,9 @@ void arch_trigger_all_cpu_backtrace(void)
if
(
!
regs
)
if
(
!
regs
)
regs
=
tp
->
kregs
;
regs
=
tp
->
kregs
;
spin_lock_irqsave
(
&
global_
reg
_snapshot_lock
,
flags
);
spin_lock_irqsave
(
&
global_
cpu
_snapshot_lock
,
flags
);
memset
(
global_
reg_snapshot
,
0
,
sizeof
(
global_reg
_snapshot
));
memset
(
global_
cpu_snapshot
,
0
,
sizeof
(
global_cpu
_snapshot
));
this_cpu
=
raw_smp_processor_id
();
this_cpu
=
raw_smp_processor_id
();
...
@@ -272,7 +278,7 @@ void arch_trigger_all_cpu_backtrace(void)
...
@@ -272,7 +278,7 @@ void arch_trigger_all_cpu_backtrace(void)
smp_fetch_global_regs
();
smp_fetch_global_regs
();
for_each_online_cpu
(
cpu
)
{
for_each_online_cpu
(
cpu
)
{
struct
global_reg_snapshot
*
gp
=
&
global_
reg_snapshot
[
cpu
]
;
struct
global_reg_snapshot
*
gp
=
&
global_
cpu_snapshot
[
cpu
].
reg
;
__global_reg_poll
(
gp
);
__global_reg_poll
(
gp
);
...
@@ -295,9 +301,9 @@ void arch_trigger_all_cpu_backtrace(void)
...
@@ -295,9 +301,9 @@ void arch_trigger_all_cpu_backtrace(void)
}
}
}
}
memset
(
global_
reg_snapshot
,
0
,
sizeof
(
global_reg
_snapshot
));
memset
(
global_
cpu_snapshot
,
0
,
sizeof
(
global_cpu
_snapshot
));
spin_unlock_irqrestore
(
&
global_
reg
_snapshot_lock
,
flags
);
spin_unlock_irqrestore
(
&
global_
cpu
_snapshot_lock
,
flags
);
}
}
#ifdef CONFIG_MAGIC_SYSRQ
#ifdef CONFIG_MAGIC_SYSRQ
...
@@ -309,16 +315,90 @@ static void sysrq_handle_globreg(int key)
...
@@ -309,16 +315,90 @@ static void sysrq_handle_globreg(int key)
static
struct
sysrq_key_op
sparc_globalreg_op
=
{
static
struct
sysrq_key_op
sparc_globalreg_op
=
{
.
handler
=
sysrq_handle_globreg
,
.
handler
=
sysrq_handle_globreg
,
.
help_msg
=
"
Globalregs
"
,
.
help_msg
=
"
global-regs(Y)
"
,
.
action_msg
=
"Show Global CPU Regs"
,
.
action_msg
=
"Show Global CPU Regs"
,
};
};
static
int
__init
sparc_globreg_init
(
void
)
static
void
__global_pmu_self
(
int
this_cpu
)
{
struct
global_pmu_snapshot
*
pp
;
int
i
,
num
;
pp
=
&
global_cpu_snapshot
[
this_cpu
].
pmu
;
num
=
1
;
if
(
tlb_type
==
hypervisor
&&
sun4v_chip_type
>=
SUN4V_CHIP_NIAGARA4
)
num
=
4
;
for
(
i
=
0
;
i
<
num
;
i
++
)
{
pp
->
pcr
[
i
]
=
pcr_ops
->
read_pcr
(
i
);
pp
->
pic
[
i
]
=
pcr_ops
->
read_pic
(
i
);
}
}
static
void
__global_pmu_poll
(
struct
global_pmu_snapshot
*
pp
)
{
int
limit
=
0
;
while
(
!
pp
->
pcr
[
0
]
&&
++
limit
<
100
)
{
barrier
();
udelay
(
1
);
}
}
static
void
pmu_snapshot_all_cpus
(
void
)
{
{
return
register_sysrq_key
(
'y'
,
&
sparc_globalreg_op
);
unsigned
long
flags
;
int
this_cpu
,
cpu
;
spin_lock_irqsave
(
&
global_cpu_snapshot_lock
,
flags
);
memset
(
global_cpu_snapshot
,
0
,
sizeof
(
global_cpu_snapshot
));
this_cpu
=
raw_smp_processor_id
();
__global_pmu_self
(
this_cpu
);
smp_fetch_global_pmu
();
for_each_online_cpu
(
cpu
)
{
struct
global_pmu_snapshot
*
pp
=
&
global_cpu_snapshot
[
cpu
].
pmu
;
__global_pmu_poll
(
pp
);
printk
(
"%c CPU[%3d]: PCR[%08lx:%08lx:%08lx:%08lx] PIC[%08lx:%08lx:%08lx:%08lx]
\n
"
,
(
cpu
==
this_cpu
?
'*'
:
' '
),
cpu
,
pp
->
pcr
[
0
],
pp
->
pcr
[
1
],
pp
->
pcr
[
2
],
pp
->
pcr
[
3
],
pp
->
pic
[
0
],
pp
->
pic
[
1
],
pp
->
pic
[
2
],
pp
->
pic
[
3
]);
}
memset
(
global_cpu_snapshot
,
0
,
sizeof
(
global_cpu_snapshot
));
spin_unlock_irqrestore
(
&
global_cpu_snapshot_lock
,
flags
);
}
static
void
sysrq_handle_globpmu
(
int
key
)
{
pmu_snapshot_all_cpus
();
}
static
struct
sysrq_key_op
sparc_globalpmu_op
=
{
.
handler
=
sysrq_handle_globpmu
,
.
help_msg
=
"global-pmu(X)"
,
.
action_msg
=
"Show Global PMU Regs"
,
};
static
int
__init
sparc_sysrq_init
(
void
)
{
int
ret
=
register_sysrq_key
(
'y'
,
&
sparc_globalreg_op
);
if
(
!
ret
)
ret
=
register_sysrq_key
(
'x'
,
&
sparc_globalpmu_op
);
return
ret
;
}
}
core_initcall
(
sparc_
globreg
_init
);
core_initcall
(
sparc_
sysrq
_init
);
#endif
#endif
...
...
arch/sparc/kernel/smp_64.c
浏览文件 @
916ca14a
...
@@ -852,6 +852,8 @@ extern unsigned long xcall_flush_tlb_mm;
...
@@ -852,6 +852,8 @@ extern unsigned long xcall_flush_tlb_mm;
extern
unsigned
long
xcall_flush_tlb_pending
;
extern
unsigned
long
xcall_flush_tlb_pending
;
extern
unsigned
long
xcall_flush_tlb_kernel_range
;
extern
unsigned
long
xcall_flush_tlb_kernel_range
;
extern
unsigned
long
xcall_fetch_glob_regs
;
extern
unsigned
long
xcall_fetch_glob_regs
;
extern
unsigned
long
xcall_fetch_glob_pmu
;
extern
unsigned
long
xcall_fetch_glob_pmu_n4
;
extern
unsigned
long
xcall_receive_signal
;
extern
unsigned
long
xcall_receive_signal
;
extern
unsigned
long
xcall_new_mmu_context_version
;
extern
unsigned
long
xcall_new_mmu_context_version
;
#ifdef CONFIG_KGDB
#ifdef CONFIG_KGDB
...
@@ -1000,6 +1002,15 @@ void smp_fetch_global_regs(void)
...
@@ -1000,6 +1002,15 @@ void smp_fetch_global_regs(void)
smp_cross_call
(
&
xcall_fetch_glob_regs
,
0
,
0
,
0
);
smp_cross_call
(
&
xcall_fetch_glob_regs
,
0
,
0
,
0
);
}
}
void
smp_fetch_global_pmu
(
void
)
{
if
(
tlb_type
==
hypervisor
&&
sun4v_chip_type
>=
SUN4V_CHIP_NIAGARA4
)
smp_cross_call
(
&
xcall_fetch_glob_pmu_n4
,
0
,
0
,
0
);
else
smp_cross_call
(
&
xcall_fetch_glob_pmu
,
0
,
0
,
0
);
}
/* We know that the window frames of the user have been flushed
/* We know that the window frames of the user have been flushed
* to the stack before we get here because all callers of us
* to the stack before we get here because all callers of us
* are flush_tlb_*() routines, and these run after flush_cache_*()
* are flush_tlb_*() routines, and these run after flush_cache_*()
...
...
arch/sparc/mm/ultra.S
浏览文件 @
916ca14a
...
@@ -481,8 +481,8 @@ xcall_sync_tick:
...
@@ -481,8 +481,8 @@ xcall_sync_tick:
.
globl
xcall_fetch_glob_regs
.
globl
xcall_fetch_glob_regs
xcall_fetch_glob_regs
:
xcall_fetch_glob_regs
:
sethi
%
hi
(
global_
reg
_snapshot
),
%
g1
sethi
%
hi
(
global_
cpu
_snapshot
),
%
g1
or
%
g1
,
%
lo
(
global_
reg
_snapshot
),
%
g1
or
%
g1
,
%
lo
(
global_
cpu
_snapshot
),
%
g1
__GET_CPUID
(%
g2
)
__GET_CPUID
(%
g2
)
sllx
%
g2
,
6
,
%
g3
sllx
%
g2
,
6
,
%
g3
add
%
g1
,
%
g3
,
%
g1
add
%
g1
,
%
g3
,
%
g1
...
@@ -509,6 +509,66 @@ xcall_fetch_glob_regs:
...
@@ -509,6 +509,66 @@ xcall_fetch_glob_regs:
stx
%
g3
,
[%
g1
+
GR_SNAP_THREAD
]
stx
%
g3
,
[%
g1
+
GR_SNAP_THREAD
]
retry
retry
.
globl
xcall_fetch_glob_pmu
xcall_fetch_glob_pmu
:
sethi
%
hi
(
global_cpu_snapshot
),
%
g1
or
%
g1
,
%
lo
(
global_cpu_snapshot
),
%
g1
__GET_CPUID
(%
g2
)
sllx
%
g2
,
6
,
%
g3
add
%
g1
,
%
g3
,
%
g1
rd
%
pic
,
%
g7
stx
%
g7
,
[%
g1
+
(
4
*
8
)]
rd
%
pcr
,
%
g7
stx
%
g7
,
[%
g1
+
(
0
*
8
)]
retry
.
globl
xcall_fetch_glob_pmu_n4
xcall_fetch_glob_pmu_n4
:
sethi
%
hi
(
global_cpu_snapshot
),
%
g1
or
%
g1
,
%
lo
(
global_cpu_snapshot
),
%
g1
__GET_CPUID
(%
g2
)
sllx
%
g2
,
6
,
%
g3
add
%
g1
,
%
g3
,
%
g1
ldxa
[%
g0
]
ASI_PIC
,
%
g7
stx
%
g7
,
[%
g1
+
(
4
*
8
)]
mov
0x08
,
%
g3
ldxa
[%
g3
]
ASI_PIC
,
%
g7
stx
%
g7
,
[%
g1
+
(
5
*
8
)]
mov
0x10
,
%
g3
ldxa
[%
g3
]
ASI_PIC
,
%
g7
stx
%
g7
,
[%
g1
+
(
6
*
8
)]
mov
0x18
,
%
g3
ldxa
[%
g3
]
ASI_PIC
,
%
g7
stx
%
g7
,
[%
g1
+
(
7
*
8
)]
mov
%
o0
,
%
g2
mov
%
o1
,
%
g3
mov
%
o5
,
%
g7
mov
HV_FAST_VT_GET_PERFREG
,
%
o5
mov
3
,
%
o0
ta
HV_FAST_TRAP
stx
%
o1
,
[%
g1
+
(
3
*
8
)]
mov
HV_FAST_VT_GET_PERFREG
,
%
o5
mov
2
,
%
o0
ta
HV_FAST_TRAP
stx
%
o1
,
[%
g1
+
(
2
*
8
)]
mov
HV_FAST_VT_GET_PERFREG
,
%
o5
mov
1
,
%
o0
ta
HV_FAST_TRAP
stx
%
o1
,
[%
g1
+
(
1
*
8
)]
mov
HV_FAST_VT_GET_PERFREG
,
%
o5
mov
0
,
%
o0
ta
HV_FAST_TRAP
stx
%
o1
,
[%
g1
+
(
0
*
8
)]
mov
%
g2
,
%
o0
mov
%
g3
,
%
o1
mov
%
g7
,
%
o5
retry
#ifdef DCACHE_ALIASING_POSSIBLE
#ifdef DCACHE_ALIASING_POSSIBLE
.
align
32
.
align
32
.
globl
xcall_flush_dcache_page_cheetah
.
globl
xcall_flush_dcache_page_cheetah
...
...
drivers/tty/sysrq.c
浏览文件 @
916ca14a
...
@@ -452,6 +452,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
...
@@ -452,6 +452,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
NULL
,
/* v */
NULL
,
/* v */
&
sysrq_showstate_blocked_op
,
/* w */
&
sysrq_showstate_blocked_op
,
/* w */
/* x: May be registered on ppc/powerpc for xmon */
/* x: May be registered on ppc/powerpc for xmon */
/* x: May be registered on sparc64 for global PMU dump */
NULL
,
/* x */
NULL
,
/* x */
/* y: May be registered on sparc64 for global register dump */
/* y: May be registered on sparc64 for global register dump */
NULL
,
/* y */
NULL
,
/* y */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录