summaryrefslogtreecommitdiffstats
path: root/sys/pci
diff options
context:
space:
mode:
authorsilby <silby@FreeBSD.org>2003-03-29 17:50:37 +0000
committersilby <silby@FreeBSD.org>2003-03-29 17:50:37 +0000
commite60a42f980067db5924e28c8a23a41768b12cdfe (patch)
treeb3a6f7be10411abeede303ab3ba29365cdcc1084 /sys/pci
parent86761e7dd6cf3456bb1aae5858988badf423a7f1 (diff)
downloadFreeBSD-src-e60a42f980067db5924e28c8a23a41768b12cdfe.zip
FreeBSD-src-e60a42f980067db5924e28c8a23a41768b12cdfe.tar.gz
Have sis_encap use m_defrag if:
1. The chain passed in is > 31 fragments long or 2. The chain will not fit in the remaining descriptors without defragmentation. This is slightly less clear than other network drivers because the sis chips share one descriptor list for all packets, it seems. Before this change, a > 127 fragment chain would get stuck in the IFQUEUE permanently, bringing all network traffic to a halt. MFC after: 2 weeks
Diffstat (limited to 'sys/pci')
-rw-r--r--sys/pci/if_sis.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/sys/pci/if_sis.c b/sys/pci/if_sis.c
index 7f72c39..fa4006e 100644
--- a/sys/pci/if_sis.c
+++ b/sys/pci/if_sis.c
@@ -1878,9 +1878,33 @@ sis_encap(sc, m_head, txidx)
{
struct sis_desc *f = NULL;
struct mbuf *m;
- int frag, cur, cnt = 0;
+ int frag, cur, cnt = 0, chainlen = 0;
/*
+ * If there's no way we can send any packets, return now.
+ */
+ if (SIS_TX_LIST_CNT - sc->sis_cdata.sis_tx_cnt < 2)
+ return (ENOBUFS);
+
+ /*
+ * Count the number of frags in this chain to see if
+ * we need to m_defrag. Since the descriptor list is shared
+ * by all packets, we'll m_defrag long chains so that they
+ * do not use up the entire list, even if they would fit.
+ */
+
+ for (m = m_head; m != NULL; m = m->m_next)
+ chainlen++;
+
+ if ((chainlen > SIS_TX_LIST_CNT / 4) ||
+ ((SIS_TX_LIST_CNT - (chainlen + sc->sis_cdata.sis_tx_cnt)) < 2)) {
+ m = m_defrag(m_head, M_DONTWAIT);
+ if (m == NULL)
+ return (ENOBUFS);
+ m_head = m;
+ }
+
+ /*
* Start packing the mbufs in this chain into
* the fragment pointers. Stop when we run out
* of fragments or hit the end of the mbuf chain.
OpenPOWER on IntegriCloud