Port-arm archive

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

Re: CURRENT broken on Raspberry Pi 2?



>herbert%gojira.at@localhost ("Herbert J. Skuhra") writes:
>
>>today I am getting a new panic:
>
>>[   1.7517449] usb0 at dwctwo0: USB revision 2.0
>>[   1.8817175] panic: uhub0 at usb0: NetBSD (0000) DWC2 root hub (0000), class 9/0, rev 2.00/1.00, addr 1
>>[   1.8917219] specificdata_setspecific
>>[   1.8917219] cpu0: Begin traceback...
>>[   1.9024390] 0x811e7ee4: netbsd:db_panic+0x14
>>[   1.9024390] 0x811e7efc: netbsd:vpanic+0x194
>>[   1.9120679] 0x811e7f14: netbsd:snprintf
>>[   1.9120679] 0x811e7f5c: netbsd:tvtohz
>>[   1.9120679] 0x811e7fac: netbsd:linux_workqueue_thread+0x54
>>[   1.9233013] cpu0: End traceback...
>>Undefined instruction 0xe7ffffff in kernel at 0x8001dc90 (LR 0x80375c50 SP 0x811
>
>
>That's a crude bug in the USB host driver.
>
>In dwc2_hcd.c a linux-style workqueue is used. The code for these
>workqueue comes from drm2 support code in
>
>sys/external/bsd/common/linux/linux_work.c
>
>That code gets initialized when loading DRM in linux_workqueue_init(),
>in particular the linux_workqueue_key is allocated and some DRM specific
>workqueues are created. But without DRM in place, nothing is initialized.
>
>The USB driver uses the same support code and creates such a workqueue
>without the key ever been allocated. The linux_workqueue_thread then tries
>to use that key which causes it to panic with "specificdata_setspecific".
>
>The question is, why does it happen now.
>
>The panic is raised when a key is used larger than all allocated keys.
>So if any key has been allocated before dwc2_hcd.c, you don't see a panic,
>but possibly two unrelated subsystems trash each others specificdata.

rpi3/aarch64, neither.

lwp_specific_key_create() called from linux_workqueue_thread() expects to be
already lwp_setspecific()'ed, but lwp_specific_key_create() was removed from
strans_init(), so linux_workqueue_thread() is executed without lwp_setspecific().
that cause this panic.

I think the underlying cause is that dwc2 is not calling linux_workqueue_init().
How about the following patches?


cvs -q diff -aup sys/external/bsd/
Index: sys/external/bsd/common/linux/linux_work.c
===================================================================
RCS file: /src/cvs/cvsroot-netbsd/src/sys/external/bsd/common/linux/linux_work.c,v
retrieving revision 1.43
diff -a -u -p -r1.43 linux_work.c
--- sys/external/bsd/common/linux/linux_work.c	27 Aug 2018 15:25:43 -0000	1.43
+++ sys/external/bsd/common/linux/linux_work.c	5 Mar 2019 17:00:06 -0000
@@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_work.c
 #include <sys/kthread.h>
 #include <sys/lwp.h>
 #include <sys/mutex.h>
+#include <sys/once.h>
 #include <sys/queue.h>
 #include <sys/sdt.h>
 
@@ -130,8 +131,8 @@ atomic_cas_uintptr(volatile uintptr_t *p
  *	Initialize the Linux workqueue subsystem.  Return 0 on success,
  *	NetBSD error on failure.
  */
-int
-linux_workqueue_init(void)
+static int
+linux_workqueue_init0(void)
 {
 	int error;
 
@@ -168,6 +169,14 @@ fail0:	KASSERT(error);
 	return error;
 }
 
+int
+linux_workqueue_init(void)
+{
+	static ONCE_DECL(linux_workqueue_init_once);
+
+	return RUN_ONCE(&linux_workqueue_init_once, &linux_workqueue_init0);
+}
+
 /*
  * linux_workqueue_fini()
  *
Index: sys/external/bsd/dwc2/dwc2.c
===================================================================
RCS file: /src/cvs/cvsroot-netbsd/src/sys/external/bsd/dwc2/dwc2.c,v
retrieving revision 1.58
diff -a -u -p -r1.58 dwc2.c
--- sys/external/bsd/dwc2/dwc2.c	17 Feb 2019 04:17:52 -0000	1.58
+++ sys/external/bsd/dwc2/dwc2.c	5 Mar 2019 17:01:29 -0000
@@ -1273,6 +1273,10 @@ dwc2_init(struct dwc2_softc *sc)
 {
 	int err = 0;
 
+	err = linux_workqueue_init();
+	if (err)
+		return err;
+
 	sc->sc_bus.ub_hcpriv = sc;
 	sc->sc_bus.ub_revision = USBREV_2_0;
 	sc->sc_bus.ub_methods = &dwc2_bus_methods;



-- 
ryo shimizu


Home | Main Index | Thread Index | Old Index