[1.6,3/3] linux-dpdk: pool: fix buffer size calculation

Message ID 1456838772-16600-4-git-send-email-zoltan.kiss@linaro.org
State New
Headers show

Commit Message

Zoltan Kiss March 1, 2016, 1:26 p.m.
Some cards round down the buffers (without the headroom) to the nearest
multiple of 1024. When enabling jumbo frame the max buffer size is
checked, and if it doesn't fit into a single segment it enables
scatter-gather on RX side, but not on TX. To avoid complications, make
sure every pool segment size aligns to n * 1024 + headroom, and that the
RX configuration uses jumbo frame size adequate for that pool's segment
size.

Signed-off-by: Zoltan Kiss <zoltan.kiss@linaro.org>
---
 platform/linux-dpdk/include/odp/config.h | 4 ++--
 platform/linux-dpdk/odp_packet_dpdk.c    | 8 ++++++--
 platform/linux-dpdk/odp_pool.c           | 7 +++++++
 3 files changed, 15 insertions(+), 4 deletions(-)

Patch hide | download patch | download mbox

diff --git a/platform/linux-dpdk/include/odp/config.h b/platform/linux-dpdk/include/odp/config.h
index 90952b9..27cc385 100644
--- a/platform/linux-dpdk/include/odp/config.h
+++ b/platform/linux-dpdk/include/odp/config.h
@@ -140,7 +140,7 @@  static inline int odp_config_packet_tailroom(void)
  * defined segment length (seg_len in odp_pool_param_t) will be rounded up into
  * this value.
  */
-#define ODP_CONFIG_PACKET_SEG_LEN_MIN 1598
+#define ODP_CONFIG_PACKET_SEG_LEN_MIN 1024
 static inline int odp_config_packet_seg_len_min(void)
 {
 	return ODP_CONFIG_PACKET_SEG_LEN_MIN;
@@ -171,7 +171,7 @@  static inline int odp_config_packet_seg_len_max(void)
  * - The value MUST be an integral number of segments
  * - The value SHOULD be large enough to accommodate jumbo packets (9K)
  */
-#define ODP_CONFIG_PACKET_BUF_LEN_MAX (ODP_CONFIG_PACKET_SEG_LEN_MIN * 6)
+#define ODP_CONFIG_PACKET_BUF_LEN_MAX (ODP_CONFIG_PACKET_SEG_LEN_MIN * 9)
 static inline int odp_config_packet_buf_len_max(void)
 {
 	return ODP_CONFIG_PACKET_BUF_LEN_MAX;
diff --git a/platform/linux-dpdk/odp_packet_dpdk.c b/platform/linux-dpdk/odp_packet_dpdk.c
index c4c1a9e..995d995 100644
--- a/platform/linux-dpdk/odp_packet_dpdk.c
+++ b/platform/linux-dpdk/odp_packet_dpdk.c
@@ -106,8 +106,12 @@  static int setup_pkt_dpdk(odp_pktio_t pktio ODP_UNUSED, pktio_entry_t *pktio_ent
 		},
 	};
 
-	/* rx packet len same size as pool segment */
-	port_conf.rxmode.max_rx_pkt_len = pool_entry->s.rte_mempool->elt_size;
+	/* rx packet len same size as pool segment minus headroom and double
+	 * VLAN tag
+	 */
+	port_conf.rxmode.max_rx_pkt_len =
+		rte_pktmbuf_data_room_size(pool_entry->s.rte_mempool) -
+		2 * 4 - RTE_PKTMBUF_HEADROOM;
 
 	if (!_dpdk_netdev_is_valid(netdev))
 		return -1;
diff --git a/platform/linux-dpdk/odp_pool.c b/platform/linux-dpdk/odp_pool.c
index 8722871..6d6a11a 100644
--- a/platform/linux-dpdk/odp_pool.c
+++ b/platform/linux-dpdk/odp_pool.c
@@ -110,6 +110,7 @@  struct mbuf_ctor_arg {
 };
 
 struct mbuf_pool_ctor_arg {
+	/* This has to be the first member */
 	struct rte_pktmbuf_pool_private pkt;
 	odp_pool_t	pool_hdl;
 };
@@ -266,6 +267,12 @@  odp_pool_t odp_pool_create(const char *name, odp_pool_param_t *params)
 				ODP_CONFIG_BUFFER_ALIGN_MIN);
 			blk_size = params->pkt.len <= seg_len ? seg_len :
 				ODP_ALIGN_ROUNDUP(params->pkt.len, seg_len);
+			/* Segment size minus headroom will be rounded down to
+			 * the nearest multiple of 1024, make sure we still can
+			 * fit the requested packets there without segmentation
+			 */
+			blk_size = ODP_ALIGN_ROUNDUP(blk_size - headroom, ODP_CONFIG_PACKET_SEG_LEN_MIN) +
+				   headroom;
 
 			/* Reject create if pkt.len needs too many segments */
 			if (blk_size / seg_len > ODP_BUFFER_MAX_SEG) {