Some devfs and tty issues
Arthur Hartwig
Arthur.Hartwig at nokia.com
Mon Mar 17 08:53:53 UTC 2008
I'm developing a driver for a USB hardware modem. I want to allow dialup
logins from the modem. The driver currently allows me to use cu to set
and examine modem parameters, make outgoing calls and converse with the
called system. I'm more interested in allowing logins over an incoming
call to the modem. The driver is modeled on the uplcom driver. If I
plugin the modem and start getty on the ttyU0 device
(# /usr/libexec/getty std.9600 ttyU0)
and then pull the adapter out of the USB socket a crash follows.
I'm happy to file a PR and supply stack traces or otherwise assist in
debugging. A recent message to this list and its replies suggest others
have also found the interactions between the tty driver and devfs to be
somewhat obscure so I'm posting this in the hope that some other eyes or
old hands might be able to point to point me to something I've missed.
These remarks apply to FreeBSD 6.3 RELEASE.
In destroy_devl() in kern_conf.c I think the call to devfs_destroy()
appears too early in the function. The following scenario in
destroy_devl() is possible:
1. in process A, devfs_destroy() in fs/devfs/devfs_devs.c called,
clearing CDP_ACTIVE.
2. msleep() called; devmtx released
3. context switch to process B which issues an open() which results
in a call to devfs_populate() which calls devfs_populate_loop()
which finds CDP_ACTIVE clear and calls dev_rel() which results in
the device structure getting freed.
4. sleep time expires and process A resumes, but retains pointer to
now freed device structure.
The devfs_destroy() call would be better moved to somewhere towards the
end of destroy_devl(), say after SI_ALIAS is cleared. The dev structure
is still safe to reference after calling devfs_destroy() because the
devmtx mutex is still held preveneting the freeing of the dev structure
After I moved the devfs_destroy() call down past the msleep() call I
could still provoke a problem by the following
1. Plug in USB modem
2. # cu -l cuaU0
to set modem parameters to auto answer
3. kill cu
4. dial in from PSTN
5. remove USB modem from USB socket.
Now kernel repeatedly reports:
Purging 4294967245 threads from cuaU0
I expect it will take a long while to purge that many threads :-)
At least longer than I was prepared to wait.
When this message was being output, the si_threadcount field of the
cuaU0 cdev structure contained 0xffffffcd while much of the rest of the
structure contained sensible looking values.
On repeating the scenario I observed:
All threads purged from cuaU0
Purging 4294967232 threads from ttyU0
Purging 4294967231 threads from ttyU0
On a second repeat of the same scenario, the cuaU0 cdev structure had
0xffffffd3 in the si_threadcount field when it was passed to destroy_devl().
Tomorrow I'll set hardware watchpoints on the si_threadcount field of
the cdev structures for both ttyU0 and cuaU0 in an attempt to catch
where they are being modified to these extravagant values.
Arthur
More information about the freebsd-arch
mailing list