svn commit: r220226 - head/sys/dev/bxe
David Christensen
davidch at FreeBSD.org
Thu Mar 31 21:30:00 UTC 2011
Author: davidch
Date: Thu Mar 31 21:30:00 2011
New Revision: 220226
URL: http://svn.freebsd.org/changeset/base/220226
Log:
- Added debug support to monitor mbuf defrag attempts/failures.
MFC after: One week.
Modified:
head/sys/dev/bxe/if_bxe.c
head/sys/dev/bxe/if_bxe.h
Modified: head/sys/dev/bxe/if_bxe.c
==============================================================================
--- head/sys/dev/bxe/if_bxe.c Thu Mar 31 21:21:07 2011 (r220225)
+++ head/sys/dev/bxe/if_bxe.c Thu Mar 31 21:30:00 2011 (r220226)
@@ -352,7 +352,7 @@ static int bxe_sysctl_reg_read(SYSCTL_HA
static int bxe_sysctl_breakpoint(SYSCTL_HANDLER_ARGS);
static void bxe_validate_rx_packet(struct bxe_fastpath *, uint16_t,
union eth_rx_cqe *, struct mbuf *);
-static void bxe_dump_grc(struct bxe_softc *, int);
+static void bxe_grcdump(struct bxe_softc *, int);
static void bxe_dump_enet(struct bxe_softc *,struct mbuf *);
static void bxe_dump_mbuf (struct bxe_softc *, struct mbuf *);
static void bxe_dump_tx_mbuf_chain(struct bxe_softc *, int, int);
@@ -8585,16 +8585,22 @@ bxe_tx_encap(struct bxe_fastpath *fp, st
error = bus_dmamap_load_mbuf_sg(fp->tx_mbuf_tag, map, m0,
segs, &nsegs, BUS_DMA_NOWAIT);
do{
- /* Handle any mapping errors. */
+ /* Handle any mapping errors. */
if(__predict_false(error)){
if (error == ENOMEM) {
+ /* Temporary OS resource issue. */
rc = ENOMEM;
}else if (error == EFBIG) {
+ /* Possibly recoverable. */
+ DBRUN(fp->mbuf_defrag_attempts++);
m0 = m_defrag(*m_head, M_DONTWAIT);
if (m0 == NULL) {
+ BXE_PRINTF("%s(%d): Can't defrag TX frame!\n",
+ __FILE__, __LINE__);
rc = ENOBUFS;
} else {
/* Defrag was successful, try mapping again.*/
+ DBRUN(fp->mbuf_defrag_successes++);
*m_head = m0;
error =
bus_dmamap_load_mbuf_sg(
@@ -8602,10 +8608,15 @@ bxe_tx_encap(struct bxe_fastpath *fp, st
segs, &nsegs, BUS_DMA_NOWAIT);
}
}else {
+ /* Unrecoverable. */
+ BXE_PRINTF("%s(%d): Unknown TX mapping error! "
+ "rc = %d.\n", __FILE__, __LINE__, error);
+ DBRUN(bxe_dump_mbuf(sc, m0));
rc = error;
}
break;
}
+
/*
* Now that we know how many buffer descriptors are required to
* send the frame, check whether we have enough transmit BD's
@@ -8615,29 +8626,39 @@ bxe_tx_encap(struct bxe_fastpath *fp, st
if (__predict_false((nsegs + 2) >
(USABLE_TX_BD - fp->used_tx_bd))) {
bus_dmamap_unload(fp->tx_mbuf_tag, map);
+ BXE_PRINTF("%s(%d): Insufficient TX queue space!\n",
+ __FILE__, __LINE__);
+ /* DRC - Should we drop a frame with this error? */
rc = ENOBUFS;
break;
}
+
/* Now make sure it fits in the pkt window */
- if (nsegs > 12) {
- /* The mbuf has more segments than the controller can handle.
- * Try to defrag the mbuf if there are too many
- * segments. If it can't be defragged then
- * drop the frame, log an error, and exit.
- * An alternative would be to use a bounce buffer.
- */
+ if (__predict_false(nsegs > 12)) {
+ /* The mbuf has more segments than the controller can
+ * handle. Try to defrag the mbuf if there are too many
+ * segments. If it can't be defragged then
+ * drop the frame, log an error, and exit.
+ * An alternative would be to use a bounce buffer.
+ */
if(m0->m_pkthdr.csum_flags & CSUM_TSO){
if (! bxe_chktso_window(sc,nsegs,segs,m0))
/* Send it */
break;
}
+
/* Defrag for non tso and if tso needs it */
+ DBRUN(fp->mbuf_defrag_attempts++);
m0 = m_defrag(*m_head, M_DONTWAIT);
if (m0 == NULL) {
+ BXE_PRINTF("%s(%d): Can't defrag TX frame!\n",
+ __FILE__, __LINE__);
rc = ENOBUFS;
break;
}
+
/* Defrag was successful, try mapping again. */
+ DBRUN(fp->mbuf_defrag_successes++);
*m_head = m0;
error =
bus_dmamap_load_mbuf_sg(
@@ -8654,6 +8675,8 @@ bxe_tx_encap(struct bxe_fastpath *fp, st
/* The frame can't be defragged,
* drop it.
*/
+ BXE_PRINTF("%s(%d): Can't map TX frame!\n",
+ __FILE__, __LINE__);
rc = error;
}
break;
@@ -8663,6 +8686,8 @@ bxe_tx_encap(struct bxe_fastpath *fp, st
if (bxe_chktso_window(sc,nsegs,segs,m0))
rc = ENOBUFS;
} else if (nsegs > 12 ){
+ BXE_PRINTF("%s(%d): Too many fragments for a TSO "
+ "frame!\n", __FILE__, __LINE__);
rc = ENOBUFS;
}
}
@@ -8672,15 +8697,13 @@ bxe_tx_encap(struct bxe_fastpath *fp, st
if (rc){
if(rc == ENOMEM){
/* Recoverable try again later */
- BXE_PRINTF("%s(%d): Error mapping mbuf into TX chain"
- "returning pkt to queue\n",__FILE__, __LINE__);
+ BXE_PRINTF("%s(%d): Error mapping mbuf into TX chain, "
+ "returning pkt to queue!\n",__FILE__, __LINE__);
}else{
fp->soft_tx_errors++;
DBRUN(fp->tx_mbuf_alloc--);
m_freem(*m_head);
*m_head = NULL;
- BXE_PRINTF("%s(%d): Error mapping mbuf into TX chain"
- "Frame dropped \n",__FILE__, __LINE__);
}
return (rc);
}
@@ -14838,7 +14861,7 @@ bxe_rxeof(struct bxe_fastpath *fp)
/*
* The high level logic used here is to
- * immediatley replace each receive buffer
+ * immediatley replace each receive buffer
* as it is used so that the receive chain
* is full at all times. First we try to
* allocate a new receive buffer, but if
@@ -15497,7 +15520,7 @@ bxe_sysctl_reg_read(SYSCTL_HANDLER_ARGS)
* 0 for success, positive value for failure.
*/
static int
-bxe_sysctl_dump_grc(SYSCTL_HANDLER_ARGS)
+bxe_sysctl_grcdump(SYSCTL_HANDLER_ARGS)
{
struct bxe_softc *sc;
int error, result;
@@ -15510,10 +15533,10 @@ bxe_sysctl_dump_grc(SYSCTL_HANDLER_ARGS)
if (result == 1) {
/* Generate a grcdump and log the contents.*/
- bxe_dump_grc(sc, 1);
+ bxe_grcdump(sc, 1);
} else {
/* Generate a grcdump and don't log the contents. */
- bxe_dump_grc(sc, 0);
+ bxe_grcdump(sc, 0);
}
return (error);
@@ -15555,13 +15578,18 @@ bxe_sysctl_breakpoint(SYSCTL_HANDLER_ARG
static void
bxe_add_sysctls(struct bxe_softc *sc)
{
- struct sysctl_ctx_list *ctx;
- struct sysctl_oid_list *children;
- struct bxe_eth_stats *estats;
+ struct sysctl_ctx_list *ctx =
+ device_get_sysctl_ctx(sc->bxe_dev);
+ struct sysctl_oid_list *children =
+ SYSCTL_CHILDREN(device_get_sysctl_tree(sc->bxe_dev));
+ struct bxe_eth_stats *estats = &sc->eth_stats;
+
+ struct sysctl_oid *queue_node;
+ struct sysctl_oid_list *queue_list;
+
+#define QUEUE_NAME_LEN 32
+ char namebuf[QUEUE_NAME_LEN];
- estats = &sc->eth_stats;
- ctx = device_get_sysctl_ctx(sc->bxe_dev);
- children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->bxe_dev));
SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
"estats_total_bytes_received_hi",
@@ -15676,36 +15704,60 @@ bxe_add_sysctls(struct bxe_softc *sc)
CTLFLAG_RD, &sc->mbuf_alloc_failed, 0,
"mbuf cluster allocation failures");
+ for (int i = 0; i < sc->num_queues; i++) {
+ struct bxe_fastpath *fp = &sc->fp[i];
+ snprintf(namebuf, QUEUE_NAME_LEN, "fp[%02d]", i);
+
+ queue_node = SYSCTL_ADD_NODE(ctx, children, OID_AUTO,
+ namebuf, CTLFLAG_RD, NULL, "Queue Name");
+ queue_list = SYSCTL_CHILDREN(queue_node);
+
+ SYSCTL_ADD_ULONG(ctx, queue_list, OID_AUTO,
+ "mbuf_alloc_failed",
+ CTLFLAG_RD, &fp->mbuf_alloc_failed,
+ "Mbuf allocation failures");
+
+ SYSCTL_ADD_ULONG(ctx, queue_list, OID_AUTO,
+ "mbuf_defrag_attempts",
+ CTLFLAG_RD, &fp->mbuf_defrag_attempts,
+ "Mbuf defrag attempts");
+
+ SYSCTL_ADD_ULONG(ctx, queue_list, OID_AUTO,
+ "mbuf_defrag_successes",
+ CTLFLAG_RD, &fp->mbuf_defrag_successes,
+ "Mbuf defrag successes");
+ }
+
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "driver_state",
- CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, bxe_sysctl_driver_state,
- "I", "Drive state information");
+ CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0,
+ bxe_sysctl_driver_state, "I", "Drive state information");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "hw_state",
- CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, bxe_sysctl_hw_state,
- "I", "Hardware state information");
+ CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0,
+ bxe_sysctl_hw_state, "I", "Hardware state information");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "dump_fw",
- CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, bxe_sysctl_dump_fw,
- "I", "Dump MCP firmware");
+ CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0,
+ bxe_sysctl_dump_fw, "I", "Dump MCP firmware");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "dump_rx_chain",
- CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, bxe_sysctl_dump_rx_chain,
- "I", "Dump rx_bd chain");
+ CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0,
+ bxe_sysctl_dump_rx_chain, "I", "Dump rx_bd chain");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "dump_cqe_chain",
- CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, bxe_sysctl_dump_cqe_chain,
- "I", "Dump cqe chain");
+ CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0,
+ bxe_sysctl_dump_cqe_chain, "I", "Dump cqe chain");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "dump_tx_chain",
- CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, bxe_sysctl_dump_tx_chain,
- "I", "Dump tx_bd chain");
+ CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0,
+ bxe_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
/*
* Generates a GRCdump (run sysctl dev.bxe.0.grcdump=0
- * before access buffer below).
+ * before accessing buffer below).
*/
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "grcdump",
- CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, bxe_sysctl_dump_grc,
+ CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, bxe_sysctl_grcdump,
"I", "Initiate a grcdump operation");
/*
@@ -15713,16 +15765,17 @@ bxe_add_sysctls(struct bxe_softc *sc)
* Use "sysctl -b dev.bxe.0.grcdump_buffer > buf.bin".
*/
SYSCTL_ADD_OPAQUE(ctx, children, OID_AUTO, "grcdump_buffer",
- CTLFLAG_RD | CTLFLAG_SKIP, sc->grcdump_buffer, BXE_GRCDUMP_BUF_SIZE,
- "IU", "Grcdump buffer");
+ CTLFLAG_RD | CTLFLAG_SKIP, sc->grcdump_buffer,
+ BXE_GRCDUMP_BUF_SIZE, "IU", "Access grcdump buffer");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "breakpoint",
- CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, bxe_sysctl_breakpoint,
- "I", "Driver breakpoint");
+ CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0,
+ bxe_sysctl_breakpoint, "I", "Driver breakpoint");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "reg_read",
- CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, bxe_sysctl_reg_read,
- "I", "Register read");
+ CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0,
+ bxe_sysctl_reg_read, "I", "Register read");
+
#endif /* BXE_DEBUG */
}
@@ -15886,7 +15939,7 @@ bxe_dump_debug_reg_wread(struct bxe_soft
* None.
*/
static void
-bxe_dump_grc(struct bxe_softc *sc, int log)
+bxe_grcdump(struct bxe_softc *sc, int log)
{
uint32_t *buf, i, index;
Modified: head/sys/dev/bxe/if_bxe.h
==============================================================================
--- head/sys/dev/bxe/if_bxe.h Thu Mar 31 21:21:07 2011 (r220225)
+++ head/sys/dev/bxe/if_bxe.h Thu Mar 31 21:30:00 2011 (r220226)
@@ -1084,6 +1084,8 @@ struct bxe_fastpath {
/* Memory buffer allocation failure counter. */
unsigned long mbuf_alloc_failed;
+ unsigned long mbuf_defrag_attempts;
+ unsigned long mbuf_defrag_successes;
/* Track the number of enqueued mbufs. */
int tx_mbuf_alloc;
More information about the svn-src-all
mailing list