DPDK patches and discussions
 help / color / mirror / Atom feed
From: Declan Doherty <declan.doherty@intel.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v2 4/6] bond: free mbufs if transmission fails in bonding tx_burst functions
Date: Mon,  1 Sep 2014 09:31:27 +0100
Message-ID: <1409560289-29558-5-git-send-email-declan.doherty@intel.com> (raw)
In-Reply-To: <1408456313-28812-1-git-send-email-declan.doherty@intel.com>

Fixing a number of corner cases that if transmission failed on slave devices then this
could lead to leaked mbufs 

V2 addresses behaviouraly issues in the first version and packets are no longer freed in
the bonding layer, except in the case of broadcast mode where in failures happen on 
more than a single slave then mbufs will be freed in all slaves except the one where
the least errors occured. Also contains new unit tests to test the transmission
 failure case in slaves for 
round-robin, balance, and broadcast modes.

 
Signed-off-by: Declan Doherty <declan.doherty@intel.com>
---
 app/test/test_link_bonding.c           |  393 +++++++++++++++++++++++++++++++-
 app/test/virtual_pmd.c                 |   80 +++++--
 app/test/virtual_pmd.h                 |    7 +
 lib/librte_pmd_bond/rte_eth_bond_pmd.c |   83 ++++++--
 4 files changed, 525 insertions(+), 38 deletions(-)

diff --git a/app/test/test_link_bonding.c b/app/test/test_link_bonding.c
index cce32ed..c5aaa80 100644
--- a/app/test/test_link_bonding.c
+++ b/app/test/test_link_bonding.c
@@ -663,6 +663,9 @@ enable_bonded_slaves(void)
 	int i;
 
 	for (i = 0; i < test_params->bonded_slave_count; i++) {
+		virtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],
+				1);
+
 		virtual_ethdev_simulate_link_status_interrupt(
 				test_params->slave_port_ids[i], 1);
 	}
@@ -1413,6 +1416,135 @@ test_roundrobin_tx_burst(void)
 }
 
 static int
+verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
+{
+	int i, refcnt;
+
+	for (i = 0; i < nb_mbufs; i++) {
+		refcnt = rte_mbuf_refcnt_read(mbufs[i]);
+		TEST_ASSERT_EQUAL(refcnt, val,
+			"mbuf ref count (%d)is not the expected value (%d)",
+			refcnt, val);
+	}
+	return 0;
+}
+
+
+static void
+free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)
+{
+	int i;
+
+	for (i = 0; i < nb_mbufs; i++)
+		rte_pktmbuf_free(mbufs[i]);
+}
+
+#define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT		(2)
+#define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE		(64)
+#define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT		(22)
+#define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX	(1)
+
+static int
+test_roundrobin_tx_burst_slave_tx_fail(void)
+{
+	struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
+	struct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];
+
+	struct rte_eth_stats port_stats;
+
+	int i, first_fail_idx, tx_count;
+
+	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
+			BONDING_MODE_ROUND_ROBIN, 0,
+			TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
+			"Failed to intialise bonded device");
+
+	/* Generate test bursts of packets to transmit */
+	TEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,
+			TEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),
+			TEST_RR_SLAVE_TX_FAIL_BURST_SIZE,
+			"Failed to generate test packet burst");
+
+	/* Copy references to packets which we expect not to be transmitted */
+	first_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
+			(TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *
+			TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +
+			TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;
+
+	for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
+		expected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +
+				(i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];
+	}
+
+	/* Set virtual slave to only fail transmission of
+	 * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */
+	virtual_ethdev_tx_burst_fn_set_success(
+			test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
+			0);
+
+	virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
+			test_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
+			TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
+
+	tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,
+			TEST_RR_SLAVE_TX_FAIL_BURST_SIZE);
+
+	TEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
+			TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
+			"Transmitted (%d) an unexpected (%d) number of packets", tx_count,
+			TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
+			TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
+
+	/* Verify that failed packet are expected failed packets */
+	for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
+		TEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],
+				"expected mbuf (%d) pointer %p not expected pointer %p",
+				i, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);
+	}
+
+	/* Verify bonded port tx stats */
+	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
+
+	TEST_ASSERT_EQUAL(port_stats.opackets,
+			(uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
+			TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,
+			"Bonded Port (%d) opackets value (%u) not as expected (%d)",
+			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
+			TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -
+			TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
+
+	/* Verify slave ports tx stats */
+	for (i = 0; i < test_params->bonded_slave_count; i++) {
+		int slave_expected_tx_count;
+
+		rte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);
+
+		slave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /
+				test_params->bonded_slave_count;
+
+		if (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)
+			slave_expected_tx_count = slave_expected_tx_count -
+					TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;
+
+		TEST_ASSERT_EQUAL(port_stats.opackets,
+				(uint64_t)slave_expected_tx_count,
+				"Slave Port (%d) opackets value (%u) not as expected (%d)",
+				test_params->slave_port_ids[i],
+				(unsigned int)port_stats.opackets, slave_expected_tx_count);
+	}
+
+	/* Verify that all mbufs have a ref value of zero */
+	TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
+			TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
+			"mbufs refcnts not as expected");
+
+	free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
+
+	/* Clean up and remove slaves from bonded device */
+	return remove_slaves_and_stop_bonded_device();
+}
+
+static int
 test_roundrobin_rx_burst_on_single_slave(void)
 {
 	struct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };
