On 01/19/2011 09:11 PM, [email protected] wrote:
Hi,
From: ext Yang Ruirui [mailto:[email protected]]
Sent: 19 January, 2011 11:07
following bug happens with n900 2.6.35 kernel:
[ 28.693756] BUG: sleeping function called from invalid context at
kernel/rwsem.c:21
[ 28.693786] in_atomic(): 1, irqs_disabled(): 128, pid: 706, name:
udisks-part-id
[ 28.693817] 1 lock held by udisks-part-id/706:
[ 28.693817] #0: (&(&musb->lock)->rlock){-.-...}, at: [<c0278590>]
<snip>
Actually the blocking notifier chain runs in process context, so not fit
for use here.
Fix it as use atomic_notifier instead.
Signed-off-by: Yang Ruirui<[email protected]>
---
drivers/usb/musb/musb_gadget.c | 2 +-
drivers/usb/otg/twl4030-usb.c | 4 ++--
include/linux/usb/otg.h | 6 +++---
3 files changed, 6 insertions(+), 6 deletions(-)
I remember that this solution was discussed on linux-kernel
mailing list previously. I cannot recall now what the end
result was, but at least in order this to be appropriate
patch, it should change the other usb transceiver drivers
as well.
As this patch is likely to fix the issue on n900 I probably take
it as temporary solution until I'll update the kernel to 2.6.37,
which doesn't have this issue.
Hi,
Thanks ilkka.
I have sent a similar patch to lkml about this issue.
In mainline kernel, no caller in interrupt currently,
but it is a potential problem as well.
Thanks, Ilkka
--- linux-2.6.35.orig/drivers/usb/otg/twl4030-usb.c 2010-08-02
06:11:14.000000000 +0800
+++ linux-2.6.35/drivers/usb/otg/twl4030-usb.c 2011-01-19
16:50:44.729545246 +0800
@@ -494,7 +494,7 @@ static irqreturn_t twl4030_usb_irq(int i
else
twl4030_phy_resume(twl);
- blocking_notifier_call_chain(&twl->otg.notifier, status,
+ atomic_notifier_call_chain(&twl->otg.notifier, status,
twl->otg.gadget);
}
sysfs_notify(&twl->dev->kobj, NULL, "vbus");
@@ -585,7 +585,7 @@ static int __devinit twl4030_usb_probe(s
if (device_create_file(&pdev->dev,&dev_attr_vbus))
dev_warn(&pdev->dev, "could not create sysfs file\n");
- BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier);
+ ATOMIC_INIT_NOTIFIER_HEAD(&twl->otg.notifier);
/* Our job is to use irqs and status from the power module
* to keep the transceiver disabled when nothing's connected.
--- linux-2.6.35.orig/include/linux/usb/otg.h 2011-01-19
11:11:42.000000000 +0800
+++ linux-2.6.35/include/linux/usb/otg.h 2011-01-19 16:45:06.729546023
+0800
@@ -81,7 +81,7 @@ struct otg_transceiver {
void __iomem *io_priv;
/* for notification of usb_xceiv_events */
- struct blocking_notifier_head notifier;
+ struct atomic_notifier_head notifier;
/* to pass extra port status to the root hub */
u16 port_status;
@@ -241,13 +241,13 @@ otg_detect_charger(struct otg_transceive
static inline int
otg_register_notifier(struct otg_transceiver *otg, struct
notifier_block *nb)
{
- return blocking_notifier_chain_register(&otg->notifier, nb);
+ return atomic_notifier_chain_register(&otg->notifier, nb);
}
static inline void
otg_unregister_notifier(struct otg_transceiver *otg, struct
notifier_block *nb)
{
- blocking_notifier_chain_unregister(&otg->notifier, nb);
+ atomic_notifier_chain_unregister(&otg->notifier, nb);
}
/* for OTG controller drivers (and maybe other stuff) */
--- linux-2.6.35.orig/drivers/usb/musb/musb_gadget.c 2011-01-19
16:42:48.000000000 +0800
+++ linux-2.6.35/drivers/usb/musb/musb_gadget.c 2011-01-19
16:46:41.096212474 +0800
@@ -1537,7 +1537,7 @@ static int musb_gadget_vbus_draw(struct
if (musb->power_draw != mA&& mA> 0) {
musb->power_draw = mA;
- blocking_notifier_call_chain(&musb->xceiv->notifier,
+ atomic_notifier_call_chain(&musb->xceiv->notifier,
USB_EVENT_ENUMERATED,
&musb->power_draw);
}
--
Thanks
Yang Ruirui
_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel