From: Jason Wessel <jason.wessel@windriver.com>
To: linux-kernel@vger.kernel.org
Cc: kgdb-bugreport@lists.sourceforge.net, mingo@elte.hu,
Jason Wessel <jason.wessel@windriver.com>,
Frederic Weisbecker <fweisbec@gmail.com>,
"K.Prasad" <prasad@linux.vnet.ibm.com>,
Peter Zijlstra <peterz@infradead.org>,
Alan Stern <stern@rowland.harvard.edu>
Subject: [PATCH 2/4] perf,hw_breakpoint: add lockless reservation for hw_breaks
Date: Mon, 25 Jan 2010 22:26:38 -0600 [thread overview]
Message-ID: <1264480000-6997-3-git-send-email-jason.wessel@windriver.com> (raw)
In-Reply-To: <1264480000-6997-1-git-send-email-jason.wessel@windriver.com>
The kernel debugger cannot take any locks at the risk of deadlocking
the system. This patch implements a simple reservation system using
an atomic variable initialized to the maximum number of system wide
breakpoints. Any time the variable is negative, there are no
remaining unreserved hw breakpoint slots.
The perf hw breakpoint API needs to keep the account correct for the
number of system wide breakpoints available at any given time. The
kernel debugger will use the same reservation semantics, but use the
low level API calls to install and remove breakpoints while general
kernel execution is paused.
CC: Frederic Weisbecker <fweisbec@gmail.com>
CC: Ingo Molnar <mingo@elte.hu>
CC: K.Prasad <prasad@linux.vnet.ibm.com>
CC: Peter Zijlstra <peterz@infradead.org>
CC: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
---
arch/x86/kernel/kgdb.c | 12 +++++++++---
include/linux/perf_event.h | 1 +
kernel/hw_breakpoint.c | 16 ++++++++++++++++
3 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index 3cb2828..2a31f35 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -251,6 +251,7 @@ kgdb_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype bptype)
return -1;
breakinfo[i].enabled = 0;
+ atomic_inc(&dbg_slots_pinned);
return 0;
}
@@ -277,11 +278,13 @@ kgdb_set_hw_break(unsigned long addr, int len, enum kgdb_bptype bptype)
{
int i;
+ if (atomic_add_negative(-1, &dbg_slots_pinned))
+ goto err_out;
for (i = 0; i < 4; i++)
if (!breakinfo[i].enabled)
break;
if (i == 4)
- return -1;
+ goto err_out;
switch (bptype) {
case BP_HARDWARE_BREAKPOINT:
@@ -295,7 +298,7 @@ kgdb_set_hw_break(unsigned long addr, int len, enum kgdb_bptype bptype)
breakinfo[i].type = X86_BREAKPOINT_RW;
break;
default:
- return -1;
+ goto err_out;
}
switch (len) {
case 1:
@@ -313,12 +316,15 @@ kgdb_set_hw_break(unsigned long addr, int len, enum kgdb_bptype bptype)
break;
#endif
default:
- return -1;
+ goto err_out;
}
breakinfo[i].addr = addr;
breakinfo[i].enabled = 1;
return 0;
+err_out:
+ atomic_inc(&dbg_slots_pinned);
+ return -1;
}
/**
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 8fa7187..71f3f05 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -825,6 +825,7 @@ static inline int is_software_event(struct perf_event *event)
}
extern atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX];
+extern atomic_t dbg_slots_pinned;
extern void __perf_sw_event(u32, u64, int, struct pt_regs *, u64);
diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c
index 50dbd59..ddf7951 100644
--- a/kernel/hw_breakpoint.c
+++ b/kernel/hw_breakpoint.c
@@ -55,6 +55,9 @@ static DEFINE_PER_CPU(unsigned int, nr_cpu_bp_pinned);
/* Number of pinned task breakpoints in a cpu */
static DEFINE_PER_CPU(unsigned int, nr_task_bp_pinned[HBP_NUM]);
+/* Slots pinned atomically by the debugger */
+atomic_t dbg_slots_pinned = ATOMIC_INIT(HBP_NUM);
+
/* Number of non-pinned cpu/task breakpoints in a cpu */
static DEFINE_PER_CPU(unsigned int, nr_bp_flexible);
@@ -249,12 +252,24 @@ int reserve_bp_slot(struct perf_event *bp)
int ret = 0;
mutex_lock(&nr_bp_mutex);
+ /*
+ * Grab a dbg_slots_pinned allocation. This atomic variable
+ * allows lockless sharing between the kernel debugger and the
+ * perf hw breakpoints. It represents the total number of
+ * available system wide breakpoints.
+ */
+ if (atomic_add_negative(-1, &dbg_slots_pinned)) {
+ atomic_inc(&dbg_slots_pinned);
+ ret = -ENOSPC;
+ goto end;
+ }
fetch_bp_busy_slots(&slots, bp);
/* Flexible counters need to keep at least one slot */
if (slots.pinned + (!!slots.flexible) == HBP_NUM) {
ret = -ENOSPC;
+ atomic_inc(&dbg_slots_pinned);
goto end;
}
@@ -271,6 +286,7 @@ void release_bp_slot(struct perf_event *bp)
mutex_lock(&nr_bp_mutex);
toggle_bp_slot(bp, false);
+ atomic_inc(&dbg_slots_pinned);
mutex_unlock(&nr_bp_mutex);
}
--
1.6.3.3
next prev parent reply other threads:[~2010-01-26 4:28 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-26 4:26 [PATCH 0/4] kgdb regression fixes for 2.6.33 Jason Wessel
2010-01-26 4:26 ` [PATCH 1/4] x86,hw_breakpoint,kgdb: kgdb to use hw_breakpoint API Jason Wessel
2010-01-28 17:10 ` Frederic Weisbecker
2010-01-28 17:44 ` [PATCH 1/4] x86,hw_breakpoint,kgdb: kgdb to use hw_breakpointAPI Jason Wessel
2010-01-28 19:58 ` Jason Wessel
2010-01-28 20:17 ` Frederic Weisbecker
2010-01-28 20:23 ` [PATCH 1/4] x86,hw_breakpoint,kgdb: kgdb to usehw_breakpointAPI Jason Wessel
2010-01-28 21:54 ` Frederic Weisbecker
2010-01-28 20:04 ` [PATCH 1/4] x86,hw_breakpoint,kgdb: kgdb to use hw_breakpointAPI Frederic Weisbecker
2010-01-28 20:27 ` [PATCH 1/4] x86,hw_breakpoint,kgdb: kgdb to usehw_breakpointAPI Jason Wessel
2010-01-28 21:50 ` Frederic Weisbecker
2010-01-26 4:26 ` Jason Wessel [this message]
2010-01-26 19:25 ` [PATCH 2/4] perf,hw_breakpoint: add lockless reservation for hw_breaks Jason Wessel
2010-01-27 17:56 ` Frederic Weisbecker
2010-01-27 22:29 ` [PATCH 2/4] perf,hw_breakpoint: add lockless reservation forhw_breaks Jason Wessel
2010-01-26 4:26 ` [PATCH 3/4] kgdb,clocksource: Prevent kernel hang in kernel debugger Jason Wessel
2010-01-26 4:37 ` Andrew Morton
2010-01-26 8:22 ` Martin Schwidefsky
2010-01-26 8:50 ` Thomas Gleixner
2010-01-26 10:01 ` Dongdong Deng
2010-01-26 10:19 ` Xiaotian Feng
2010-01-26 10:37 ` Thomas Gleixner
2010-01-26 11:16 ` Thomas Gleixner
2010-01-26 8:45 ` Thomas Gleixner
2010-01-26 10:43 ` Thomas Gleixner
2010-01-26 14:09 ` [tip:timers/urgent] clocksource: Prevent potential kgdb dead lock tip-bot for Thomas Gleixner
2010-01-26 20:14 ` Andrew Morton
2010-01-26 20:46 ` Jason Wessel
2010-01-26 4:26 ` [PATCH 4/4] softlockup: add sched_clock_tick() to avoid kernel warning on kgdb resume Jason Wessel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1264480000-6997-3-git-send-email-jason.wessel@windriver.com \
--to=jason.wessel@windriver.com \
--cc=fweisbec@gmail.com \
--cc=kgdb-bugreport@lists.sourceforge.net \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=peterz@infradead.org \
--cc=prasad@linux.vnet.ibm.com \
--cc=stern@rowland.harvard.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®