panic: mutex Giant not owned at
/usr/src/sys/kern/tty_ttydisc.c:1127
Hans Petter Selasky
hselasky at c2i.net
Sat Jan 24 00:50:01 PST 2009
Hi Maksim,
On Saturday 24 January 2009, Maksim Yevmenkin wrote:
> [...]
> i'm sorry, did i mention there is no sleeping in netgraph? :-)
>
> again, sorry, but this is not going to work. you still doing
> UBT_LOCK()/UBT_UNLOCK() in netgraph method. that is you are trying to
> grab the same lock that is used for locking interfaces.
Yes, you have to do that. Else you end up with a state nightmare with the
taskqueue where you don't know in the end if you should start or stop the USB
interface!
> more importantly, like i said before, usb2_transfer_stop() does
> USB_BUS_LOCK()/USB_BUS_UNLOCK(). is there a guarantee that another usb
> device will not do something synchronously over the same usb bus?
Every time something is done synchronously the USB_BUS_LOCK() is dropped. This
mutex is only used when filling out DMA structures and when touching USB
hardware registers. I cannot see that this will take any time at all. We are
talking about microseconds of congestion time! USB_BUS_LOCK() is a mutex and
not a SX lock! A mutex cannot sleep in the same way an SX lock can.
> i'm actually working on including some of your changes (except getting
> rid of ubt_task), so, please, lets just stop for a second and talk
> before we start commit war here :) please bear with me for just a
> second, ok?
Ok.
>
> >
> > I have a question. What is the following doing at the middle of the
> > ubt_detach():
> >
> > if (node != NULL)
> > NG_NODE_UNREF(node);
> >
> > If you say that:
> >
> > ng_rmnode_self(node);
> >
> > Cleans up the last reference?
>
> the complete code is
>
> node_p node = sc->sc_node;
>
> if (node != NULL) {
> sc->sc_node = NULL; <-- clear sc_node
>
> NG_NODE_SET_PRIVATE(node, NULL);
> NG_NODE_REALLY_DIE(node);
>
> NG_NODE_REF(node); <--- grab +1 reference
> ng_rmnode_self(node); <--- mark node as "dead", but not ensure its
> not free()d
> }
>
> /* bla, bla */
>
> if (node != NULL)
> NG_NODE_UNREF(node); <--- drop 1 reference and possibly free() node
Yes, but you are already dropping an extra reference in ubt_shutdown(). What
about that?
> so, say we enter detach() with only one reference (from attach()).
> when we see the sc_node pointer, we assume that there could be
> multiple (> 1) references on it. so just for added protection we grab
> one more (now reference count is 2). then we call ng_rmnode_self()
> which will mark node as "dead" and drop one reference (now reference
> count is 1). then we do "bla bla" stuff which could access node
> pointer. the important thing is that node pointer still points to a
> valid "dead" node, so NG_NODE_NOT_VALID() can be used to check if node
> is "dead" or "alive". finally when "bla bla" stuff is done, we know we
> are not going to access node pointer any mode and we drop our
> reference (now reference count is 0 and node is destroyed).
> do you mean transfer stop on hook disconnection? but those are
> protected by interface locks, no? and like i said, i'm changing
> ubt_task to call drain() instead of stop() to make stop completely
> synchronous (which is actually a nice thing).
I think you misunderstand. I'm using mutexes. They will not block for very
long! There are no DELAY()'s with mutexes held! When another USB device is
attached / detached it is:
1) Done from another thread
2) The USB locks in the critical path are dropped when waiting for wakeup or
doing so called synchronous stuff.
>
> it would be if we could sleep in netgraph, and we can not.
Do mutexes sleep? No? So my code should be fine?
> in theory,
> we only need one extra reference which would tell us if there anything
> in usb2 that still could access node pointer. in practice, instead of
> checking every transfer and making sure its no pending before dropping
> that extra reference i just add multiple references for each usb2
> transfer and ubt_task (i.e. things that could access node pointer).
I'm just thinking that this is starting to get complicated, and please
understand I've spent much time on detach issues, and there is alot of
builtin funcionality inside USB which will handle start/stop/re-start issues
automagically. I see it like duplicate code when you check for USB transfer
re-start in netgraph ???
>
> right, and what if some other usb device attached to the same usb
> controller is doing something synchronously? do you see that you could
> potentially block netgraph for arbitrary time and that is really out
> of ng_ubt2 driver control?
Again, USB_BUS_LOCK() is a mutex, not an SX lock. All code using this lock is
called from High Priority threads! See explanation further up. And will not
block very long at all.
>
> i beg to differ :)
Ok, I think we are going somewhere!
--HPS
More information about the freebsd-current
mailing list