@@ -2900,6 +3032,141 @@ test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)
 	return balance_l34_tx_burst(0, 0, 0, 0, 1);
 }
 
+#define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT			(2)
+#define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1			(40)
+#define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2			(20)
+#define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT		(25)
+#define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX	(0)
+
+static int
+test_balance_tx_burst_slave_tx_fail(void)
+{
+	struct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];
+	struct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];
+
+	struct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];
+
+	struct rte_eth_stats port_stats;
+
+	int i, first_tx_fail_idx, tx_count_1, tx_count_2;
+
+	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
+			BONDING_MODE_BALANCE, 0,
+			TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
+			"Failed to intialise bonded device");
+
+	TEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(
+			test_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),
+			"Failed to set balance xmit policy.");
+
+
+	/* Generate test bursts for transmission */
+	TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,
+			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),
+			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,
+			"Failed to generate test packet burst 1");
+
+	first_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
+			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;
+
+	/* copy mbuf referneces for expected transmission failures */
+	for (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
+		expected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];
+	}
+
+	TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,
+			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),
+			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
+			"Failed to generate test packet burst 2");
+
+
+	/* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
+	 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
+	virtual_ethdev_tx_burst_fn_set_success(
+			test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
+			0);
+
+	virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
+			test_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],
+			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
+
+
+	/* Transmit burst 1 */
+	tx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,
+			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);
+
+	TEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
+			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
+			"Transmitted (%d) packets, expected to transmit (%d) packets",
+			tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
+			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
+
+	/* Verify that failed packet are expected failed packets */
+	for (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {
+		TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],
+				"expected mbuf (%d) pointer %p not expected pointer %p",
+				i, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);
+	}
+
+	/* Transmit burst 2 */
+	tx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,
+			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
+
+	TEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
+			"Transmitted (%d) packets, expected to transmit (%d) packets",
+			tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
+
+
+	/* Verify bonded port tx stats */
+	rte_eth_stats_get(test_params->bonded_port_id, &port_stats);
+
+	TEST_ASSERT_EQUAL(port_stats.opackets,
+			(uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
+			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
+			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),
+			"Bonded Port (%d) opackets value (%u) not as expected (%d)",
+			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
+			(TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
+			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +
+			TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
+
+	/* Verify slave ports tx stats */
+
+	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
+
+	TEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)
+				TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
+				TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,
+				"Slave Port (%d) opackets value (%u) not as expected (%d)",
+				test_params->slave_port_ids[0],
+				(unsigned int)port_stats.opackets,
+				TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -
+				TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
+
+
+
+
+	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
+
+	TEST_ASSERT_EQUAL(port_stats.opackets,
+				(uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,
+				"Slave Port (%d) opackets value (%u) not as expected (%d)",
+				test_params->slave_port_ids[1],
+				(unsigned int)port_stats.opackets,
+				TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
+
+	/* Verify that all mbufs have a ref value of zero */
+	TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
+			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
+			"mbufs refcnts not as expected");
+
+	free_mbufs(&pkts_burst_1[tx_count_1],
+			TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
+
+	/* Clean up and remove slaves from bonded device */
+	return remove_slaves_and_stop_bonded_device();
+}
+
 #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)
 
 static int
@@ -3412,7 +3679,7 @@ test_broadcast_tx_burst(void)
 	/* Send burst on bonded port */
 	nb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
 			burst_size);
-	if (nb_tx != burst_size * test_params->bonded_slave_count) {
+	if (nb_tx != burst_size) {
 		printf("Bonded Port (%d) rx burst failed, packets transmitted value (%u) not as expected (%d)\n",
 				test_params->bonded_port_id,
 				nb_tx, burst_size);
@@ -3455,6 +3722,125 @@ test_broadcast_tx_burst(void)
 	return remove_slaves_and_stop_bonded_device();
 }
 
+
+#define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT		(3)
+#define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE			(40)
+#define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT	(15)
+#define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT	(10)
+
+static int
+test_broadcast_tx_burst_slave_tx_fail(void)
+{
+	struct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];
+	struct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];
+
+	struct rte_eth_stats port_stats;
+
+	int i, tx_count;
+
+	TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
+			BONDING_MODE_BROADCAST, 0,
+			TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),
+			"Failed to intialise bonded device");
+
+	/* Generate test bursts for transmission */
+	TEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,
+			TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),
+			TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,
+			"Failed to generate test packet burst");
+
+	for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
+		expected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
+			TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];
+	}
+
+	/* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail
+	 * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */
+	virtual_ethdev_tx_burst_fn_set_success(
+			test_params->slave_port_ids[0],
+			0);
+	virtual_ethdev_tx_burst_fn_set_success(
+			test_params->slave_port_ids[1],
+			0);
+	virtual_ethdev_tx_burst_fn_set_success(
+			test_params->slave_port_ids[2],
+			0);
+
+	virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
+			test_params->slave_port_ids[0],
+			TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
+
+	virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
+			test_params->slave_port_ids[1],
+			TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
+
+	virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(
+			test_params->slave_port_ids[2],
+			TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
+
+	/* Transmit burst */
+	tx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,
+			TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);
+
+	TEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
+			TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
+			"Transmitted (%d) packets, expected to transmit (%d) packets",
+			tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
+			TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
+
+	/* Verify that failed packet are expected failed packets */
+	for (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {
+		TEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],
+				"expected mbuf (%d) pointer %p not expected pointer %p",
+				i, expected_fail_pkts[i], pkts_burst[i + tx_count]);
+	}
+
+	/* Verify slave ports tx stats */
+
+	rte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);
+
+	TEST_ASSERT_EQUAL(port_stats.opackets,
+			(uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
+			TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
+			"Port (%d) opackets value (%u) not as expected (%d)",
+			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
+			TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
+			TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
+
+
+	rte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);
+
+	TEST_ASSERT_EQUAL(port_stats.opackets,
+			(uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
+			TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,
+			"Port (%d) opackets value (%u) not as expected (%d)",
+			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
+			TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -s
+			TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
+
+	rte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);
+
+	TEST_ASSERT_EQUAL(port_stats.opackets,
+			(uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
+			TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,
+			"Port (%d) opackets value (%u) not as expected (%d)",
+			test_params->bonded_port_id, (unsigned int)port_stats.opackets,
+			TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -
+			TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);
+
+
+	/* Verify that all mbufs who transmission failed have a ref value of one */
+	TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],
+			TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),
+			"mbufs refcnts not as expected");
+
+	free_mbufs(&pkts_burst[tx_count],
+		TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);
+
+	/* Clean up and remove slaves from bonded device */
+	return remove_slaves_and_stop_bonded_device();
+}
+
 #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)
 
 static int
