[ECOS] How can we fix MBUF problem on old 1.3.1 code base
Jonathan Larmour
jlarmour@redhat.com
Mon Sep 18 18:07:00 GMT 2000
AshCan@aol.com wrote:
>
> Are there are few simple fixes to the 1.3.1 code base to fix the out of MBUFs panic? What are they?
As luck would have it, I just happened to remember seeing the relevant
patch go by. Try the attached patch, but you'll probably have to
effectively apply it by hand, or tweak the patch - I doubt it will apply
straight off. I give no guarantees whether what you end up with will work
well though - it may rely on other patches being present, so take a backup
of your existing sources.
Jifl
--
Red Hat, 35 Cambridge Place, Cambridge, UK. CB2 1NS Tel: +44 (1223) 728762
"Plan to be spontaneous tomorrow." || These opinions are all my own fault
Index: net/drivers/eth/common/current/ChangeLog
===================================================================
RCS file: /local/cvsfiles/ecc/ecc/net/drivers/eth/common/current/ChangeLog,v
retrieving revision 1.9
diff -u -5 -p -r1.9 ChangeLog
--- net/drivers/eth/common/current/ChangeLog 2000/03/08 19:11:19 1.9
+++ net/drivers/eth/common/current/ChangeLog 2000/03/29 13:28:42
@@ -1,5 +1,10 @@
+2000-03-28 Gary Thomas <gthomas@redhat.com>
+
+ * src/eth_drv.c (eth_drv_recv): Tolerate running out of MBUFs
+ instead of "panic"ing.
+
2000-03-08 Gary Thomas <gthomas@redhat.com>
* src/eth_drv.c: Add some function [block] comments.
(eth_drv_send): Use eCos scheduler lock instead of interrupt lock.
Index: net/drivers/eth/common/current/src/eth_drv.c
===================================================================
RCS file: /local/cvsfiles/ecc/ecc/net/drivers/eth/common/current/src/eth_drv.c,v
retrieving revision 1.7
diff -u -5 -p -r1.7 eth_drv.c
--- net/drivers/eth/common/current/src/eth_drv.c 2000/03/08 19:11:20 1.7
+++ net/drivers/eth/common/current/src/eth_drv.c 2000/03/29 13:25:07
@@ -336,11 +336,11 @@ eth_drv_recv(struct eth_drv_sc *sc, int
int sg_len;
/* Pull packet off interface. */
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == 0) {
- panic("out of MBUFs");
+ diag_printf("warning: eth_recv out of MBUFs\n");
}
// Set up buffers
// Unload ethernet header separately so IP/UDP/TCP headers are aligned
sg_list[0].buf = (CYG_ADDRESS)eh;
@@ -348,30 +348,43 @@ eth_drv_recv(struct eth_drv_sc *sc, int
sg_len = 1;
// Compute total length (minus ethernet header)
total_len -= sizeof(*eh);
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = total_len;
- mlen = MHLEN;
top = 0;
+ mlen = MHLEN;
mp = ⊤
+ if (m) {
+ m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.len = total_len;
+ } else {
+ sg_list[sg_len].buf = (CYG_ADDRESS)0;
+ sg_list[sg_len].len = min(total_len, MCLBYTES);
+ sg_len++;
+ total_len = 0;
+ }
+
while (total_len > 0) {
if (top) {
MGET(m, M_DONTWAIT, MT_DATA);
if (m == 0) {
m_freem(top);
- panic("out of MBUFs");
+ panic("out of MBUFs [2]");
}
mlen = MLEN;
}
if (total_len >= MINCLSIZE) {
MCLGET(m, M_DONTWAIT);
if ((m->m_flags & M_EXT) == 0) {
m_freem(top);
- panic("out of MBUFs");
+ diag_printf("warning: eth_recv out of MBUFs\n");
+ sg_list[sg_len].buf = (CYG_ADDRESS)0;
+ sg_list[sg_len].len = min(total_len, MCLBYTES);
+ sg_len++;
+ top = 0;
+ break;
}
mlen = MCLBYTES;
}
m->m_len = mlen = min(total_len, mlen);
total_len -= mlen;
@@ -386,11 +399,13 @@ eth_drv_recv(struct eth_drv_sc *sc, int
// Ask hardware to unload buffers
(sc->funs->recv)(sc, sg_list, sg_len);
if (net_debug) {
for (i = 0; i < sg_len; i++) {
- diag_dump_buf((void *)sg_list[i].buf, sg_list[i].len);
+ if (sg_list[i].buf) {
+ diag_dump_buf((void *)sg_list[i].buf, sg_list[i].len);
+ }
}
}
m = top;
if (m == 0) {
Index: net/drivers/eth/edb7xxx/current/ChangeLog
===================================================================
RCS file: /local/cvsfiles/ecc/ecc/net/drivers/eth/edb7xxx/current/ChangeLog,v
retrieving revision 1.8
diff -u -5 -p -r1.8 ChangeLog
--- net/drivers/eth/edb7xxx/current/ChangeLog 2000/03/06 15:52:28 1.8
+++ net/drivers/eth/edb7xxx/current/ChangeLog 2000/03/29 13:28:17
@@ -1,5 +1,10 @@
+2000-03-28 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_edb7xxx.c (cs8900_recv): Handle case where there were
+ no buffers (and thus the sg_list[] has NULL pointers).
+
2000-03-06 Gary Thomas <gthomas@redhat.com>
* src/if_edb7xxx.c: Use new driver API.
2000-02-29 Gary Thomas <gthomas@cygnus.co.uk>
Index: net/drivers/eth/edb7xxx/current/src/if_edb7xxx.c
===================================================================
RCS file: /local/cvsfiles/ecc/ecc/net/drivers/eth/edb7xxx/current/src/if_edb7xxx.c,v
retrieving revision 1.6
diff -u -5 -p -r1.6 if_edb7xxx.c
--- net/drivers/eth/edb7xxx/current/src/if_edb7xxx.c 2000/03/06 15:52:29 1.6
+++ net/drivers/eth/edb7xxx/current/src/if_edb7xxx.c 2000/03/29 13:25:07
@@ -330,24 +330,29 @@ cs8900_RxEvent(struct eth_drv_sc *sc)
//
static void
cs8900_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
{
int i, mlen;
- unsigned short *data;
- unsigned char *cp;
+ unsigned short *data, val;
+ unsigned char *cp, cval;
for (i = 0; i < sg_len; i++) {
data = (unsigned short *)sg_list[i].buf;
mlen = sg_list[i].len;
while (mlen >= sizeof(*data)) {
- *data++ = CS8900_RTDATA;
+ val = CS8900_RTDATA;
+ if (data) {
+ *data++ = val;
+ }
mlen -= sizeof(*data);
}
if (mlen) {
// Fetch last odd byte
- cp = (unsigned char *)data;
- *cp = CS8900_RTDATA & 0xFF;
+ cval = CS8900_RTDATA & 0xFF;
+ if (cp = (unsigned char *)data) {
+ *cp = cval;
+ }
}
}
}
static void
Index: net/drivers/eth/quicc/current/ChangeLog
===================================================================
RCS file: /local/cvsfiles/ecc/ecc/net/drivers/eth/quicc/current/ChangeLog,v
retrieving revision 1.8
diff -u -5 -p -r1.8 ChangeLog
--- net/drivers/eth/quicc/current/ChangeLog 2000/03/06 15:52:29 1.8
+++ net/drivers/eth/quicc/current/ChangeLog 2000/03/29 13:27:47
@@ -1,5 +1,10 @@
+2000-03-28 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_quicc.c (quicc_eth_recv): Handle case where there were
+ no buffers (and thus the sg_list[] contains NULL pointers).
+
2000-03-06 Gary Thomas <gthomas@redhat.com>
* src/if_quicc.c: New driver API.
2000-03-05 Gary Thomas <gthomas@redhat.com>
Index: net/drivers/eth/quicc/current/src/if_quicc.c
===================================================================
RCS file: /local/cvsfiles/ecc/ecc/net/drivers/eth/quicc/current/src/if_quicc.c,v
retrieving revision 1.9
diff -u -5 -p -r1.9 if_quicc.c
--- net/drivers/eth/quicc/current/src/if_quicc.c 2000/03/06 15:52:30 1.9
+++ net/drivers/eth/quicc/current/src/if_quicc.c 2000/03/29 13:25:07
@@ -463,12 +463,14 @@ quicc_eth_recv(struct eth_drv_sc *sc, st
HAL_DCACHE_IS_ENABLED(cache_state);
if (cache_state) {
HAL_DCACHE_INVALIDATE(qi->rxbd->buffer, qi->rxbd->length); // Make sure no stale data
}
for (i = 0; i < sg_len; i++) {
- bcopy(bp, (void *)sg_list[i].buf, sg_list[i].len);
- bp += sg_list[i].len;
+ if (sg_list[i].buf != 0) {
+ bcopy(bp, (void *)sg_list[i].buf, sg_list[i].len);
+ bp += sg_list[i].len;
+ }
}
}
static void
quicc_eth_TxEvent(struct eth_drv_sc *sc, int stat)
More information about the Ecos-discuss
mailing list