Apply error and success logic consistently to the function netisr_queue() and

its users.

netisr_queue() now returns (0) on success and ERRNO on failure.  At the
moment ENXIO (netisr queue not functional) and ENOBUFS (netisr queue full)
are supported.

Previously it would return (1) on success but the return value of IF_HANDOFF()
was interpreted wrongly and (0) was actually returned on success.  Due to this
schednetisr() was never called to kick the scheduling of the isr.  However this
was masked by other normal packets coming through netisr_dispatch() causing the
dequeueing of waiting packets.

PR:		kern/70988
Found by:	MOROHOSHI Akihiko <moro@remus.dti.ne.jp>
MFC after:	3 days
This commit is contained in:
Andre Oppermann 2004-08-27 18:33:08 +00:00
parent 3713458b99
commit 3161f583ca
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=134391
16 changed files with 25 additions and 28 deletions

View File

@ -480,7 +480,7 @@ fore_recv_drain(fup)
/*
* Schedule callback
*/
if (! netisr_queue(NETISR_ATM, mhead)) {
if (netisr_queue(NETISR_ATM, mhead)) { /* (0) on success. */
fup->fu_stats->st_drv.drv_rv_ifull++;
goto free_ent;
}

View File

@ -762,6 +762,5 @@ idt_receive(nicstar_reg_t * idt, struct mbuf * m, int vpi, int vci)
/*
* Schedule callback
*/
if (! netisr_queue(NETISR_ATM, m))
KB_FREEALL(m);
netisr_queue(NETISR_ATM, m); /* mbuf is free'd on failure. */
}

View File

@ -510,7 +510,7 @@ lp_intr (void *arg)
if (top) {
if (sc->sc_if.if_bpf)
lptap(&sc->sc_if, top);
netisr_queue(NETISR_IP, top);
netisr_queue(NETISR_IP, top); /* mbuf is free'd on failure. */
}
goto done;
}
@ -555,7 +555,7 @@ lp_intr (void *arg)
if (top) {
if (sc->sc_if.if_bpf)
lptap(&sc->sc_if, top);
netisr_queue(NETISR_IP, top);
netisr_queue(NETISR_IP, top); /* mbuf is free'd on failure. */
}
}
goto done;

View File

@ -881,16 +881,12 @@ ipr_rx_data_rdy(int unit)
BPF_MTAP(&sc->sc_if, &mm);
}
if(! netisr_queue(NETISR_IP, m))
if(netisr_queue(NETISR_IP, m)) /* (0) on success. */
{
NDBGL4(L4_IPRDBG, "ipr%d: ipintrq full!", unit);
sc->sc_if.if_ierrors++;
sc->sc_if.if_iqdrops++;
}
else
{
schednetisr(NETISR_IP);
}
}
/*---------------------------------------------------------------------------*

View File

@ -311,7 +311,7 @@ if_simloop(ifp, m, af, hlen)
}
ifp->if_ipackets++;
ifp->if_ibytes += m->m_pkthdr.len;
netisr_queue(isr, m);
netisr_queue(isr, m); /* mbuf is free'd on failure. */
return (0);
}

View File