@@ -3767,7 +4153,7 @@ test_broadcast_verify_slave_link_status_change_behaviour(void)
 	}
 
 	if (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0],
-			burst_size) != (burst_size * slave_count)) {
+			burst_size) != burst_size) {
 		printf("rte_eth_tx_burst failed\n");
 		return -1;
 	}
@@ -3915,6 +4301,7 @@ static struct unit_test_suite link_bonding_test_suite  = {
 		TEST_CASE(test_status_interrupt),
 		TEST_CASE(test_adding_slave_after_bonded_device_started),
 		TEST_CASE(test_roundrobin_tx_burst),
+		TEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),
 		TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
 		TEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),
 		TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
@@ -3938,11 +4325,13 @@ static struct unit_test_suite link_bonding_test_suite  = {
 		TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),
 		TEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),
 		TEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),
+		TEST_CASE(test_balance_tx_burst_slave_tx_fail),
 		TEST_CASE(test_balance_rx_burst),
 		TEST_CASE(test_balance_verify_promiscuous_enable_disable),
 		TEST_CASE(test_balance_verify_mac_assignment),
 		TEST_CASE(test_balance_verify_slave_link_status_change_behaviour),
 		TEST_CASE(test_broadcast_tx_burst),
+		TEST_CASE(test_broadcast_tx_burst_slave_tx_fail),
 		TEST_CASE(test_broadcast_rx_burst),
 		TEST_CASE(test_broadcast_verify_promiscuous_enable_disable),
 		TEST_CASE(test_broadcast_verify_mac_assignment),
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index e861c5b..f9bd841 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -48,6 +48,8 @@ struct virtual_ethdev_private {
 
 	struct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST];
 	int rx_pkt_burst_len;
