From: Robert Richter <robert.richter@amd.com>
To: Dave Jones <davej@redhat.com>,
Linux Kernel <linux-kernel@vger.kernel.org>
Subject: Re: sleeping while atomic warning while modprobing oprofile.
Date: Mon, 23 May 2011 19:01:36 +0200 [thread overview]
Message-ID: <20110523170136.GO20052@erda.amd.com> (raw)
In-Reply-To: <20110520034724.GA20052@erda.amd.com>
On 20.05.11 05:47:24, Robert Richter wrote:
> On 18.05.11 15:17:06, Dave Jones wrote:
> > I just saw this when after I did a 'modprobe oprofile' on my amd64 box.
>
> Thanks for reporting this. This happens in init_ibs(). We are actually
> too strict here with disabling preemption, though we still need it.
> Will change that code.
>
> -Robert
>
> >
> > Dave
> >
> > BUG: sleeping function called from invalid context at mm/slub.c:824
> > in_atomic(): 1, irqs_disabled(): 0, pid: 32357, name: modprobe
> > INFO: lockdep is turned off.
> > Pid: 32357, comm: modprobe Not tainted 2.6.39-rc7+ #14
> > Call Trace:
> > [<ffffffff8104bdc8>] __might_sleep+0x112/0x117
> > [<ffffffff81129693>] kmem_cache_alloc_trace+0x4b/0xe7
> > [<ffffffff81278f14>] kzalloc.constprop.0+0x29/0x2b
> > [<ffffffff81278f4c>] pci_get_subsys+0x36/0x78
> > [<ffffffff81022689>] ? setup_APIC_eilvt+0xfb/0x139
> > [<ffffffff81278fa4>] pci_get_device+0x16/0x18
> > [<ffffffffa06c8b5d>] op_amd_init+0xd3/0x211 [oprofile]
> > [<ffffffffa064d000>] ? 0xffffffffa064cfff
> > [<ffffffffa064d298>] op_nmi_init+0x21e/0x26a [oprofile]
> > [<ffffffffa064d062>] oprofile_arch_init+0xe/0x26 [oprofile]
> > [<ffffffffa064d010>] oprofile_init+0x10/0x42 [oprofile]
> > [<ffffffff81002099>] do_one_initcall+0x7f/0x13a
> > [<ffffffff81096524>] sys_init_module+0x132/0x281
> > [<ffffffff814cc682>] system_call_fastpath+0x16/0x1b
Dave,
the patch below should fix this.
-Robert
>From 3d2606f42984613d324ad3047cf503bcddc3880a Mon Sep 17 00:00:00 2001
From: Robert Richter <robert.richter@amd.com>
Date: Fri, 20 May 2011 09:46:54 +0200
Subject: [PATCH] oprofile, x86: Enable preemption during pci device setup in
IBS init
IBS initialization is a mix of per-core register access and per-node
pci device setup. Register access should be pinned to the cpu, but pci
setup must run with preemption enabled.
This patch better separates the code into non-/preemptible sections
and fixes sleeping with preemption disabled. See bug message below.
Fixes also freeing the eilvt entry by introducing put_eilvt().
BUG: sleeping function called from invalid context at mm/slub.c:824
in_atomic(): 1, irqs_disabled(): 0, pid: 32357, name: modprobe
INFO: lockdep is turned off.
Pid: 32357, comm: modprobe Not tainted 2.6.39-rc7+ #14
Call Trace:
[<ffffffff8104bdc8>] __might_sleep+0x112/0x117
[<ffffffff81129693>] kmem_cache_alloc_trace+0x4b/0xe7
[<ffffffff81278f14>] kzalloc.constprop.0+0x29/0x2b
[<ffffffff81278f4c>] pci_get_subsys+0x36/0x78
[<ffffffff81022689>] ? setup_APIC_eilvt+0xfb/0x139
[<ffffffff81278fa4>] pci_get_device+0x16/0x18
[<ffffffffa06c8b5d>] op_amd_init+0xd3/0x211 [oprofile]
[<ffffffffa064d000>] ? 0xffffffffa064cfff
[<ffffffffa064d298>] op_nmi_init+0x21e/0x26a [oprofile]
[<ffffffffa064d062>] oprofile_arch_init+0xe/0x26 [oprofile]
[<ffffffffa064d010>] oprofile_init+0x10/0x42 [oprofile]
[<ffffffff81002099>] do_one_initcall+0x7f/0x13a
[<ffffffff81096524>] sys_init_module+0x132/0x281
[<ffffffff814cc682>] system_call_fastpath+0x16/0x1b
Reported-by: Dave Jones <davej@redhat.com>
Cc: <stable@kernel.org> [2.6.37.x]
Signed-off-by: Robert Richter <robert.richter@amd.com>
---
arch/x86/oprofile/op_model_amd.c | 95 +++++++++++++++++++++----------------
1 files changed, 54 insertions(+), 41 deletions(-)
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
index c3b8e24..9fd8a56 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -316,16 +316,23 @@ static void op_amd_stop_ibs(void)
wrmsrl(MSR_AMD64_IBSOPCTL, 0);
}
-static inline int eilvt_is_available(int offset)
+static inline int get_eilvt(int offset)
{
- /* check if we may assign a vector */
return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1);
}
+static inline int put_eilvt(int offset)
+{
+ return !setup_APIC_eilvt(offset, 0, 0, 1);
+}
+
static inline int ibs_eilvt_valid(void)
{
int offset;
u64 val;
+ int valid = 0;
+
+ preempt_disable();
rdmsrl(MSR_AMD64_IBSCTL, val);
offset = val & IBSCTL_LVT_OFFSET_MASK;
@@ -333,16 +340,20 @@ static inline int ibs_eilvt_valid(void)
if (!(val & IBSCTL_LVT_OFFSET_VALID)) {
pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n",
smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
- return 0;
+ goto out;
}
- if (!eilvt_is_available(offset)) {
+ if (!get_eilvt(offset)) {
pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n",
smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
- return 0;
+ goto out;
}
- return 1;
+ valid = 1;
+out:
+ preempt_enable();
+
+ return valid;
}
static inline int get_ibs_offset(void)
@@ -600,67 +611,69 @@ static int setup_ibs_ctl(int ibs_eilvt_off)
static int force_ibs_eilvt_setup(void)
{
- int i;
+ int offset;
int ret;
- /* find the next free available EILVT entry */
- for (i = 1; i < 4; i++) {
- if (!eilvt_is_available(i))
- continue;
- ret = setup_ibs_ctl(i);
- if (ret)
- return ret;
- pr_err(FW_BUG "using offset %d for IBS interrupts\n", i);
- return 0;
+ /*
+ * find the next free available EILVT entry, skip offset 0,
+ * pin search to this cpu
+ */
+ preempt_disable();
+ for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) {
+ if (get_eilvt(offset))
+ break;
}
+ preempt_enable();
- printk(KERN_DEBUG "No EILVT entry available\n");
-
- return -EBUSY;
-}
-
-static int __init_ibs_nmi(void)
-{
- int ret;
-
- if (ibs_eilvt_valid())
- return 0;
+ if (offset == APIC_EILVT_NR_MAX) {
+ printk(KERN_DEBUG "No EILVT entry available\n");
+ return -EBUSY;
+ }
- ret = force_ibs_eilvt_setup();
+ ret = setup_ibs_ctl(offset);
if (ret)
- return ret;
+ goto out;
- if (!ibs_eilvt_valid())
- return -EFAULT;
+ if (!ibs_eilvt_valid()) {
+ ret = -EFAULT;
+ goto out;
+ }
+ pr_err(FW_BUG "using offset %d for IBS interrupts\n", offset);
pr_err(FW_BUG "workaround enabled for IBS LVT offset\n");
return 0;
+out:
+ preempt_disable();
+ put_eilvt(offset);
+ preempt_enable();
+ return ret;
}
/*
* check and reserve APIC extended interrupt LVT offset for IBS if
* available
- *
- * init_ibs() preforms implicitly cpu-local operations, so pin this
- * thread to its current CPU
*/
static void init_ibs(void)
{
- preempt_disable();
-
ibs_caps = get_ibs_caps();
+
if (!ibs_caps)
+ return;
+
+ if (ibs_eilvt_valid())
goto out;
- if (__init_ibs_nmi() < 0)
- ibs_caps = 0;
- else
- printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps);
+ if (!force_ibs_eilvt_setup())
+ goto out;
+
+ /* Failed to setup ibs */
+ ibs_caps = 0;
+ return;
out:
- preempt_enable();
+ printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps);
}
static int (*create_arch_files)(struct super_block *sb, struct dentry *root);
--
1.7.5.rc3
--
Advanced Micro Devices, Inc.
Operating System Research Center
next prev parent reply other threads:[~2011-05-23 17:01 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-18 19:17 sleeping while atomic warning while modprobing oprofile Dave Jones
2011-05-20 3:47 ` Robert Richter
2011-05-23 17:01 ` Robert Richter [this message]
2011-05-23 17:03 ` [PATCH] oprofile, x86: Enable preemption during pci device setup in IBS init Robert Richter
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=20110523170136.GO20052@erda.amd.com \
--to=robert.richter@amd.com \
--cc=davej@redhat.com \
--cc=linux-kernel@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.