mbuf losses in 4.2 bsd

Tim Seaver tas at unc.UUCP
Thu Apr 5 13:22:32 AEST 1984


Well, I just took my first dive into the 4.2 ipc code to see
why ~20 sockets would run our system out of mbufs (~1800 in
'use' for data at the time of the last system crash...). I
think I've found a problem, but I'd like to have it confirmed
by someone with more experience with 4.2. 

My analysis:

	When uipc_usrreq is called from sosend with a PRU_SEND
request, it is assumed that uipc_usrreq will free the mbuf chain
being sent. This is not alway the case, causing mbufs to be lost
to that great mbuf chain in the sky. Three things in uipc_usrreq
can cause this.

1) If the socket is a datagram or stream socket and an error is
detected, the PRU_SEND case of the major switch finishes up with
an 'm = 0;', which causes the mbuf chain not to be freed before
the routine returns to sosend, which itself sets 'top = 0;' shortly
thereafter, causing the mbuf chain to disappear.

2) If the socket is a datagram socket and there is no buffer space
available to the *destination* socket, the same problems as in 1
apply.

3) If the socket is a datagram socket and there is buffer space
available at the destination, but not enough to hold all of the
data and accessory information, the routine sbappendaddr is called
to update the destination rcv buffer, detects the lack of space, 
and returns without freeing the mbuf chain, after which uipc_usrreq
does another 'm = 0;' and returns to the same problem in sosend
as in 1 and 2.

Proposed solution:

	The easiest solution I can see is to move the 'm = 0'
statement at the end of the PRU_SEND case in uipc_usrreq to the
end of the SOCK_STREAM subcase to solve problems 1 and 2, and
check the return code from sbappendaddr, only doing the sbwakeup
and 'm = 0' if it's non-zero, indicating that the mbuf chain has
been freed. This solves problem 3.
-- 
Timothy A. Seaver
decvax!mcnc!unc!tas
tas%unc at csnet-relay



More information about the Comp.unix.wizards mailing list