+
+	int tx_burst_fail_count;
 };
 
 struct virtual_ethdev_queue {
@@ -350,42 +352,67 @@ virtual_ethdev_rx_burst_fail(void *queue __rte_unused,
 }
 
 static uint16_t
-virtual_ethdev_tx_burst_success(void *queue,
-							 struct rte_mbuf **bufs __rte_unused,
-							 uint16_t nb_pkts)
+virtual_ethdev_tx_burst_success(void *queue, struct rte_mbuf **bufs,
+		uint16_t nb_pkts)
 {
+	struct virtual_ethdev_queue *tx_q = (struct virtual_ethdev_queue *)queue;
+
 	struct rte_eth_dev *vrtl_eth_dev;
-	struct virtual_ethdev_queue *tx_q;
 	struct virtual_ethdev_private *dev_private;
-	int i;
 
-	tx_q = (struct virtual_ethdev_queue *)queue;
+	int i;
 
 	vrtl_eth_dev = &rte_eth_devices[tx_q->port_id];
+	dev_private = vrtl_eth_dev->data->dev_private;
 
 	if (vrtl_eth_dev->data->dev_link.link_status) {
-		dev_private = vrtl_eth_dev->data->dev_private;
+		/* increment opacket count */
 		dev_private->eth_stats.opackets += nb_pkts;
 
-		return nb_pkts;
-	}
-
-	/* free packets in burst */
-	for (i = 0; i < nb_pkts; i++) {
-		if (bufs[i] != NULL)
+		/* free packets in burst */
+		for (i = 0; i < nb_pkts; i++) {
 			rte_pktmbuf_free(bufs[i]);
+			bufs[i] = NULL;
+		}
 
-		bufs[i] = NULL;
+		return nb_pkts;
 	}
 
 	return 0;
 }
 
-
 static uint16_t
-virtual_ethdev_tx_burst_fail(void *queue __rte_unused,
-		struct rte_mbuf **bufs __rte_unused, uint16_t nb_pkts __rte_unused)
+virtual_ethdev_tx_burst_fail(void *queue, struct rte_mbuf **bufs,
+		uint16_t nb_pkts)
 {
+	struct rte_eth_dev *vrtl_eth_dev = NULL;
+	struct virtual_ethdev_queue *tx_q = NULL;
+	struct virtual_ethdev_private *dev_private = NULL;
+
+	int i;
+
+	tx_q = (struct virtual_ethdev_queue *)queue;
+	vrtl_eth_dev = &rte_eth_devices[tx_q->port_id];
+	dev_private = vrtl_eth_dev->data->dev_private;
+
+	if (dev_private->tx_burst_fail_count < nb_pkts) {
+		int successfully_txd = nb_pkts - dev_private->tx_burst_fail_count;
+
+		/* increment opacket count */
+		dev_private->eth_stats.opackets += successfully_txd;
+
+		/* free packets in burst */
+		for (i = 0; i < successfully_txd; i++) {
+			/* free packets in burst */
+			if (bufs[i] != NULL)
+				rte_pktmbuf_free(bufs[i]);
+
+			bufs[i] = NULL;
+		}
+
+		return successfully_txd;
+	}
+
 	return 0;
 }
 
@@ -405,17 +432,34 @@ virtual_ethdev_rx_burst_fn_set_success(uint8_t port_id, uint8_t success)
 void
 virtual_ethdev_tx_burst_fn_set_success(uint8_t port_id, uint8_t success)
 {
+	struct virtual_ethdev_private *dev_private = NULL;
 	struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id];
 
+	dev_private = vrtl_eth_dev->data->dev_private;
+
 	if (success)
 		vrtl_eth_dev->tx_pkt_burst = virtual_ethdev_tx_burst_success;
 	else
 		vrtl_eth_dev->tx_pkt_burst = virtual_ethdev_tx_burst_fail;
+
+	dev_private->tx_burst_fail_count = 0;
 }
 
+void
+virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(uint8_t port_id,
+		uint8_t packet_fail_count)
+{
+	struct virtual_ethdev_private *dev_private = NULL;
+	struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id];
+
+
+	dev_private = vrtl_eth_dev->data->dev_private;
+	dev_private->tx_burst_fail_count = packet_fail_count;
+}
 
 void
-virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id, uint8_t link_status)
+virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id,
+		uint8_t link_status)
 {
 	struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id];
 
diff --git a/app/test/virtual_pmd.h b/app/test/virtual_pmd.h
index 766b6ac..3b5c911 100644
--- a/app/test/virtual_pmd.h
+++ b/app/test/virtual_pmd.h
@@ -67,6 +67,13 @@ void virtual_ethdev_rx_burst_fn_set_success(uint8_t port_id, uint8_t success);
 
 void virtual_ethdev_tx_burst_fn_set_success(uint8_t port_id, uint8_t success);
 
