From: Kevin Hilman <khilman(a)linaro.org>
When CONFIG_TRACE is disabled, linking fails with:
common/built-in.o:(.data.init_sequence_f+0x8): undefined reference to `trace_early_init'
To fix, wrap trace init calls with #ifdef CONFIG_TRACE.
While at it, remove the static inline version of the init call from
trace.h as suggested by Simon Glass, since it doesnt work.
Cc: Simon Glass <sjg(a)chromium.org>
Cc: Tom Rini <trini(a)ti.com>
Signed-off-by: Kevin Hilman <khilman(a)linaro.org>
---
Applies to v2015.01-rc3
v3: Actually remove the static inlines this time. :/
common/board_f.c | 2 ++
include/trace.h | 7 -------
2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/common/board_f.c b/common/board_f.c
index 98c9c728ce73..cfd77f865361 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -813,7 +813,9 @@ static init_fnc_t init_sequence_f[] = {
#endif
setup_mon_len,
setup_fdt,
+#ifdef CONFIG_TRACE
trace_early_init,
+#endif
initf_malloc,
#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
/* TODO: can this go into arch_cpu_init()? */
diff --git a/include/trace.h b/include/trace.h
index 871327fb358a..09a38d782fc0 100644
--- a/include/trace.h
+++ b/include/trace.h
@@ -89,14 +89,7 @@ int trace_list_calls(void *buff, int buff_size, unsigned int *needed);
*/
void trace_set_enabled(int enabled);
-#ifdef CONFIG_TRACE_EARLY
int trace_early_init(void);
-#else
-static inline int trace_early_init(void)
-{
- return 0;
-}
-#endif
/**
* Init the trace system
--
2.1.3
Currently restore_user_regs deallocates the SVC stack early in
its execution and relies on no exception being taken between
the deallocation and the registers being restored. The introduction
of a default FIQ handler that also uses the SVC stack breaks this
assumption and can result in corrupted register state.
This patch works around the problem by removing the early
stack deallocation and using r2 as a temporary instead. I have
not found a way to do this without introducing an extra mov
instruction to the macro.
Signed-off-by: Daniel Thompson <daniel.thompson(a)linaro.org>
---
Notes:
I have recently started to hook up the PMU via FIQ (although
its slightly hacky at present) and was seeing random userspace
SEGVs when perf was running (after ~100,000 or so FIQs).
Instrumenting the code eventually revealed that in almost all
cases the last FIQ handler to run prior the SEGV had interrupted
ret_to_user_from_irq or ret_fast_syscall. Very occasionally it was
in the fault handling code (because that code runs as part of SEGV
handling and the PMU is instrumenting that too).
No SEGV problems have been observed since fixing the issue. This
version of the patch has seen >7M FIQs and an older version (based
on cpsid f) ran overnight.
arch/arm/kernel/entry-header.S | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 4176df721bf0..1a0045abead7 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -253,21 +253,22 @@
.endm
.macro restore_user_regs, fast = 0, offset = 0
- ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr
- ldr lr, [sp, #\offset + S_PC]! @ get pc
+ mov r2, sp
+ ldr r1, [r2, #\offset + S_PSR] @ get calling cpsr
+ ldr lr, [r2, #\offset + S_PC]! @ get pc
msr spsr_cxsf, r1 @ save in spsr_svc
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K)
@ We must avoid clrex due to Cortex-A15 erratum #830321
- strex r1, r2, [sp] @ clear the exclusive monitor
+ strex r1, r2, [r2] @ clear the exclusive monitor
#endif
.if \fast
- ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
+ ldmdb r2, {r1 - lr}^ @ get calling r1 - lr
.else
- ldmdb sp, {r0 - lr}^ @ get calling r0 - lr
+ ldmdb r2, {r0 - lr}^ @ get calling r0 - lr
.endif
mov r0, r0 @ ARMv5T and earlier require a nop
@ after ldm {}^
- add sp, sp, #S_FRAME_SIZE - S_PC
+ add sp, sp, #\offset + S_FRAME_SIZE
movs pc, lr @ return & move spsr_svc into cpsr
.endm
--
1.9.3
Hi,
Why:
====
While sharing buffers using dma-buf, currently there's no mechanism to let
devices share their memory access constraints with each other to allow for
delayed allocation of backing storage.
This RFC attempts to introduce the idea of memory constraints of a device,
and how these constraints can be shared and used to help allocate buffers that
can satisfy requirements of all devices attached to a particular dma-buf.
How:
====
A constraints_mask is added to dma_parms of the device, and at the time of
each device attachment to a dma-buf, the dma-buf uses this constraints_mask
to calculate the access_mask for the dma-buf.
Allocators can be defined for each of these constraints_masks, and then helper
functions can be used to allocate the backing storage from the matching
allocator satisfying the constraints of all devices interested.
A new miscdevice, /dev/cenalloc [1] is created, which acts as the dma-buf
exporter to make this transparent to the devices.
More details in the patch description of "cenalloc: Constraint-Enabled
Allocation helpers for dma-buf".
At present, the constraint_mask is only a bitmask, but it should be possible to
change it to a struct and adapt the constraint_mask calculation accordingly,
based on discussion.
Important requirement:
======================
Of course, delayed allocation can only work if all participating devices
will wait for other devices to have 'attached' before mapping the buffer
for the first time.
As of now, users of dma-buf(drm prime, v4l2 etc) call the attach() and then
map_attachment() almost immediately after it. This would need to be changed if
they were to benefit from constraints.
What 'cenalloc' is not:
=======================
- not 'general' allocator helpers - useful only for constraints-enabled
devices that share buffers with others using dma-buf.
- not a replacement for existing allocation mechanisms inside various
subsystems; merely a possible alternative.
- no page-migration - it would be very complementary to the delayed allocation
suggested here.
TODOs:
======
- demonstration test cases
- vma helpers for allocators
- more sample allocators
- userspace ioctl (It should be a simple one, and we have one ready, but wanted
to agree on the kernel side of things first)
May the brickbats begin, please! :)
Best regards,
~Sumit.
[1]: 'C'onstraints 'EN'abled 'ALLOC'ation helpers = cenalloc: it might not be a
very appealing name, so suggestions are very welcome!
Benjamin Gaignard (1):
cenalloc: a sample allocator for contiguous page allocation
Sumit Semwal (3):
dma-buf: Add constraints sharing information
cenalloc: Constraint-Enabled Allocation helpers for dma-buf
cenalloc: Build files for constraint-enabled allocation helpers
MAINTAINERS | 1 +
drivers/Kconfig | 2 +
drivers/Makefile | 1 +
drivers/cenalloc/Kconfig | 8 +
drivers/cenalloc/Makefile | 3 +
drivers/cenalloc/cenalloc.c | 597 ++++++++++++++++++++++++++++++
drivers/cenalloc/cenalloc.h | 99 +++++
drivers/cenalloc/cenalloc_priv.h | 188 ++++++++++
drivers/cenalloc/cenalloc_system_contig.c | 225 +++++++++++
drivers/dma-buf/dma-buf.c | 50 ++-
include/linux/device.h | 7 +-
include/linux/dma-buf.h | 14 +
12 files changed, 1189 insertions(+), 6 deletions(-)
create mode 100644 drivers/cenalloc/Kconfig
create mode 100644 drivers/cenalloc/Makefile
create mode 100644 drivers/cenalloc/cenalloc.c
create mode 100644 drivers/cenalloc/cenalloc.h
create mode 100644 drivers/cenalloc/cenalloc_priv.h
create mode 100644 drivers/cenalloc/cenalloc_system_contig.c
--
1.9.1
This patchset implements "kiosk" mode for KDB debugger and is a
continuation of previous work by Anton Vorontsov (dating back to late
2012).
When kiosk mode is engaged several kdb commands become disabled leaving
only status reporting functions working normally. In particular arbitrary
memory read/write is prevented and it is no longer possible to alter
program flow.
Note that the commands that remain enabled are sufficient to run the
post-mortem macro commands, dumpcommon, dumpall and dumpcpu. One of the
motivating use-cases for this work is to realize post-mortem on embedded
devices (such as phones) without allowing the debug facility to be easily
exploited to compromise user privacy. In principle this means the feature
can be enabled on production devices.
There are a few patches, some are just cleanups, some are churn-ish
cleanups, but inevitable. And the rest implements the mode -- after all
the preparations, everything is pretty straightforward. The first patch
is actually a pure bug fix (arguably unrelated to kiosk mode) but
collides with the kiosk code to honour the sysrq mask so I have included
it here.
Changes since v1 (circa 2012):
* ef (Display exception frame) is essentially an overly complex peek
and has therefore been marked unsafe
* bt (Stack traceback) has been marked safe only with no arguments
* sr (Magic SysRq key) honours the sysrq mask when called in kiosk
mode
* Fixed over-zealous blocking of macro commands
* Symbol lookup is forbidden by kdbgetaddrarg (more robust, better
error reporting to user)
* Fix deadlock in sr (Magic SysRq key)
* Better help text in kiosk mode
* Default (kiosk on/off) can be changed From the config file.
Anton Vorontsov (7):
kdb: Remove currently unused kdbtab_t->cmd_flags
kdb: Rename kdb_repeat_t to kdb_cmdflags_t, cmd_repeat to cmd_flags
kdb: Rename kdb_register_repeat() to kdb_register_flags()
kdb: Use KDB_REPEAT_* values as flags
kdb: Remove KDB_REPEAT_NONE flag
kdb: Mark safe commands as KDB_SAFE and KDB_SAFE_NO_ARGS
kdb: Add kiosk mode
Daniel Thompson (3):
sysrq: Implement __handle_sysrq_nolock to avoid recursive locking in
kdb
kdb: Improve usability of help text when running in kiosk mode
kdb: Allow access to sensitive commands to be restricted by default
drivers/tty/sysrq.c | 11 ++-
include/linux/kdb.h | 20 ++--
include/linux/sysrq.h | 1 +
kernel/debug/kdb/kdb_bp.c | 22 ++---
kernel/debug/kdb/kdb_main.c | 207 +++++++++++++++++++++++------------------
kernel/debug/kdb/kdb_private.h | 3 +-
kernel/trace/trace_kdb.c | 4 +-
lib/Kconfig.kgdb | 21 +++++
8 files changed, 172 insertions(+), 117 deletions(-)
--
1.9.0
Currently if an active CPU fails to respond to a roundup request the
CPU that requested the roundup will become stuck. This needlessly
reduces the robustness of the debugger.
This patch introduces a timeout allowing the system state to be examined
even when the system contains unresponsive processors. It also modifies
kdb's cpu command to make it censor attempts to switch to unresponsive
processors and to report their state as (D)ead.
Signed-off-by: Daniel Thompson <daniel.thompson(a)linaro.org>
Cc: Jason Wessel <jason.wessel(a)windriver.com>
Cc: Mike Travis <travis(a)sgi.com>
Cc: Randy Dunlap <rdunlap(a)infradead.org>
Cc: Dimitri Sivanich <sivanich(a)sgi.com>
Cc: Andrew Morton <akpm(a)linux-foundation.org>
Cc: Borislav Petkov <bp(a)suse.de>
Cc: kgdb-bugreport(a)lists.sourceforge.net
---
kernel/debug/debug_core.c | 9 +++++++--
kernel/debug/kdb/kdb_main.c | 4 +++-
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index 1adf62b..acd7497 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -471,6 +471,7 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs,
int cpu;
int trace_on = 0;
int online_cpus = num_online_cpus();
+ u64 time_left;
kgdb_info[ks->cpu].enter_kgdb++;
kgdb_info[ks->cpu].exception_state |= exception_state;
@@ -595,9 +596,13 @@ return_normal:
/*
* Wait for the other CPUs to be notified and be waiting for us:
*/
- while (kgdb_do_roundup && (atomic_read(&masters_in_kgdb) +
- atomic_read(&slaves_in_kgdb)) != online_cpus)
+ time_left = loops_per_jiffy * HZ;
+ while (kgdb_do_roundup && --time_left &&
+ (atomic_read(&masters_in_kgdb) + atomic_read(&slaves_in_kgdb)) !=
+ online_cpus)
cpu_relax();
+ if (!time_left)
+ pr_crit("KGDB: Timed out waiting for secondary CPUs.\n");
/*
* At this point the primary processor is completely
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index 2f7c760..49f2425 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -2157,6 +2157,8 @@ static void kdb_cpu_status(void)
for (start_cpu = -1, i = 0; i < NR_CPUS; i++) {
if (!cpu_online(i)) {
state = 'F'; /* cpu is offline */
+ } else if (!kgdb_info[i].enter_kgdb) {
+ state = 'D'; /* cpu is online but unresponsive */
} else {
state = ' '; /* cpu is responding to kdb */
if (kdb_task_state_char(KDB_TSK(i)) == 'I')
@@ -2210,7 +2212,7 @@ static int kdb_cpu(int argc, const char **argv)
/*
* Validate cpunum
*/
- if ((cpunum > NR_CPUS) || !cpu_online(cpunum))
+ if ((cpunum > NR_CPUS) || !kgdb_info[cpunum].enter_kgdb)
return KDB_BADCPUNUM;
dbg_switch_cpu = cpunum;
--
1.9.3
This patchset improves kdb's capabilities to search the output
of commands. Specifically it fixes a bug in the prompt management
when '| grep' is used and adds a new feature to search command
output interactively from the more prompt.
Daniel Thompson (3):
kdb: Fix a prompt management bug when using | grep
kdb: Provide forward search at more prompt
kdb: Const qualifier for kdb_getstr's prompt argument
kernel/debug/kdb/kdb_io.c | 24 +++++++++++++++++++++---
kernel/debug/kdb/kdb_main.c | 11 ++++++-----
kernel/debug/kdb/kdb_private.h | 4 +++-
3 files changed, 30 insertions(+), 9 deletions(-)
--
1.9.3
Issuing a stack dump feels ergonomically wrong when entering due to NMI.
Entering due to NMI is a normally reaction to a user request, either the
NMI button on a server or a "magic knock" on a UART. Therefore the
backtrace behaviour on entry due to NMI should be like SysRq-g (no stack
dump) rather than like oops.
Note also that the stack dump does not offer any information that
cannot be trivial retrieved using the 'bt' command.
Signed-off-by: Daniel Thompson <daniel.thompson(a)linaro.org>
Cc: Jason Wessel <jason.wessel(a)windriver.com>
Cc: Mike Travis <travis(a)sgi.com>
Cc: Ingo Molnar <mingo(a)redhat.com>
Cc: kgdb-bugreport(a)lists.sourceforge.net
---
kernel/debug/kdb/kdb_main.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index 49f2425..6d19905 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -1207,7 +1207,6 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs,
kdb_printf("due to NonMaskable Interrupt @ "
kdb_machreg_fmt "\n",
instruction_pointer(regs));
- kdb_dumpregs(regs);
break;
case KDB_REASON_SSTEP:
case KDB_REASON_BREAK:
--
1.9.3
Currently when kdb traps printk messages then the log level prefix
does not get stripped off before the message is issued to the various
I/O handlers supported by kdb. This results in annoying visual noise
and problems with grepping for ^.
This patch addresses the problem by stripping log levels from messages
before they are issued to the I/O handlers.
printk(), which is used as an I/O handler for logging purposes, is
handled as a special case; if the caller provided a log level then this
will be preserved.
Signed-off-by: Daniel Thompson <daniel.thompson(a)linaro.org>
Cc: Jason Wessel <jason.wessel(a)windriver.com>
Cc: Mike Travis <travis(a)sgi.com>
Cc: Ingo Molnar <mingo(a)redhat.com>
Cc: Andrew Morton <akpm(a)linux-foundation.org>
---
kernel/debug/kdb/kdb_io.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c
index 7c70812..381f297 100644
--- a/kernel/debug/kdb/kdb_io.c
+++ b/kernel/debug/kdb/kdb_io.c
@@ -691,19 +691,22 @@ kdb_printit:
* Write to all consoles.
*/
retlen = strlen(kdb_buffer);
+ cp = kdb_buffer;
+ if (cp[0] == KERN_SOH_ASCII && cp[1] != '\0')
+ cp += 2;
if (!dbg_kdb_mode && kgdb_connected) {
- gdbstub_msg_write(kdb_buffer, retlen);
+ gdbstub_msg_write(cp, retlen - (cp - kdb_buffer));
} else {
if (dbg_io_ops && !dbg_io_ops->is_console) {
- len = retlen;
- cp = kdb_buffer;
+ len = retlen - (cp - kdb_buffer);
+ cp2 = cp;
while (len--) {
- dbg_io_ops->write_char(*cp);
- cp++;
+ dbg_io_ops->write_char(*cp2);
+ cp2++;
}
}
while (c) {
- c->write(c, kdb_buffer, retlen);
+ c->write(c, cp, retlen - (cp - kdb_buffer));
touch_nmi_watchdog();
c = c->next;
}
@@ -711,7 +714,10 @@ kdb_printit:
if (logging) {
saved_loglevel = console_loglevel;
console_loglevel = CONSOLE_LOGLEVEL_SILENT;
- printk(KERN_INFO "%s", kdb_buffer);
+ if (cp == kdb_buffer)
+ printk(KERN_INFO "%s", kdb_buffer);
+ else
+ printk("%s", kdb_buffer);
}
if (KDB_STATE(PAGER)) {
--
1.9.3
I tried to verify kgdb in vanilla kernel on fast model, but it seems that
the single stepping with kgdb doesn't work correctly since its first
appearance at v3.15.
On v3.15, 'stepi' command after breaking the kernel at some breakpoint
steps forward to the next instruction, but the succeeding 'stepi' never
goes beyond that.
On v3.16, 'stepi' moves forward and stops at the next instruction just
after enable_dbg in el1_dbg, and never goes beyond that. This variance of
behavior seems to come in with the following patch in v3.16:
commit 2a2830703a23 ("arm64: debug: avoid accessing mdscr_el1 on fault
paths where possible")
This patch
(1) moves kgdb_disable_single_step() from 'c' command handling to single
step handler.
This makes sure that single stepping gets effective at every 's' command.
Please note that, under the current implementation, single step bit in
spsr, which is cleared by the first single stepping, will not be set
again for the consecutive 's' commands because single step bit in mdscr
is still kept on (that is, kernel_active_single_step() in
kgdb_arch_handle_exception() is true).
(2) re-implements kgdb_roundup_cpus() because the current implementation
enabled interrupts naively. See below.
(3) removes 'enable_dbg' in el1_dbg.
Single step bit in mdscr is turned on in do_handle_exception()->
kgdb_handle_expection() before returning to debugged context, and if
debug exception is enabled in el1_dbg, we will see unexpected single-
stepping in el1_dbg.
Since v3.18, the following patch does the same:
commit 1059c6bf8534 ("arm64: debug: don't re-enable debug exceptions
on return from el1_dbg)
(4) masks interrupts while single-stepping one instruction.
If an interrupt is caught during processing a single-stepping, debug
exception is unintentionally enabled by el1_irq's 'enable_dbg' before
returning to debugged context.
Thus, like in (2), we will see unexpected single-stepping in el1_irq.
Basically (1) and (2) are for v3.15, (3) and (4) for v3.1[67].
* issue fixed by (2):
Without (2), we would see another problem if a breakpoint is set at
interrupt-sensible places, like gic_handle_irq():
KGDB: re-enter error: breakpoint removed ffffffc000081258
------------[ cut here ]------------
WARNING: CPU: 0 PID: 650 at kernel/debug/debug_core.c:435
kgdb_handle_exception+0x1dc/0x1f4()
Modules linked in:
CPU: 0 PID: 650 Comm: sh Not tainted 3.17.0-rc2+ #177
Call trace:
[<ffffffc000087fac>] dump_backtrace+0x0/0x130
[<ffffffc0000880ec>] show_stack+0x10/0x1c
[<ffffffc0004d683c>] dump_stack+0x74/0xb8
[<ffffffc0000ab824>] warn_slowpath_common+0x8c/0xb4
[<ffffffc0000ab90c>] warn_slowpath_null+0x14/0x20
[<ffffffc000121bfc>] kgdb_handle_exception+0x1d8/0x1f4
[<ffffffc000092ffc>] kgdb_brk_fn+0x18/0x28
[<ffffffc0000821c8>] brk_handler+0x9c/0xe8
[<ffffffc0000811e8>] do_debug_exception+0x3c/0xac
Exception stack(0xffffffc07e027650 to 0xffffffc07e027770)
...
[<ffffffc000083cac>] el1_dbg+0x14/0x68
[<ffffffc00012178c>] kgdb_cpu_enter+0x464/0x5c0
[<ffffffc000121bb4>] kgdb_handle_exception+0x190/0x1f4
[<ffffffc000092ffc>] kgdb_brk_fn+0x18/0x28
[<ffffffc0000821c8>] brk_handler+0x9c/0xe8
[<ffffffc0000811e8>] do_debug_exception+0x3c/0xac
Exception stack(0xffffffc07e027ac0 to 0xffffffc07e027be0)
...
[<ffffffc000083cac>] el1_dbg+0x14/0x68
[<ffffffc00032e4b4>] __handle_sysrq+0x11c/0x190
[<ffffffc00032e93c>] write_sysrq_trigger+0x4c/0x60
[<ffffffc0001e7d58>] proc_reg_write+0x54/0x84
[<ffffffc000192fa4>] vfs_write+0x98/0x1c8
[<ffffffc0001939b0>] SyS_write+0x40/0xa0
Once some interrupt occurs, a breakpoint at gic_handle_irq() triggers kgdb.
Kgdb then calls kgdb_roundup_cpus() to sync with other cpus.
Current kgdb_roundup_cpus() unmasks interrupts temporarily to
use smp_call_function().
This eventually allows another interrupt to occur and likely results in
hitting a breakpoint at gic_handle_irq() again since debug exception is
always enabled in el1_irq.
We can avoid this issue by specifying "nokgdbroundup" in kernel parameter,
but this will also leave other cpus be in unknown state in terms of kgdb,
and may result in interfering with kgdb activity.
Signed-off-by: AKASHI Takahiro <takahiro.akashi(a)linaro.org>
---
arch/arm64/kernel/kgdb.c | 60 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 46 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c
index a0d10c5..81b5910 100644
--- a/arch/arm64/kernel/kgdb.c
+++ b/arch/arm64/kernel/kgdb.c
@@ -19,9 +19,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/cpumask.h>
#include <linux/irq.h>
+#include <linux/irq_work.h>
#include <linux/kdebug.h>
#include <linux/kgdb.h>
+#include <linux/percpu.h>
+#include <asm/ptrace.h>
#include <asm/traps.h>
struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
@@ -95,6 +99,9 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
{ "fpcr", 4, -1 },
};
+static DEFINE_PER_CPU(unsigned int, kgdb_pstate);
+static DEFINE_PER_CPU(struct irq_work, kgdb_irq_work);
+
char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
{
if (regno >= DBG_MAX_REG_NUM || regno < 0)
@@ -176,18 +183,14 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
* over and over again.
*/
kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
- atomic_set(&kgdb_cpu_doing_single_step, -1);
- kgdb_single_step = 0;
-
- /*
- * Received continue command, disable single step
- */
- if (kernel_active_single_step())
- kernel_disable_single_step();
err = 0;
break;
case 's':
+ /* mask interrupts while single stepping */
+ __this_cpu_write(kgdb_pstate, linux_regs->pstate);
+ linux_regs->pstate |= PSR_I_BIT;
+
/*
* Update step address value with address passed
* with step packet.
@@ -198,8 +201,6 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
*/
kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
atomic_set(&kgdb_cpu_doing_single_step, raw_smp_processor_id());
- kgdb_single_step = 1;
-
/*
* Enable single step handling
*/
@@ -229,6 +230,18 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr)
static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr)
{
+ unsigned int pstate;
+
+ kernel_disable_single_step();
+ atomic_set(&kgdb_cpu_doing_single_step, -1);
+
+ /* restore interrupt mask status */
+ pstate = __this_cpu_read(kgdb_pstate);
+ if (pstate & PSR_I_BIT)
+ regs->pstate |= PSR_I_BIT;
+ else
+ regs->pstate &= ~PSR_I_BIT;
+
kgdb_handle_exception(1, SIGTRAP, 0, regs);
return 0;
}
@@ -249,16 +262,27 @@ static struct step_hook kgdb_step_hook = {
.fn = kgdb_step_brk_fn
};
-static void kgdb_call_nmi_hook(void *ignored)
+static void kgdb_roundup_hook(struct irq_work *work)
{
kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
}
void kgdb_roundup_cpus(unsigned long flags)
{
- local_irq_enable();
- smp_call_function(kgdb_call_nmi_hook, NULL, 0);
- local_irq_disable();
+ int cpu;
+ struct cpumask mask;
+ struct irq_work *work;
+
+ mask = *cpu_online_mask;
+ cpumask_clear_cpu(smp_processor_id(), &mask);
+ cpu = cpumask_first(&mask);
+ if (cpu >= nr_cpu_ids)
+ return;
+
+ for_each_cpu(cpu, &mask) {
+ work = per_cpu_ptr(&kgdb_irq_work, cpu);
+ irq_work_queue_on(work, cpu);
+ }
}
static int __kgdb_notify(struct die_args *args, unsigned long cmd)
@@ -299,6 +323,8 @@ static struct notifier_block kgdb_notifier = {
int kgdb_arch_init(void)
{
int ret = register_die_notifier(&kgdb_notifier);
+ int cpu;
+ struct irq_work *work;
if (ret != 0)
return ret;
@@ -306,6 +332,12 @@ int kgdb_arch_init(void)
register_break_hook(&kgdb_brkpt_hook);
register_break_hook(&kgdb_compiled_brkpt_hook);
register_step_hook(&kgdb_step_hook);
+
+ for_each_possible_cpu(cpu) {
+ work = per_cpu_ptr(&kgdb_irq_work, cpu);
+ init_irq_work(work, kgdb_roundup_hook);
+ }
+
return 0;
}
--
1.7.9.5
If the overflow threshold for a counter is set above or near the
0xffffffff boundary then the kernel may lose track of the overflow
causing only events that occur *after* the overflow to be recorded.
Specifically the problem occurs when the value of the performance counter
overtakes its original programmed value due to wrap around.
Typical solutions to this problem are either to avoid programming in
values likely to be overtaken or to treat the overflow bit as the 33rd
bit of the counter.
Its somewhat fiddly to refactor the code to correctly handle the 33rd bit
during irqsave sections (context switches for example) so instead we take
the simpler approach of avoiding values likely to be overtaken.
We set the limit to half of max_period because this matches the limit
imposed in __hw_perf_event_init(). This causes a doubling of the interrupt
rate for large threshold values, however even with a very fast counter
ticking at 4GHz the interrupt rate would only be ~1Hz.
Signed-off-by: Daniel Thompson <daniel.thompson(a)linaro.org>
---
Notes:
There is similar code in the arm64 tree which retains the assumptions of
the original arm code regarding 32-bit wide performance counters. If
this patch doesn't get beaten up during review I'll also share a similar
patch for arm64.
arch/arm/kernel/perf_event.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 266cba46db3e..b50a770f8c99 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -115,8 +115,14 @@ int armpmu_event_set_period(struct perf_event *event)
ret = 1;
}
- if (left > (s64)armpmu->max_period)
- left = armpmu->max_period;
+ /*
+ * Limit the maximum period to prevent the counter value
+ * from overtaking the one we are about to program. In
+ * effect we are reducing max_period to account for
+ * interrupt latency (and we are being very conservative).
+ */
+ if (left > (s64)(armpmu->max_period >> 1))
+ left = armpmu->max_period >> 1;
local64_set(&hwc->prev_count, (u64)-left);
--
1.9.3