Return to BSD News archive
Newsgroups: comp.os.386bsd.bugs Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!haven.umd.edu!uunet!mcsun!sun4nl!izfcs!tom From: tom@izf.tno.nl (Tom Vijlbrief) Subject: Fix for hanging slip Message-ID: <C5pzBs.66J@izf.tno.nl> Organization: TNO Institute for Perception Date: Mon, 19 Apr 1993 07:26:16 GMT Lines: 86 I experienced trouble with slip on both a 486 Notebook and a Compaq 386sx deskpro. After sending a few megabytes of data slip hangs, and netstat shows a rising oerr count and ping reports 'no more buffer space'. This is probably caused by a missed transmitter queue empty interrupt, at which point the queue is just filled to its max length and all packets are dropped. (I experienced the same lost interrupt problem when debugging a serial line driver routine for a Messy DOS slip router). This patch detects this situation and restarts by a call to slstart. Tom =============================================================================== Tom Vijlbrief TNO Institute for Perception Phone: +31 34 63 562 11 P.O. Box 23 Fax: +31 34 63 539 77 3769 ZG Soesterberg E-mail: tom@izf.tno.nl The Netherlands =============================================================================== *** org/if_slvar.h Sun Apr 18 14:35:52 1993 --- if_slvar.h Sun Apr 18 14:37:26 1993 *************** *** 62,67 **** --- 62,69 ---- long sc_lasttime; /* last time a char arrived */ long sc_starttime; /* last time a char arrived */ long sc_abortcount; /* number of abort esacpe chars */ + /* PATCH, tom@izf.tno.nl */ + u_int sc_prevqueue; /* previous queue length (detects deadlock) */ #ifdef INET /* XXX */ struct slcompress sc_comp; /* tcp compression data */ #endif *** org/if_sl.c Sun Apr 18 14:39:51 1993 --- if_sl.c Sun Apr 18 14:42:00 1993 *************** *** 89,94 **** --- 89,96 ---- #include "kernel.h" #include "conf.h" + #include "syslog.h" + #include "if.h" #include "if_types.h" #include "netisr.h" *************** *** 388,393 **** --- 390,405 ---- return (0); } s = splimp(); + + /* PATCH: Detect hanging output queue, tom@izf.tno.nl */ + if (sc->sc_prevqueue + && RB_LEN(&sc->sc_ttyp->t_out) == sc->sc_prevqueue + && (((time.tv_sec - sc->sc_if.if_lastchange.tv_sec) * hz + + (time.tv_usec - sc->sc_if.if_lastchange.tv_usec) * hz / 1000000) > 1)) { + log(LOG_NOTICE, "slip queue hangs, restarting\n"); + slstart(sc->sc_ttyp); + } + if (IF_QFULL(ifq)) { IF_DROP(ifq); m_freem(m); *************** *** 397,403 **** } IF_ENQUEUE(ifq, m); sc->sc_if.if_lastchange = time; ! if (RB_LEN(&sc->sc_ttyp->t_out) == 0) slstart(sc->sc_ttyp); splx(s); return (0); --- 409,416 ---- } IF_ENQUEUE(ifq, m); sc->sc_if.if_lastchange = time; ! /* PATCH: tom@izf.tno.nl */ ! if ((sc->sc_prevqueue= RB_LEN(&sc->sc_ttyp->t_out)) == 0) slstart(sc->sc_ttyp); splx(s); return (0);