Subject: used-to-be-mcluster references and m_copym()
To: None <tech-net@netbsd.org>
From: Dennis Ferguson <dennis@jnx.com>
List: tech-net
Date: 05/01/1997 18:40:44
Hello,

I'm trying to debug an odd problem I'm having with what used to be
mcluster's and multicasting, and am sitting here looking at some code
in kern/uipc_mbuf.c that just doesn't seem right.  I'm hoping someone
will point out what I'm missing.

In sys/mbuf.h there is a comment above the fancy new mcluster reference
macros which reads

      * Note: add and delete reference must be called at splimp().

In kern/uipc_mbuf.c there are three uses of MCLADDREFERENCE(), two in
m_copypacket() and one in m_copym().  There doesn't appear to be an
splimp() in sight in either of these routines.  If you grep in
netinet/ you will find quite a few calls to m_copym (via the m_copy()
pun), not one of which is protected by more than splsoftnet().

So how can these work?  The only way I can see it is that something
is assuming that you'll never m_copym() an mbuf chain where there
is another copy held by a device driver (which might dereference
a used-to-be-mcluster in its transmit interrupt routine).  Of course,
even ignoring the fact that this seems dangerous to assume in general,
m_copy()ing packets and handing the copies to device drivers is what the
multicast code does.

I'd also note that the use of mclrefcnt[] in all older code I can find
is similarly unprotected, with the added feature that machines that
can't do byte loads and stores may spread the apparent damage to
mcluster reference counts adjacent to the one being fiddled.

In any case, since m_copym() seems to have worked the way it was for
a long time I still have a nagging suspicion that I'm not seeing
something.  Does anyone know what it is?

Dennis Ferguson