Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Nov 2015 22:20:49 +0000 (UTC)
From:      "Conrad E. Meyer" <cem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r291034 - head/sys/dev/ntb/if_ntb
Message-ID:  <201511182220.tAIMKn35084518@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cem
Date: Wed Nov 18 22:20:49 2015
New Revision: 291034
URL: https://svnweb.freebsd.org/changeset/base/291034

Log:
  if_ntb: Reuse receive buffers correctly
  
  Discard the unused rx_free_q.  Instead, reuse inputed packets by putting
  them back on the *pend* queue after reinitialization.
  
  If tx or rx handlers are unavailable, free mbufs rather than leaking
  them.
  
  With this change, if_ntb can receive more than 100
  (NTB_QP_DEF_NUM_ENTRIES) packets.
  
  Sponsored by:	EMC / Isilon Storage Division

Modified:
  head/sys/dev/ntb/if_ntb/if_ntb.c

Modified: head/sys/dev/ntb/if_ntb/if_ntb.c
==============================================================================
--- head/sys/dev/ntb/if_ntb/if_ntb.c	Wed Nov 18 22:20:40 2015	(r291033)
+++ head/sys/dev/ntb/if_ntb/if_ntb.c	Wed Nov 18 22:20:49 2015	(r291034)
@@ -164,7 +164,6 @@ struct ntb_transport_qp {
 	    void *data, int len);
 	struct ntb_queue_list	rx_post_q;
 	struct ntb_queue_list	rx_pend_q;
-	struct ntb_queue_list	rx_free_q;
 	/* ntb_rx_q_lock: synchronize access to rx_XXXX_q */
 	struct mtx		ntb_rx_q_lock;
 	struct task		rx_completion_task;
@@ -718,7 +717,6 @@ ntb_transport_init_queue(struct ntb_tran
 
 	STAILQ_INIT(&qp->rx_post_q);
 	STAILQ_INIT(&qp->rx_pend_q);
-	STAILQ_INIT(&qp->rx_free_q);
 	STAILQ_INIT(&qp->tx_free_q);
 
 	callout_reset(&qp->link_work, 0, ntb_qp_link_work, qp);
@@ -743,9 +741,6 @@ ntb_transport_free_queue(struct ntb_tran
 	qp->tx_handler = NULL;
 	qp->event_handler = NULL;
 
-	while ((entry = ntb_list_rm(&qp->ntb_rx_q_lock, &qp->rx_free_q)))
-		free(entry, M_NTB_IF);
-
 	while ((entry = ntb_list_rm(&qp->ntb_rx_q_lock, &qp->rx_pend_q)))
 		free(entry, M_NTB_IF);
 
@@ -910,8 +905,11 @@ ntb_process_tx(struct ntb_transport_qp *
 	if (entry->len > qp->tx_max_frame - sizeof(struct ntb_payload_header)) {
 		if (qp->tx_handler != NULL)
 			qp->tx_handler(qp, qp->cb_data, entry->buf,
-				       EIO);
+			    EIO);
+		else
+			m_freem(entry->buf);
 
+		entry->buf = NULL;
 		ntb_list_add(&qp->ntb_tx_free_q_lock, entry, &qp->tx_free_q);
 		CTR1(KTR_NTB,
 		    "TX: frame too big. returning entry %p to tx_free_q",
@@ -969,8 +967,11 @@ ntb_memcpy_tx(struct ntb_transport_qp *q
 		qp->tx_bytes += entry->len;
 
 		if (qp->tx_handler)
-			qp->tx_handler(qp, qp->cb_data, entry->cb_data,
-				       entry->len);
+			qp->tx_handler(qp, qp->cb_data, entry->buf,
+			    entry->len);
+		else
+			m_freem(entry->buf);
+		entry->buf = NULL;
 	}
 
 	CTR3(KTR_NTB,
@@ -1146,17 +1147,28 @@ ntb_complete_rxc(void *arg, int pending)
 		entry->x_hdr->flags = 0;
 		iowrite32(entry->index, &qp->rx_info->entry);
 
+		STAILQ_REMOVE_HEAD(&qp->rx_post_q, entry);
+
 		len = entry->len;
 		m = entry->buf;
 
-		STAILQ_REMOVE_HEAD(&qp->rx_post_q, entry);
-		STAILQ_INSERT_TAIL(&qp->rx_free_q, entry, entry);
+		/*
+		 * Re-initialize queue_entry for reuse; rx_handler takes
+		 * ownership of the mbuf.
+		 */
+		entry->buf = NULL;
+		entry->len = transport_mtu;
+		entry->cb_data = qp->transport->ifp;
+
+		STAILQ_INSERT_TAIL(&qp->rx_pend_q, entry, entry);
 
 		mtx_unlock_spin(&qp->ntb_rx_q_lock);
 
 		CTR2(KTR_NTB, "RX: completing entry %p, mbuf %p", entry, m);
 		if (qp->rx_handler != NULL && qp->client_ready)
 			qp->rx_handler(qp, qp->cb_data, m, len);
+		else
+			m_freem(m);
 
 		mtx_lock_spin(&qp->ntb_rx_q_lock);
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201511182220.tAIMKn35084518>