* Fix for /proc/<pid>/maps "stack" vma annotation
* sched stats not printing correct sleeping task PC * perf not reporting page faults -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJU9pzyAAoJEGnX8d3iisJe4+UP+gJmR69LPcyz+ZUZEaObpwSD 8D5Zz8csMtpvzW1IoIKo1qPLEkF59PpK2dt4K4xDmYf6GRftEiOryJ8ASu4NEJxd Rg13GuYazzjps22ztp9Cr6LiG5YrNuLG51HZdlGvoeZll8so87bjehKV5EWhpeBw 5+TGhAUwKmowdNiqO35DXalYGZCot7t7Wj9ADC3qzKzXmQnnSGK1Jp/iBtqX98Tu nlEow2jubrn8ofsifshYgViBseCHgMTn00Eqa1usb+a7DUv5PiPHsG/V29nzdRem g/f0Trp0uqSVsJ2Jlv/9rpWPaFN9XtCNhNV+kaXkhXlD2o2dhrbBSx+VGXMO5lBD lNwqfyfZ1EG+OyJnRK6BgKh9OTV4sK218iY5as2jtBq9crggTvGjRKUfEVyPOrdN MwBNjqiod/jB/lfom0FSO3JXo2DJwoLYmCEYLPuhIGfWr2yx8kFbnqdX/u7uzyg1 RezSKpQqMOMVkewB5tbcH3luZqLRsVNmKF/7ghtiaJfTR9QGIKdxATJtti7I4oTZ ARLG5W1JMjJKpVypxyvOvB8FlGKBxkqlZQiT8uCI8wMxgOntmOVtuNXaRJcf9qs0 3z/CrgRPvnZ09S4O0yfYjqqLwETph1mBjI8btspw55tq0ZLqs0lmcUpAF4zs+D+e LNMKue1NWxXNAFqorsSh =clY5 -----END PGP SIGNATURE----- Merge tag 'arc-4.0-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc Pull ARC fixes from Vineet Gupta: - Fix for /proc/<pid>/maps "stack" vma annotation - sched stats not printing correct sleeping task PC - perf not reporting page faults * tag 'arc-4.0-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: ARC: Fix thread_saved_pc() ARC: Fix KSTK_ESP() ARC: perf: Enable generic software events ARC: Make arc_unwind_core accessible externally
This commit is contained in:
commit
f2cb4777f6
|
@ -47,9 +47,6 @@ struct thread_struct {
|
|||
/* Forward declaration, a strange C thing */
|
||||
struct task_struct;
|
||||
|
||||
/* Return saved PC of a blocked thread */
|
||||
unsigned long thread_saved_pc(struct task_struct *t);
|
||||
|
||||
#define task_pt_regs(p) \
|
||||
((struct pt_regs *)(THREAD_SIZE + (void *)task_stack_page(p)) - 1)
|
||||
|
||||
|
@ -72,18 +69,21 @@ unsigned long thread_saved_pc(struct task_struct *t);
|
|||
#define release_segments(mm) do { } while (0)
|
||||
|
||||
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->ret)
|
||||
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->sp)
|
||||
|
||||
/*
|
||||
* Where abouts of Task's sp, fp, blink when it was last seen in kernel mode.
|
||||
* Look in process.c for details of kernel stack layout
|
||||
*/
|
||||
#define KSTK_ESP(tsk) (tsk->thread.ksp)
|
||||
#define TSK_K_ESP(tsk) (tsk->thread.ksp)
|
||||
|
||||
#define KSTK_REG(tsk, off) (*((unsigned int *)(KSTK_ESP(tsk) + \
|
||||
#define TSK_K_REG(tsk, off) (*((unsigned int *)(TSK_K_ESP(tsk) + \
|
||||
sizeof(struct callee_regs) + off)))
|
||||
|
||||
#define KSTK_BLINK(tsk) KSTK_REG(tsk, 4)
|
||||
#define KSTK_FP(tsk) KSTK_REG(tsk, 0)
|
||||
#define TSK_K_BLINK(tsk) TSK_K_REG(tsk, 4)
|
||||
#define TSK_K_FP(tsk) TSK_K_REG(tsk, 0)
|
||||
|
||||
#define thread_saved_pc(tsk) TSK_K_BLINK(tsk)
|
||||
|
||||
extern void start_thread(struct pt_regs * regs, unsigned long pc,
|
||||
unsigned long usp);
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
|
||||
* Copyright (C) 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_STACKTRACE_H
|
||||
#define __ASM_STACKTRACE_H
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
/**
|
||||
* arc_unwind_core - Unwind the kernel mode stack for an execution context
|
||||
* @tsk: NULL for current task, specific task otherwise
|
||||
* @regs: pt_regs used to seed the unwinder {SP, FP, BLINK, PC}
|
||||
* If NULL, use pt_regs of @tsk (if !NULL) otherwise
|
||||
* use the current values of {SP, FP, BLINK, PC}
|
||||
* @consumer_fn: Callback invoked for each frame unwound
|
||||
* Returns 0 to continue unwinding, -1 to stop
|
||||
* @arg: Arg to callback
|
||||
*
|
||||
* Returns the address of first function in stack
|
||||
*
|
||||
* Semantics:
|
||||
* - synchronous unwinding (e.g. dump_stack): @tsk NULL, @regs NULL
|
||||
* - Asynchronous unwinding of sleeping task: @tsk !NULL, @regs NULL
|
||||
* - Asynchronous unwinding of intr/excp etc: @tsk !NULL, @regs !NULL
|
||||
*/
|
||||
notrace noinline unsigned int arc_unwind_core(
|
||||
struct task_struct *tsk, struct pt_regs *regs,
|
||||
int (*consumer_fn) (unsigned int, void *),
|
||||
void *arg);
|
||||
|
||||
#endif /* __ASM_STACKTRACE_H */
|
|
@ -192,29 +192,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* API: expected by schedular Code: If thread is sleeping where is that.
|
||||
* What is this good for? it will be always the scheduler or ret_from_fork.
|
||||
* So we hard code that anyways.
|
||||
*/
|
||||
unsigned long thread_saved_pc(struct task_struct *t)
|
||||
{
|
||||
struct pt_regs *regs = task_pt_regs(t);
|
||||
unsigned long blink = 0;
|
||||
|
||||
/*
|
||||
* If the thread being queried for in not itself calling this, then it
|
||||
* implies it is not executing, which in turn implies it is sleeping,
|
||||
* which in turn implies it got switched OUT by the schedular.
|
||||
* In that case, it's kernel mode blink can reliably retrieved as per
|
||||
* the picture above (right above pt_regs).
|
||||
*/
|
||||
if (t != current && t->state != TASK_RUNNING)
|
||||
blink = *((unsigned int *)regs - 1);
|
||||
|
||||
return blink;
|
||||
}
|
||||
|
||||
int elf_check_arch(const struct elf32_hdr *x)
|
||||
{
|
||||
unsigned int eflags;
|
||||
|
|
|
@ -43,6 +43,10 @@ static void seed_unwind_frame_info(struct task_struct *tsk,
|
|||
struct pt_regs *regs,
|
||||
struct unwind_frame_info *frame_info)
|
||||
{
|
||||
/*
|
||||
* synchronous unwinding (e.g. dump_stack)
|
||||
* - uses current values of SP and friends
|
||||
*/
|
||||
if (tsk == NULL && regs == NULL) {
|
||||
unsigned long fp, sp, blink, ret;
|
||||
frame_info->task = current;
|
||||
|
@ -61,12 +65,17 @@ static void seed_unwind_frame_info(struct task_struct *tsk,
|
|||
frame_info->regs.r63 = ret;
|
||||
frame_info->call_frame = 0;
|
||||
} else if (regs == NULL) {
|
||||
/*
|
||||
* Asynchronous unwinding of sleeping task
|
||||
* - Gets SP etc from task's pt_regs (saved bottom of kernel
|
||||
* mode stack of task)
|
||||
*/
|
||||
|
||||
frame_info->task = tsk;
|
||||
|
||||
frame_info->regs.r27 = KSTK_FP(tsk);
|
||||
frame_info->regs.r28 = KSTK_ESP(tsk);
|
||||
frame_info->regs.r31 = KSTK_BLINK(tsk);
|
||||
frame_info->regs.r27 = TSK_K_FP(tsk);
|
||||
frame_info->regs.r28 = TSK_K_ESP(tsk);
|
||||
frame_info->regs.r31 = TSK_K_BLINK(tsk);
|
||||
frame_info->regs.r63 = (unsigned int)__switch_to;
|
||||
|
||||
/* In the prologue of __switch_to, first FP is saved on stack
|
||||
|
@ -83,6 +92,10 @@ static void seed_unwind_frame_info(struct task_struct *tsk,
|
|||
frame_info->call_frame = 0;
|
||||
|
||||
} else {
|
||||
/*
|
||||
* Asynchronous unwinding of intr/exception
|
||||
* - Just uses the pt_regs passed
|
||||
*/
|
||||
frame_info->task = tsk;
|
||||
|
||||
frame_info->regs.r27 = regs->fp;
|
||||
|
@ -95,7 +108,7 @@ static void seed_unwind_frame_info(struct task_struct *tsk,
|
|||
|
||||
#endif
|
||||
|
||||
static noinline unsigned int
|
||||
notrace noinline unsigned int
|
||||
arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs,
|
||||
int (*consumer_fn) (unsigned int, void *), void *arg)
|
||||
{
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/disasm.h>
|
||||
|
@ -253,6 +254,7 @@ int misaligned_fixup(unsigned long address, struct pt_regs *regs,
|
|||
}
|
||||
}
|
||||
|
||||
perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, address);
|
||||
return 0;
|
||||
|
||||
fault:
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/ptrace.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/mmu.h>
|
||||
|
||||
|
@ -139,13 +140,20 @@ void do_page_fault(unsigned long address, struct pt_regs *regs)
|
|||
return;
|
||||
}
|
||||
|
||||
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
|
||||
|
||||
if (likely(!(fault & VM_FAULT_ERROR))) {
|
||||
if (flags & FAULT_FLAG_ALLOW_RETRY) {
|
||||
/* To avoid updating stats twice for retry case */
|
||||
if (fault & VM_FAULT_MAJOR)
|
||||
if (fault & VM_FAULT_MAJOR) {
|
||||
tsk->maj_flt++;
|
||||
else
|
||||
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1,
|
||||
regs, address);
|
||||
} else {
|
||||
tsk->min_flt++;
|
||||
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1,
|
||||
regs, address);
|
||||
}
|
||||
|
||||
if (fault & VM_FAULT_RETRY) {
|
||||
flags &= ~FAULT_FLAG_ALLOW_RETRY;
|
||||
|
|
Loading…
Reference in New Issue