aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2021-02-22 22:21:05 +0000
committerAlexander Motin <mav@FreeBSD.org>2021-02-25 01:40:29 +0000
commit1f3cff343b451d9fc9c10f4f8c4b416ed5eae23f (patch)
treecf0a3792a03ace06753a6655bb2b30bb0a4c140d
parent1c1460747efd44eb74762b960883656b56134e30 (diff)
downloadsrc-1f3cff343b451d9fc9c10f4f8c4b416ed5eae23f.tar.gz
src-1f3cff343b451d9fc9c10f4f8c4b416ed5eae23f.zip
cxgb(4): Rework my commit 9dc7c250.
The previous implementation was reported to try to coalesce packets in situations when it should not, that resulted in assertion later. This implementation better checks the first packet of the chain for the coallescing elligibility. (cherry picked from commit d510bf133d045d6c83742aeda6949bec150f6cbf)
-rw-r--r--sys/dev/cxgb/cxgb_sge.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c
index 491d1a751f4a..f13d2f03180c 100644
--- a/sys/dev/cxgb/cxgb_sge.c
+++ b/sys/dev/cxgb/cxgb_sge.c
@@ -312,20 +312,22 @@ set_wr_hdr(struct work_request_hdr *wrp, uint32_t wr_hi, uint32_t wr_lo)
struct coalesce_info {
int count;
int nbytes;
+ int noncoal;
};
static int
coalesce_check(struct mbuf *m, void *arg)
{
struct coalesce_info *ci = arg;
- int *count = &ci->count;
- int *nbytes = &ci->nbytes;
-
- if ((*nbytes == 0) || ((*nbytes + m->m_len <= 10500) &&
- (*count < 7) && (m->m_next == NULL) &&
- ((mtod(m, vm_offset_t) & PAGE_MASK) + m->m_len <= PAGE_SIZE))) {
- *count += 1;
- *nbytes += m->m_len;
+
+ if ((m->m_next != NULL) ||
+ ((mtod(m, vm_offset_t) & PAGE_MASK) + m->m_len > PAGE_SIZE))
+ ci->noncoal = 1;
+
+ if ((ci->count == 0) || (ci->noncoal == 0 && (ci->count < 7) &&
+ (ci->nbytes + m->m_len <= 10500))) {
+ ci->count++;
+ ci->nbytes += m->m_len;
return (1);
}
return (0);
@@ -342,7 +344,7 @@ cxgb_dequeue(struct sge_qset *qs)
return TXQ_RING_DEQUEUE(qs);
m_head = m_tail = NULL;
- ci.count = ci.nbytes = 0;
+ ci.count = ci.nbytes = ci.noncoal = 0;
do {
m = TXQ_RING_DEQUEUE_COND(qs, coalesce_check, &ci);
if (m_head == NULL) {