Fix handling of ENOBUFS condition. During reception, the filled mbuf
cluster from the RX descriptor is passed up to the higher layers and replaced with an empty buffer for the next time the descriptor comes up in the RX ring. The xl_newbuf() routine returns ENOBUFS if it can't obtain a new mbuf cluster, but this return value was being ignored. Now, if buffer allocation fails, we leave the old one in place and drop the packet. This is rude, but there's not much else that can be done in this situation. Without this, the driver can cause a panic if the system runs out of MBUF clusters. Now it will complain loudly, but it shouldn't cause a panic. Also added another pair of missing newlines to some printf()s.
This commit is contained in:
parent
2d9dae457a
commit
cdb5ef5fba
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=38697
@ -29,7 +29,7 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: if_xl.c,v 1.5 1998/08/24 17:51:38 wpaul Exp $
|
||||
* $Id: if_xl.c,v 1.46 1998/08/31 15:10:22 wpaul Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -124,7 +124,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id: if_xl.c,v 1.5 1998/08/24 17:51:38 wpaul Exp $";
|
||||
"$Id: if_xl.c,v 1.46 1998/08/31 15:10:22 wpaul Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -1635,7 +1635,8 @@ static int xl_list_rx_init(sc)
|
||||
for (i = 0; i < XL_RX_LIST_CNT; i++) {
|
||||
cd->xl_rx_chain[i].xl_ptr =
|
||||
(struct xl_list_onefrag *)&ld->xl_rx_list[i];
|
||||
xl_newbuf(sc, &cd->xl_rx_chain[i]);
|
||||
if (xl_newbuf(sc, &cd->xl_rx_chain[i]) == ENOBUFS)
|
||||
return(ENOBUFS);
|
||||
if (i == (XL_RX_LIST_CNT - 1)) {
|
||||
cd->xl_rx_chain[i].xl_next = &cd->xl_rx_chain[0];
|
||||
ld->xl_rx_list[i].xl_next =
|
||||
@ -1663,14 +1664,15 @@ static int xl_newbuf(sc, c)
|
||||
|
||||
MGETHDR(m_new, M_DONTWAIT, MT_DATA);
|
||||
if (m_new == NULL) {
|
||||
printf("xl%d: no memory for rx list",
|
||||
sc->xl_unit);
|
||||
printf("xl%d: no memory for rx list -- packet dropped!\n",
|
||||
sc->xl_unit);
|
||||
return(ENOBUFS);
|
||||
}
|
||||
|
||||
MCLGET(m_new, M_DONTWAIT);
|
||||
if (!(m_new->m_flags & M_EXT)) {
|
||||
printf("xl%d: no memory for rx list", sc->xl_unit);
|
||||
printf("xl%d: no memory for rx list -- packet dropped!\n",
|
||||
sc->xl_unit);
|
||||
m_freem(m_new);
|
||||
return(ENOBUFS);
|
||||
}
|
||||
@ -1703,6 +1705,8 @@ static void xl_rxeof(sc)
|
||||
|
||||
while((rxstat = sc->xl_cdata.xl_rx_head->xl_ptr->xl_status)) {
|
||||
cur_rx = sc->xl_cdata.xl_rx_head;
|
||||
sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
|
||||
|
||||
/*
|
||||
* If an error occurs, update stats, clear the
|
||||
* status word and leave the mbuf cluster in place:
|
||||
@ -1712,7 +1716,6 @@ static void xl_rxeof(sc)
|
||||
if (rxstat & XL_RXSTAT_UP_ERROR) {
|
||||
ifp->if_ierrors++;
|
||||
cur_rx->xl_ptr->xl_status = 0;
|
||||
sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1726,15 +1729,25 @@ static void xl_rxeof(sc)
|
||||
sc->xl_unit);
|
||||
ifp->if_ierrors++;
|
||||
cur_rx->xl_ptr->xl_status = 0;
|
||||
sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* No errors; receive the packet. */
|
||||
sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
|
||||
m = cur_rx->xl_mbuf;
|
||||
total_len = cur_rx->xl_ptr->xl_status & XL_RXSTAT_LENMASK;
|
||||
xl_newbuf(sc, cur_rx);
|
||||
|
||||
/*
|
||||
* Try to conjure up a new mbuf cluster. If that
|
||||
* fails, it means we have an out of memory condition and
|
||||
* should leave the buffer in place and continue. This will
|
||||
* result in a lost packet, but there's little else we
|
||||
* can do in this situation.
|
||||
*/
|
||||
if (xl_newbuf(sc, cur_rx) == ENOBUFS) {
|
||||
ifp->if_ierrors++;
|
||||
cur_rx->xl_ptr->xl_status = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
eh = mtod(m, struct ether_header *);
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
@ -2250,8 +2263,10 @@ static void xl_init(xsc)
|
||||
xl_wait(sc);
|
||||
|
||||
/* Init circular RX list. */
|
||||
if (xl_list_rx_init(sc)) {
|
||||
printf("xl%d: failed to set up rx lists\n", sc->xl_unit);
|
||||
if (xl_list_rx_init(sc) == ENOBUFS) {
|
||||
printf("xl%d: initialization failed: no "
|
||||
"memory for rx buffers\n", sc->xl_unit);
|
||||
xl_stop(sc);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user