+/* if a value greater than zero is set for packet_fail_count then virtual
+ * device tx burst function will fail that many packet from burst or all
+ * packets if packet_fail_count is greater than the number of packets in the
+ * burst */
+void virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(uint8_t port_id,
+		uint8_t packet_fail_count);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_pmd_bond/rte_eth_bond_pmd.c b/lib/librte_pmd_bond/rte_eth_bond_pmd.c
index 70123fc..38cc1ae 100644
--- a/lib/librte_pmd_bond/rte_eth_bond_pmd.c
+++ b/lib/librte_pmd_bond/rte_eth_bond_pmd.c
@@ -101,10 +101,10 @@ bond_ethdev_tx_burst_round_robin(void *queue, struct rte_mbuf **bufs,
 	uint8_t num_of_slaves;
 	uint8_t slaves[RTE_MAX_ETHPORTS];
 
-	uint16_t num_tx_total = 0;
+	uint16_t num_tx_total = 0, num_tx_slave;
 
 	static int slave_idx = 0;
-	int i, cs_idx = 0;
+	int i, cslave_idx = 0, tx_fail_total = 0;
 
 	bd_tx_q = (struct bond_tx_queue *)queue;
 	internals = bd_tx_q->dev_private;
@@ -120,19 +120,32 @@ bond_ethdev_tx_burst_round_robin(void *queue, struct rte_mbuf **bufs,
 
 	/* Populate slaves mbuf with which packets are to be sent on it  */
 	for (i = 0; i < nb_pkts; i++) {
-		cs_idx = (slave_idx + i) % num_of_slaves;
-		slave_bufs[cs_idx][(slave_nb_pkts[cs_idx])++] = bufs[i];
+		cslave_idx = (slave_idx + i) % num_of_slaves;
+		slave_bufs[cslave_idx][(slave_nb_pkts[cslave_idx])++] = bufs[i];
 	}
 
 	/* increment current slave index so the next call to tx burst starts on the
 	 * next slave */
-	slave_idx = ++cs_idx;
+	slave_idx = ++cslave_idx;
 
 	/* Send packet burst on each slave device */
-	for (i = 0; i < num_of_slaves; i++)
-		if (slave_nb_pkts[i] > 0)
-			num_tx_total += rte_eth_tx_burst(slaves[i],
-					bd_tx_q->queue_id, slave_bufs[i], slave_nb_pkts[i]);
+	for (i = 0; i < num_of_slaves; i++) {
+		if (slave_nb_pkts[i] > 0) {
+			num_tx_slave = rte_eth_tx_burst(slaves[i], bd_tx_q->queue_id,
+					slave_bufs[i], slave_nb_pkts[i]);
+
+			/* if tx burst fails move packets to end of bufs */
+			if (unlikely(num_tx_slave < slave_nb_pkts[i])) {
+				int tx_fail_slave = slave_nb_pkts[i] - num_tx_slave;
+
+				tx_fail_total += tx_fail_slave;
+
+				memcpy(&bufs[nb_pkts - tx_fail_total],
+						&slave_bufs[i][num_tx_slave], tx_fail_slave * sizeof(bufs[0]));
+			}
+			num_tx_total += num_tx_slave;
+		}
+	}
 
 	return num_tx_total;
 }
@@ -283,7 +296,7 @@ bond_ethdev_tx_burst_balance(void *queue, struct rte_mbuf **bufs,
 	uint8_t num_of_slaves;
 	uint8_t slaves[RTE_MAX_ETHPORTS];
 
-	uint16_t num_tx_total = 0;
+	uint16_t num_tx_total = 0, num_tx_slave = 0, tx_fail_total = 0;
 
 	int i, op_slave_id;
 
@@ -315,11 +328,23 @@ bond_ethdev_tx_burst_balance(void *queue, struct rte_mbuf **bufs,
 	/* Send packet burst on each slave device */
 	for (i = 0; i < num_of_slaves; i++) {
 		if (slave_nb_pkts[i] > 0) {
-			num_tx_total += rte_eth_tx_burst(slaves[i], bd_tx_q->queue_id,
+			num_tx_slave = rte_eth_tx_burst(slaves[i], bd_tx_q->queue_id,
 					slave_bufs[i], slave_nb_pkts[i]);
+
+			/* if tx burst fails move packets to end of bufs */
+			if (unlikely(num_tx_slave < slave_nb_pkts[i])) {
+				int slave_tx_fail_count = slave_nb_pkts[i] - num_tx_slave;
+
+				tx_fail_total += slave_tx_fail_count;
+				memcpy(bufs[nb_pkts - tx_fail_total],
+						slave_bufs[i][num_tx_slave], slave_tx_fail_count);
+			}
+
+			num_tx_total += num_tx_slave;
 		}
 	}
 
+
 	return num_tx_total;
 }
 
@@ -330,12 +355,13 @@ bond_ethdev_tx_burst_broadcast(void *queue, struct rte_mbuf **bufs,
 	struct bond_dev_private *internals;
 	struct bond_tx_queue *bd_tx_q;
 
-	uint8_t num_of_slaves;
+	uint8_t tx_failed_flag = 0, num_of_slaves;
 	uint8_t slaves[RTE_MAX_ETHPORTS];
 
-	uint16_t num_tx_total = 0;
+	uint16_t max_nb_of_tx_pkts = 0;
 
-	int i;
+	int slave_tx_total[RTE_MAX_ETHPORTS];
+	int i, most_scuccesful_tx_slave;
 
 	bd_tx_q = (struct bond_tx_queue *)queue;
 	internals = bd_tx_q->dev_private;
@@ -354,11 +380,32 @@ bond_ethdev_tx_burst_broadcast(void *queue, struct rte_mbuf **bufs,
 		rte_mbuf_refcnt_update(bufs[i], num_of_slaves - 1);
 
 	/* Transmit burst on each active slave */
-	for (i = 0; i < num_of_slaves; i++)
-		num_tx_total += rte_eth_tx_burst(slaves[i], bd_tx_q->queue_id,
-				bufs, nb_pkts);
+	for (i = 0; i < num_of_slaves; i++) {
+		slave_tx_total[i] = rte_eth_tx_burst(slaves[i], bd_tx_q->queue_id,
+					bufs, nb_pkts);
 
-	return num_tx_total;
+		if (unlikely(slave_tx_total[i] < nb_pkts))
+			tx_failed_flag = 1;
+
+		/* record the value and slave index for the slave which transmits the
+		 * maximum number of packets */
+		if (slave_tx_total[i] > max_nb_of_tx_pkts) {
+			max_nb_of_tx_pkts = slave_tx_total[i];
+			most_scuccesful_tx_slave = i;
+		}
+	}
+
+	/* if slaves fail to transmit packets from burst, the calling application
+	 * is not expected to know about multiple references to packets so we must
+	 * handle failures of all packets except those of the most successful slave
+	 */
+	if (unlikely(tx_failed_flag))
+		for (i = 0; i < num_of_slaves; i++)
+			if (i != most_scuccesful_tx_slave)
+				while (slave_tx_total[i] < nb_pkts)
+					rte_pktmbuf_free(bufs[slave_tx_total[i]++]);
+
+	return max_nb_of_tx_pkts;
 }
 
 void
-- 
1.7.0.7

  parent reply	other threads:[~2014-09-01  8:27 UTC|newest]

Thread overview: 91+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-19 13:51 [dpdk-dev] [PATCH 0/6] link bonding Declan Doherty
2014-08-19 13:51 ` [dpdk-dev] [PATCH 1/6] bond: link status interrupt support Declan Doherty
2014-08-20 20:24   ` Sanford, Robert
2014-08-19 13:51 ` [dpdk-dev] [PATCH 2/6] bond: removing switch statement from rx burst method Declan Doherty
2014-08-20 20:25   ` Sanford, Robert
2014-08-19 13:51 ` [dpdk-dev] [PATCH 3/6] bond: fix naming inconsistency in tx_burst_round_robin Declan Doherty
2014-08-20 20:25   ` Sanford, Robert
2014-08-19 13:51 ` [dpdk-dev] [PATCH 4/6] bond: free mbufs if transmission fails in bonding tx_burst functions Declan Doherty
2014-08-19 13:51 ` [dpdk-dev] [PATCH 5/6] test app: adding support for generating variable sized packets Declan Doherty
2014-08-19 13:51 ` [dpdk-dev] [PATCH 6/6] testpmd: adding parameter to reconfig method to set socket_id when adding new port to portlist Declan Doherty
2014-08-22  7:41 ` [dpdk-dev] [PATCH 0/6] link bonding Jiajia, SunX
2014-09-01  8:31 ` [dpdk-dev] [PATCH v2 " Declan Doherty
2014-09-02 13:31   ` De Lara Guarch, Pablo
2014-09-02 18:15   ` Stephen Hemminger
2014-09-01  8:31 ` [dpdk-dev] [PATCH v2 1/6] bond: link status interrupt support Declan Doherty
2014-09-01  8:31 ` [dpdk-dev] [PATCH v2 2/6] bond: removing switch statement from rx burst method Declan Doherty
2014-09-01  8:31 ` [dpdk-dev] [PATCH v2 3/6] bond: fix naming inconsistency in tx_burst_round_robin Declan Doherty
2014-09-01  8:31 ` Declan Doherty [this message]
2014-09-02  9:22   ` [dpdk-dev] [PATCH v2 4/6] bond: free mbufs if transmission fails in bonding tx_burst functions Doherty, Declan
2014-09-02  9:31     ` Thomas Monjalon
2014-09-23 13:18   ` [dpdk-dev] [PATCH v3 0/5] link bonding Declan Doherty
2014-09-23 13:18     ` [dpdk-dev] [PATCH v3 1/5] bond: free mbufs if transmission fails in bonding tx_burst functions Declan Doherty
2014-09-23 13:18     ` [dpdk-dev] [PATCH v3 2/5] test app: adding support for generating variable sized packet Declan Doherty
2014-09-23 13:18     ` [dpdk-dev] [PATCH v3 3/5] testpmd: adding parameter to reconfig method to set socket_id when adding new port to portlist Declan Doherty
2014-09-23 13:18     ` [dpdk-dev] [PATCH v3 4/5] bond: lsc polling support Declan Doherty
2014-09-24 13:16       ` Ananyev, Konstantin
2014-09-23 13:18     ` [dpdk-dev] [PATCH v3 5/5] bond: unit test test macro refactor Declan Doherty
2014-09-01  8:31 ` [dpdk-dev] [PATCH v2 5/6] test app: adding support for generating variable sized packets Declan Doherty
2014-09-01  8:31 ` [dpdk-dev] [PATCH v2 6/6] testpmd: adding parameter to reconfig method to set socket_id when adding new port to portlist Declan Doherty
2014-09-30  9:57 ` [dpdk-dev] [PATCH v4 0/8] link bonding Declan Doherty
2014-09-30  9:57   ` [dpdk-dev] [PATCH v4 1/8] bond: link status interrupt support Declan Doherty
2014-09-30  9:57   ` [dpdk-dev] [PATCH v4 2/8] bond: removing switch statement from rx burst method Declan Doherty
2014-09-30  9:57   ` [dpdk-dev] [PATCH v4 3/8] bond: fix naming inconsistency in tx_burst_round_robin Declan Doherty
2014-09-30  9:57   ` [dpdk-dev] [PATCH v4 4/8] bond: free mbufs if transmission fails in bonding tx_burst functions Declan Doherty
2014-10-13 15:29     ` De Lara Guarch, Pablo
2014-09-30  9:57   ` [dpdk-dev] [PATCH v4 5/8] test app: adding support for generating variable sized packet bursts Declan Doherty
2014-10-24  3:22     ` Liang, Cunming
2014-09-30  9:57   ` [dpdk-dev] [PATCH v4 6/8] testpmd: adding parameter to reconfig method to set socket_id when adding new port to portlist Declan Doherty
2014-09-30  9:57   ` [dpdk-dev] [PATCH v4 7/8] bond: lsc polling support Declan Doherty
2014-09-30  9:57   ` [dpdk-dev] [PATCH v4 8/8] bond: unit test test macro refactor Declan Doherty
2014-10-08  8:49   ` [dpdk-dev] [PATCH v4 0/8] link bonding Jiajia, SunX
2014-10-09 19:20   ` De Lara Guarch, Pablo
2014-10-14 12:59   ` [dpdk-dev] [PATCH v5 " Declan Doherty
2014-10-14 12:59     ` [dpdk-dev] [PATCH v5 1/8] bond: link status interrupt support Declan Doherty
2014-10-14 12:59     ` [dpdk-dev] [PATCH v5 2/8] bond: removing switch statement from rx burst method Declan Doherty
2014-10-14 12:59     ` [dpdk-dev] [PATCH v5 3/8] bond: fix naming inconsistency in tx_burst_round_robin Declan Doherty
2014-10-14 12:59     ` [dpdk-dev] [PATCH v5 4/8] bond: free mbufs if transmission fails in bonding tx_burst functions Declan Doherty
2014-10-14 12:59     ` [dpdk-dev] [PATCH v5 5/8] test app: adding support for generating variable sized packet Declan Doherty
2014-10-14 12:59     ` [dpdk-dev] [PATCH v5 6/8] testpmd: adding parameter to reconfig method to set socket_id when adding new port to portlist Declan Doherty
2014-10-14 12:59     ` [dpdk-dev] [PATCH v5 7/8] bond: lsc polling support Declan Doherty
2014-10-14 12:59     ` [dpdk-dev] [PATCH v5 8/8] bond: unit test test macro refactor Declan Doherty
2014-10-14 15:59     ` [dpdk-dev] [PATCH v5 0/8] link bonding De Lara Guarch, Pablo
2014-11-05  3:10     ` Jiajia, SunX
2014-11-07 12:22     ` [dpdk-dev] [PATCH v6 " Declan Doherty
2014-11-07 12:22       ` [dpdk-dev] [PATCH v6 1/8] bond: link status interrupt support Declan Doherty
2014-11-07 12:22       ` [dpdk-dev] [PATCH v6 2/8] bond: removing switch statement from rx burst method Declan Doherty
2014-11-07 12:22       ` [dpdk-dev] [PATCH v6 3/8] bond: fix naming inconsistency in tx_burst_round_robin Declan Doherty
2014-11-07 12:22       ` [dpdk-dev] [PATCH v6 4/8] bond: free mbufs if transmission fails in bonding tx_burst functions Declan Doherty
2014-11-07 12:22       ` [dpdk-dev] [PATCH v6 5/8] test app: adding support for generating variable sized packet Declan Doherty
2014-11-07 12:22       ` [dpdk-dev] [PATCH v6 6/8] testpmd: adding parameter to reconfig method to set socket_id when adding new port to portlist Declan Doherty
2014-11-07 12:22       ` [dpdk-dev] [PATCH v6 7/8] bond: lsc polling support Declan Doherty
2014-11-07 12:22       ` [dpdk-dev] [PATCH v6 8/8] bond: unit test test macro refactor Declan Doherty
2014-11-07 16:40       ` [dpdk-dev] [PATCH v6 0/8] link bonding De Lara Guarch, Pablo
2014-11-21 17:07         ` Doherty, Declan
2014-11-21 18:36           ` Thomas Monjalon
2014-11-23 13:40             ` Thomas Monjalon
2014-11-21  8:59       ` Jiajia, SunX
2014-11-24 12:27       ` [dpdk-dev] [PATCH v7 0/7] " Declan Doherty
2014-11-24 12:27         ` [dpdk-dev] [PATCH v7 1/7] bond: link status interrupt support Declan Doherty
2014-11-24 12:27         ` [dpdk-dev] [PATCH v7 2/7] bond: removing switch statement from rx burst method Declan Doherty
2014-11-24 12:27         ` [dpdk-dev] [PATCH v7 3/7] bond: fix naming inconsistency in tx_burst_round_robin Declan Doherty
2014-11-24 12:27         ` [dpdk-dev] [PATCH v7 4/7] bond: free mbufs if transmission fails in bonding tx_burst functions Declan Doherty
2014-11-24 12:27         ` [dpdk-dev] [PATCH v7 5/7] testpmd: adding parameter to reconfig method to set socket_id when adding new port to portlist Declan Doherty
2014-11-24 12:27         ` [dpdk-dev] [PATCH v7 6/7] bond: lsc polling support Declan Doherty
2014-11-24 12:27         ` [dpdk-dev] [PATCH v7 7/7] bond: unit test test macro refactor Declan Doherty
2014-11-24 15:35         ` [dpdk-dev] [PATCH v7 0/7] link bonding Thomas Monjalon
2014-11-24 16:24           ` Doherty, Declan
2014-11-24 17:53             ` Thomas Monjalon
2014-11-24 16:33         ` [dpdk-dev] [PATCH v8 " Declan Doherty
2014-11-24 16:33           ` [dpdk-dev] [PATCH v8 1/7] bond: link status interrupt support Declan Doherty
2014-11-24 16:33           ` [dpdk-dev] [PATCH v8 2/7] bond: removing switch statement from rx burst method Declan Doherty
2014-11-24 16:33           ` [dpdk-dev] [PATCH v8 3/7] bond: fix naming inconsistency in tx_burst_round_robin Declan Doherty
2014-11-24 16:33           ` [dpdk-dev] [PATCH v8 4/7] bond: free mbufs if transmission fails in bonding tx_burst functions Declan Doherty
2014-11-24 16:33           ` [dpdk-dev] [PATCH v8 5/7] testpmd: adding parameter to reconfig method to set socket_id when adding new port to portlist Declan Doherty
2014-11-24 16:33           ` [dpdk-dev] [PATCH v8 6/7] bond: lsc polling support Declan Doherty
2014-11-24 16:33           ` [dpdk-dev] [PATCH v8 7/7] bond: unit test test macro refactor Declan Doherty
2014-11-24 18:32           ` [dpdk-dev] [PATCH v8 0/7] link bonding Thomas Monjalon
2014-11-24 18:51             ` Thomas Monjalon
2014-11-24 20:54           ` Thomas Monjalon
2014-11-25 10:56             ` Jastrzebski, MichalX K
2014-11-25 11:20               ` Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1409560289-29558-5-git-send-email-declan.doherty@intel.com \
    --to=declan.doherty@intel.com \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

DPDK patches and discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://inbox.dpdk.org/dev/0 dev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dev dev/ https://inbox.dpdk.org/dev \
		dev@dpdk.org
	public-inbox-index dev

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.dev


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git