mention msleep() in porting_drivers.txt
|Status:||In Progress||Start date:|
Any suggestions on how to make this clearer are welcome.
RCS file: /home/aggelos/imports/vcs/dcvs/doc/notes/porting_drivers.txt,v
retrieving revision 1.3
diff -u -p -u -r1.3 porting_drivers.txt
--- notes/porting_drivers.txt 29 Dec 2007 18:35:59 -0000 1.3
+++ notes/porting_drivers.txt 6 Jan 2008 17:40:24 -0000
@@ -84,6 +84,24 @@ $DragonFly: doc/notes/porting_drivers.tx
call is replaced with
+ On occasion, the FreeBSD code will use mtx_sleep() or msleep()
+ (currently [01/2008], those macros have identical definitions)
+ in order to release a mutex and sleep without missing any
+ wakeups that might occur in between. The DragonFly idiom for
+ this case is to enter a critical section and use tsleep_interlock()
+ to let threads in other cpus know that we're about to go to
+ sleep. In our example, you would substitute
+ lockmgr(&my_lock, LK_RELEASE);
+ tsleep(ident, flags, "whatever", timeout);
+ lockmgr(&my_lock, LK_EXCLUSIVE);
+ msleep(ident, &my_mtx, flags, "whatever", timeout);
As for mtx_assert() calls, translate them like this:
mtx_assert(&my_mtx, MA_OWNED) -> KKASSERT(lockstatus(&my_lock, curthread) != 0)
#1 Updated by hsu1 almost 6 years ago
Well, we do have a msleep() function. It atomically releases a
lock before sleeping to ensure that no wakeup is missed. It is the
same as the msleep() function that's currently in FreeBSD, except
in FreeBSD it release a mutex lock and in DragonFly it releases a
spin lock. For short critical sections that don't block, substituting
a spinlock and msleep() for a mutex lock and msleep() would be the
most direct way to convert between FreeBSD and DragonFly.
For more complicated critical sections, it might be better to pursue
a different MP-safety strategy entirely, such as per-cpu data along with
crit_enter()/crit_exit(). This has lower overhead and also parallelizes,
rather than serializes, the work load.
#2 Updated by aoiko almost 6 years ago
Unfortunately it was not obvious from the patch context, but the added text
is part of an example of how to convert MTX_DEF FreeBSD mutexes. So I guess
this comment does not apply.
Agreed. The reason I didn't just add an example for MTX_SPIN mutexes is
precisely not to encourage just blindly copying FreeBSD's fine-grained
locking. Explaining alternative strategies and tradeoffs would require
a seperate article of its own though.
#3 Updated by dillon almost 6 years ago
:Agreed. The reason I didn't just add an example for MTX_SPIN mutexes is
:precisely not to encourage just blindly copying FreeBSD's fine-grained
:locking. Explaining alternative strategies and tradeoffs would require
:a seperate article of its own though.
Yah, I far prefer that people use lockmgr locks for most porting from
FreeBSD, if only to make debugging far, far easier. They aren't half
bad... over the years I've removed a lot of cruft from the lockmgr API,
it's actually pretty efficient.
The interrupt serializer is the best locking mechanism to use for drivers
which have interrupt service routines, but requires a bit more research
to use properly in a port vs lockmgr locks.
#4 Updated by tuxillo over 4 years ago
At least there's a mention to it:
* MSLEEP/TSLEEP conversion. The DragonFly msleep/tsleep do not have 'PRI'
priorities. 0 should be used.
Maybe the most common "translation" could be added, and make it clear that there
are situations where it cannot just blindly replaced. Pointing to this ticket
and some documention is also interesting in my opinion.
- Description updated (diff)
Some more stuff for the porting file...
All mbuf calls use MB_* flags, not M_* flags. e.g. MB_DONTWAIT instead of
m_collapse(*xxx, M_DONTWAIT, XXX_XXX) -> m_defrag(*xxx, MB_DONTWAIT)
IFQ_DRV_* -> ifq_*
(struct ifnet)->if_flags was split into if_flags and if_drv_flags in FreeBSD,
replace all occurences of if_drv_flags with if_flags and the variable being
assigned from IF_DRV_* to IF_*