Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 03 Dec 2006 00:51:09 +0000
From:      Ian Dowse <iedowse@iedowse.com>
To:        Alfred Perlstein <alfred@freebsd.org>
Cc:        freebsd-smp@freebsd.org, freebsd-usb@freebsd.org
Subject:   Re: RFC: Fixing USB ethernet for FreeBSD 7.0. 
Message-ID:  <200612030051.aa75264@nowhere.iedowse.com>
In-Reply-To: Your message of "Fri, 01 Dec 2006 11:17:31 PST." <20061201191731.GR38808@elvis.mu.org> 

next in thread | previous in thread | raw e-mail | index | archive | help
In message <20061201191731.GR38808@elvis.mu.org>, Alfred Perlstein writes:
>I recently had the displeasure of trying to use an USB etherdongle
>under FreeBSD.  Result: panic when the interface was started.
>
>I fixed it using a stopgap:
>
>http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/usb/if_aue.c?rev=1.101&conte
>nt-type=text/x-cvsweb-markup
>
>There are still some major issues:
>1) requires Giant.
>2) several error paths will still panic the kernel.
>
>I would like to fix them, however that does not seem easy given the
>existing infrastructure.

FYI, some USB ethernet drivers are better than others in this respect
- for example, axe(4) uses sx locks and task queues to avoid the
worst of the issues. The problems remaining in axe are that the
error recovery code in axe_encap should use a task queue, and there
are some cases where if_ioctl routines are called with other locks
held.

On the issue of calling if_ioctl while holding locks, I think this
can happen when if_addmulti() holds locks and calls if_ioctl to
synchronise the hardware with the software state from ifp->if_multiaddrs.
Almost all other if_ioctl calls occur in a context where blocking
is allowed, so it may be possible to rework the if_addmulti() code
paths so that the outer ioctl() code could first update the software
state, release locks and then perform the if_ioctl to synchronise
the hardware state.

>Statement #2:
>Using callbacks to do all IO during an interrupt is programatically
>complex and painful.  For instance, take the case of the following
>code pulled from aue_stop() (which can be called from interrupt
>context):

Note though that most USB ethernet devices require just a single
USB transfer per packet, so it's typically only during error recovery
and setup that asynchronous I/O is too tricky. That's probably easy
enough to fix with a queued task, and since error recovery is rare
it doesn't matter too much if many devices share a task queue.

If there are devices requiring multiple commands to be sent during
normal sending/receiving of packets then you'd probably also want
a separate thread for the TX and RX paths if you were to do the
commands synchronously.

Ian



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200612030051.aa75264>