From 3161f583cab80c7b985abc00c709427f05f0acba Mon Sep 17 00:00:00 2001 From: Andre Oppermann Date: Fri, 27 Aug 2004 18:33:08 +0000 Subject: [PATCH] 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 MFC after: 3 days --- sys/dev/hfa/fore_receive.c | 2 +- sys/dev/idt/idt_harp.c | 3 +-- sys/dev/ppbus/if_plip.c | 4 ++-- sys/i4b/driver/i4b_ipr.c | 6 +----- sys/net/if_loop.c | 2 +- sys/net/if_ppp.c | 4 ++-- sys/net/if_sl.c | 2 +- sys/net/if_spppsubr.c | 2 +- sys/net/netisr.c | 8 +++++--- sys/net/rtsock.c | 2 +- sys/netgraph/atm/atmpif/ng_atmpif_harp.c | 2 +- sys/netinet/ip_mroute.c | 2 +- sys/netinet6/ah_input.c | 4 ++-- sys/netinet6/esp_input.c | 4 ++-- sys/netipsec/ipsec_input.c | 4 ++-- sys/netipsec/xform_ipip.c | 2 +- 16 files changed, 25 insertions(+), 28 deletions(-) diff --git a/sys/dev/hfa/fore_receive.c b/sys/dev/hfa/fore_receive.c index 5d89522908d..c07eee5e960 100644 --- a/sys/dev/hfa/fore_receive.c +++ b/sys/dev/hfa/fore_receive.c @@ -480,7 +480,7 @@ retry: /* * 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; } diff --git a/sys/dev/idt/idt_harp.c b/sys/dev/idt/idt_harp.c index 3a2f27be685..61cbdf9d1a7 100644 --- a/sys/dev/idt/idt_harp.c +++ b/sys/dev/idt/idt_harp.c @@ -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. */ } diff --git a/sys/dev/ppbus/if_plip.c b/sys/dev/ppbus/if_plip.c index 67d8be9ffd2..5b05812ed55 100644 --- a/sys/dev/ppbus/if_plip.c +++ b/sys/dev/ppbus/if_plip.c @@ -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; diff --git a/sys/i4b/driver/i4b_ipr.c b/sys/i4b/driver/i4b_ipr.c index f0d9e8dd6fa..cc087dc56a8 100644 --- a/sys/i4b/driver/i4b_ipr.c +++ b/sys/i4b/driver/i4b_ipr.c @@ -881,16 +881,12 @@ error: 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); - } } /*---------------------------------------------------------------------------* diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index 21f8026a58a..1ddf74fcfe2 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -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); } diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c index 8f06594d589..eaab431ada3 100644 --- a/sys/net/if_ppp.c +++ b/sys/net/if_ppp.c @@ -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++; diff --git a/sys/net/if_sl.c b/sys/net/if_sl.c index 2a23b161e7b..37db1c01e2b 100644 --- a/sys/net/if_sl.c +++ b/sys/net/if_sl.c @@ -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++; } diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c index 4c9f304b8ea..71019750bfd 100644 --- a/sys/net/if_spppsubr.c +++ b/sys/net/if_spppsubr.c @@ -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)); diff --git a/sys/net/netisr.c b/sys/net/netisr.c index ca2a6cb7e4f..8f573d9ca53 100644 --- a/sys/net/netisr.c +++ b/sys/net/netisr.c @@ -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 diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 0108f5e7bc2..8616e237882 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -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. */ } /* diff --git a/sys/netgraph/atm/atmpif/ng_atmpif_harp.c b/sys/netgraph/atm/atmpif/ng_atmpif_harp.c index 261107b7124..13077564632 100644 --- a/sys/netgraph/atm/atmpif/ng_atmpif_harp.c +++ b/sys/netgraph/atm/atmpif/ng_atmpif_harp.c @@ -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. diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index 94781e08a2f..ca2b562e145 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -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 diff --git a/sys/netinet6/ah_input.c b/sys/netinet6/ah_input.c index e03eb256a53..24e59ea2f5a 100644 --- a/sys/netinet6/ah_input.c +++ b/sys/netinet6/ah_input.c @@ -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; diff --git a/sys/netinet6/esp_input.c b/sys/netinet6/esp_input.c index e2440bfd106..bb3c4afab13 100644 --- a/sys/netinet6/esp_input.c +++ b/sys/netinet6/esp_input.c @@ -389,7 +389,7 @@ noreplaycheck: 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 @@ noreplaycheck: goto bad; } - if (! netisr_queue(NETISR_IPV6, m)) { + if (netisr_queue(NETISR_IPV6, m)) { /* (0) on success. */ ipsec6stat.in_inval++; m = NULL; goto bad; diff --git a/sys/netipsec/ipsec_input.c b/sys/netipsec/ipsec_input.c index 9eefa4ddbc2..7258446686d 100644 --- a/sys/netipsec/ipsec_input.c +++ b/sys/netipsec/ipsec_input.c @@ -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: diff --git a/sys/netipsec/xform_ipip.c b/sys/netipsec/xform_ipip.c index 4ede1d284dd..b71d56b1c96 100644 --- a/sys/netipsec/xform_ipip.c +++ b/sys/netipsec/xform_ipip.c @@ -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__));