Re: [RFC] usb: musb: Fix oops on module unload

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello.

On 24-09-2010 13:31, Jon Povey wrote:

This more-or-less reverts
"musb_core: don't call musb_platform_exit() twice"

   NAK. You can't just revert this patch -- it fixed an existing issue.

commit 461972d8a4c94bc44f11a13046041c78a7cf18dd

Hm, ironically I was preparing the patch to address the same problem and was going to post it today. :-)

to fix an Oops on module unload:

Unable to handle kernel NULL pointer dereference at virtual address 0000002a
pgd = c6898000
[0000002a] *pgd=86810031, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1] PREEMPT
last sysfs file: /sys/devices/virtual/gpio/gpio77/value
Modules linked in: musb_hdrc(-) techwell mcpcan dm355spi wm8985 penta fpanel
mcp4725 [last unloaded: g_serial]
CPU: 0    Tainted: G        W    (2.6.36-rc4+ #40)
PC is at kobject_put+0x18/0x60
LR is at put_device+0x1c/0x20
pc : [<c0156f9c>]    lr : [<c018a5ec>]    psr: 20000013
sp : c680fe28  ip : c680fe48  fp : c680fe44
r10: 400a2000  r9 : c680e000  r8 : c0027084
r7 : fec64000  r6 : c03671d8  r5 : c6ed8100  r4 : 0000000a
r3 : c68741e0  r2 : c680fe00  r1 : c680fdd0  r0 : 0000000a
Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 0005317f  Table: 86898000  DAC: 00000015
Process rmmod (pid: 1055, stack limit = 0xc680e270)
Stack: (0xc680fe28 to 0xc6810000)
fe20:                   c03671d8 fec64000 c680fe54 c6862800 c680fe54 c680fe48
fe40: c018a5ec c0156f94 c680fe6c c680fe58 bf1238dc c018a5e0 00000000 c6ed8100
fe60: c680fe8c c680fe70 bf12dd60 bf12386c c03671e0 bf131038 c0367214 bf131038
fe80: c680fe9c c680fe90 c018ee60 bf12dd04 c680feb4 c680fea0 c018da5c c018ee50
fea0: c03671e0 c680e000 c680fed4 c680feb8 c018db64 c018d9dc bf131038 bf131038
fec0: c0376978 c680ff3c c680fef4 c680fed8 c018ccf0 c018dab8 00000000 bf131038
fee0: 00000000 c680ff3c c680ff14 c680fef8 c018e15c c018cc68 00000000 bf1310c0
ff00: 00000880 c680ff3c c680ff24 c680ff18 c018f0c4 c018e104 c680ff34 c680ff28
ff20: bf12dcec c018f0c0 c680ffa4 c680ff38 c006bab0 bf12dce8 00000000 6273756d
ff40: 7264685f 400a0063 00000005 400a201c c680ff6c c680ff60 c005964c c015b04c
ff60: c680ffa4 c680ff70 c008ec78 c005964c 08100875 00034024 bf1310c0 00000880
ff80: c680ff84 00000000 00014294 6273756d 7264685f 00000081 00000000 c680ffa8
ffa0: c0026f00 c006b8d0 00014294 6273756d be89bb80 00000880 00000000 00000004
ffc0: 00014294 6273756d 7264685f 00000081 00000068 00000000 400a2000 00000000
ffe0: be89bb78 be89bb68 00014018 40165740 60000010 be89bb80 00000000 00000000
Backtrace:
[<c0156f84>] (kobject_put+0x0/0x60) from [<c018a5ec>] (put_device+0x1c/0x20)
  r4:c6862800
[<c018a5d0>] (put_device+0x0/0x20) from [<bf1238dc>] (musb_free+0x80/0x90 [musb_hdrc])
[<bf12385c>] (musb_free+0x0/0x90 [musb_hdrc]) from [<bf12dd60>] (musb_remove+0x6c/0xa4 [musb_hdrc])
  r5:c6ed8100 r4:00000000
[<bf12dcf4>] (musb_remove+0x0/0xa4 [musb_hdrc]) from [<c018ee60>] (platform_drv_remove+0x20/0x24)
  r7:bf131038 r6:c0367214 r5:bf131038 r4:c03671e0
[<c018ee40>] (platform_drv_remove+0x0/0x24) from [<c018da5c>] (__device_release_driver+0x90/0xdc)
[<c018d9cc>] (__device_release_driver+0x0/0xdc) from [<c018db64>] (driver_detach+0xbc/0xe4)
  r5:c680e000 r4:c03671e0
[<c018daa8>] (driver_detach+0x0/0xe4) from [<c018ccf0>] (bus_remove_driver+0x98/0xc0)
  r7:c680ff3c r6:c0376978 r5:bf131038 r4:bf131038
[<c018cc58>] (bus_remove_driver+0x0/0xc0) from [<c018e15c>] (driver_unregister+0x68/0x78)
  r7:c680ff3c r6:00000000 r5:bf131038 r4:00000000
[<c018e0f4>] (driver_unregister+0x0/0x78) from [<c018f0c4>] (platform_driver_unregister+0x14/0x18)
  r7:c680ff3c r6:00000880 r5:bf1310c0 r4:00000000
[<c018f0b0>] (platform_driver_unregister+0x0/0x18) from [<bf12dcec>] (musb_cleanup+0x14/0x1c [musb_hdrc])
[<bf12dcd8>] (musb_cleanup+0x0/0x1c [musb_hdrc]) from [<c006bab0>] (sys_delete_module+0x1f0/0x264)
[<c006b8c0>] (sys_delete_module+0x0/0x264) from [<c0026f00>] (ret_fast_syscall+0x0/0x2c)
  r7:00000081 r6:7264685f r5:6273756d r4:00014294
Code: e24cb004 e24dd00c e2504000 0a00000b (e5d43020)
ttyS2: 2 input overrun(s)

Signed-off-by: Jon Povey<jon.povey@xxxxxxxxxxxxxxx>
---
I am not really sure what is going on here, I found I needed to do

musb_platform_exit() calls usb_nop_xceiv_unregister(), and after my patch this now precedes the put_device(musb_>xceiv->dev) call.

this a while back but can't remember why. Sending to the list for
comment or if others would like to test.

My config is

CONFIG_USB_SUSPEND=y
CONFIG_USB_OTG=y
CONFIG_USB_MUSB_HDRC=m
CONFIG_USB_MUSB_SOC=y
CONFIG_USB_MUSB_OTG=y
CONFIG_USB_GADGET_MUSB_HDRC=y
CONFIG_USB_MUSB_HDRC_HCD=y
# CONFIG_MUSB_PIO_ONLY is not set
# CONFIG_USB_INVENTRA_DMA is not set
CONFIG_USB_TI_CPPI_DMA=y
CONFIG_USB_MUSB_DEBUG=y

and it crashes after I've been using g_serial on top of it.

   Note that this oops should only occur in OTG mode.

Sometimes on unload I don't get an Oops but a WARNING:

   Yeah, I have seen only this warning so far.

------------[ cut here ]------------
WARNING: at lib/kobject.c:595 kobject_put+0x3c/0x60()
ttyS2: 3 input overrun(s)
kobject: '(null)' (c73de788): is not initialized, yet kobject_put() is being called.
Modules linked in: musb_hdrc(-) techwell mcpcan dm355spi wm8985 penta fpanel mcp4725 [last unloaded: g_serial]
Backtrace:
[<c002a3c8>] (dump_backtrace+0x0/0x114) from [<c0292f10>] (dump_stack+0x18/0x1c)
  r7:c6ebfe08 r6:c0156fc0 r5:c032a900 r4:00000253
[<c0292ef8>] (dump_stack+0x0/0x1c) from [<c003abc4>] (warn_slowpath_common+0x54/0x6c)
[<c003ab70>] (warn_slowpath_common+0x0/0x6c) from [<c003ac80>] (warn_slowpath_fmt+0x38/0x40)
  r9:c6ebe000 r8:c0027084 r7:fec64000 r6:c03671d8 r5:c6edf100
r4:c73de788
[<c003ac48>] (warn_slowpath_fmt+0x0/0x40) from [<c0156fc0>] (kobject_put+0x3c/0x60)
  r3:00000000 r2:c032a90e
[<c0156f84>] (kobject_put+0x0/0x60) from [<c018a5ec>] (put_device+0x1c/0x20)
  r4:c6818800
[<c018a5d0>] (put_device+0x0/0x20) from [<bf0cb8dc>] (musb_free+0x80/0x90 [musb_hdrc])
[<bf0cb85c>] (musb_free+0x0/0x90 [musb_hdrc]) from [<bf0d5d60>] (musb_remove+0x6c/0xa4 [musb_hdrc])
  r5:c6edf100 r4:00000000
[<bf0d5cf4>] (musb_remove+0x0/0xa4 [musb_hdrc]) from [<c018ee60>] (platform_drv_remove+0x20/0x24)
  r7:bf0d9038 r6:c0367214 r5:bf0d9038 r4:c03671e0
[<c018ee40>] (platform_drv_remove+0x0/0x24) from [<c018da5c>] (__device_release_driver+0x90/0xdc)
[<c018d9cc>] (__device_release_driver+0x0/0xdc) from [<c018db64>] (driver_detach+0xbc/0xe4)
  r5:c6ebe000 r4:c03671e0
[<c018daa8>] (driver_detach+0x0/0xe4) from [<c018ccf0>] (bus_remove_driver+0x98/0xc0)
  r7:c6ebff3c r6:c0376978 r5:bf0d9038 r4:bf0d9038
[<c018cc58>] (bus_remove_driver+0x0/0xc0) from [<c018e15c>] (driver_unregister+0x68/0x78)
  r7:c6ebff3c r6:00000000 r5:bf0d9038 r4:00000000
[<c018e0f4>] (driver_unregister+0x0/0x78) from [<c018f0c4>] (platform_driver_unregister+0x14/0x18)
  r7:c6ebff3c r6:00000880 r5:bf0d90c0 r4:00000000
[<c018f0b0>] (platform_driver_unregister+0x0/0x18) from [<bf0d5cec>] (musb_cleanup+0x14/0x1c [musb_hdrc])
[<bf0d5cd8>] (musb_cleanup+0x0/0x1c [musb_hdrc]) from [<c006bab0>] (sys_delete_module+0x1f0/0x264)
[<c006b8c0>] (sys_delete_module+0x0/0x264) from [<c0026f00>] (ret_fast_syscall+0x0/0x2c)
  r7:00000081 r6:7264685f r5:6273756d r4:00014294
---[ end trace d4d0e8881978b0c6 ]---

  drivers/usb/musb/musb_core.c |    8 ++++----
  1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 540c766..77f53d8 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1925,6 +1925,10 @@ static void musb_free(struct musb *musb)
  	put_device(musb->xceiv->dev);
  #endif

I believe the real problem is this unbalanced put_device() call under #ifdef CONFIG_USB_MUSB_OTG, and I'm removing it. The glue layers should call otg_put_transceiver() instead.

+	musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+	musb_platform_exit(musb);
+	musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+
  #ifdef CONFIG_USB_MUSB_HDRC_HCD
  	usb_put_hcd(musb_to_hcd(musb));
  #else
@@ -2245,10 +2249,6 @@ static int __exit musb_remove(struct platform_device *pdev)
  	if (musb->board_mode == MUSB_HOST)
  		usb_remove_hcd(musb_to_hcd(musb));
  #endif
-	musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
-	musb_platform_exit(musb);
-	musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
-
  	musb_free(musb);
  	iounmap(ctrl_base);
  	device_init_wakeup(&pdev->dev, 0);

WBR, Sergei
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux