tas@unc.UUCP (Tim Seaver) (04/05/84)
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@csnet-relay