@ -1611,8 +1611,8 @@ ppp_inproc(sc, m)
if (isr == -1)
rv = IF_HANDOFF(&sc->sc_inq, m, NULL);
else
rv = netisr_queue(isr, m);
if (!rv) {
rv = netisr_queue(isr, m); /* (0) on success. */
if ((isr == -1 && !rv) || (isr != -1 && rv)) {
if (sc->sc_flags & SC_DEBUG)
if_printf(ifp, "input queue full\n");
ifp->if_iqdrops++;

View File

@ -960,7 +960,7 @@ slinput(int c, struct tty *tp)
m_freem(m);
goto newpack;
}
if (! netisr_queue(NETISR_IP, m)) {
if (netisr_queue(NETISR_IP, m)) { /* (0) on success. */
sc->sc_if.if_ierrors++;
sc->sc_if.if_iqdrops++;
}

View File

@ -715,7 +715,7 @@ sppp_input(struct ifnet *ifp, struct mbuf *m)
goto drop;
/* Check queue. */
if (! netisr_queue(isr, m)) {
if (netisr_queue(isr, m)) { /* (0) on success. */
if (debug)
log(LOG_DEBUG, SPP_FMT "protocol queue overflow\n",
SPP_ARGS(ifp));

View File

@ -204,6 +204,8 @@ netisr_dispatch(int num, struct mbuf *m)
* Same as above, but always queue.
* This is either used in places where we are not confident that
* direct dispatch is possible, or where queueing is required.
* It returns (0) on success and ERRNO on failure. On failure the
* mbuf has been free'd.
*/
int
netisr_queue(int num, struct mbuf *m)
@ -216,13 +218,13 @@ netisr_queue(int num, struct mbuf *m)
if (ni->ni_queue == NULL) {
isrstat.isrs_drop++;
m_freem(m);
return (1);
return (ENXIO);
}
isrstat.isrs_queued++;
if (!IF_HANDOFF(ni->ni_queue, m, NULL))
return (0);
return (ENOBUFS); /* IF_HANDOFF has free'd the mbuf */
schednetisr(num);
return (1);
return (0);
}
static void

View File

@ -978,7 +978,7 @@ rt_dispatch(struct mbuf *m, const struct sockaddr *sa)
*family = sa ? sa->sa_family : 0;
m_tag_prepend(m, tag);
}
netisr_queue(NETISR_ROUTE, m);
netisr_queue(NETISR_ROUTE, m); /* mbuf is free'd on failure. */
}
/*

View File

@ -915,7 +915,7 @@ vatmpif_harp_recv_drain(Vatmpif_unit *vup, KBuffer *m,
/*
* Schedule callback
*/
if (!netisr_queue(NETISR_ATM, m)) {
if ((err = netisr_queue(NETISR_ATM, m))) { /* (0) on success. */
/*
* queue is full. Unable to pass up to the HARP stack
* Update the stats.

View File

@ -869,7 +869,7 @@ mroute_encap_input(struct mbuf *m, int off)
m->m_pkthdr.rcvif = last_encap_vif->v_ifp;
netisr_queue(NETISR_IP, m);
netisr_queue(NETISR_IP, m); /* mbuf is free'd on failure. */
/*
* normally we would need a "schednetisr(NETISR_IP)"
* here but we were called by ip_input and it is going

View File

@ -449,7 +449,7 @@ ah4_input(m, off)
goto fail;
}
if (! netisr_queue(NETISR_IP, m)) {
if (netisr_queue(NETISR_IP, m)) { /* (0) on success. */
ipsecstat.in_inval++;
m = NULL;
goto fail;
@ -841,7 +841,7 @@ ah6_input(mp, offp, proto)
goto fail;
}
if (! netisr_queue(NETISR_IPV6, m)) {
if (netisr_queue(NETISR_IPV6, m)) { /* (0) on success. */
ipsec6stat.in_inval++;
m = NULL;
goto fail;

View File

@ -389,7 +389,7 @@ esp4_input(m, off)
goto bad;
}
if (! netisr_queue(NETISR_IP, m)) {
if (netisr_queue(NETISR_IP, m)) { /* (0) on success. */
ipsecstat.in_inval++;
m = NULL;
goto bad;
@ -745,7 +745,7 @@ esp6_input(mp, offp, proto)
goto bad;
}
if (! netisr_queue(NETISR_IPV6, m)) {
if (netisr_queue(NETISR_IPV6, m)) { /* (0) on success. */
ipsec6stat.in_inval++;
m = NULL;
goto bad;

View File

@ -447,13 +447,13 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
/*
* Re-dispatch via software interrupt.
*/
if (!netisr_queue(NETISR_IP, m)) {
if ((error = netisr_queue(NETISR_IP, m))) {
IPSEC_ISTAT(sproto, espstat.esps_qfull, ahstat.ahs_qfull,
ipcompstat.ipcomps_qfull);
DPRINTF(("%s: queue full; proto %u packet dropped\n",
__func__, sproto));
return ENOBUFS;
return error;
}
return 0;
bad:

View File

@ -376,7 +376,7 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
panic("%s: bogus ip version %u", __func__, v>>4);
}
if (!netisr_queue(isr, m)) {
if (netisr_queue(isr, m)) { /* (0) on success. */
ipipstat.ipips_qfull++;
DPRINTF(("%s: packet dropped because of full queue\n",
__func__));