Show a patch.

GET /api/patches/271/
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 271,
    "url": "https://patches.dpdk.org/api/patches/271/",
    "web_url": "https://patches.dpdk.org/patch/271/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk"
    },
    "msgid": "<1409560289-29558-5-git-send-email-declan.doherty@intel.com>",
    "date": "2014-09-01T08:31:27",
    "name": "[dpdk-dev,v2,4/6] bond: free mbufs if transmission fails in bonding tx_burst functions",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "a41db96ec4c01f6c7ec065cc6e83ccd67d2ebd5e",
    "submitter": {
        "id": 11,
        "url": "https://patches.dpdk.org/api/people/11/",
        "name": "Doherty, Declan",
        "email": "declan.doherty@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/patch/271/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/271/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/271/checks/",
    "tags": {},
    "headers": {
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Date": "Mon,  1 Sep 2014 09:31:27 +0100",
        "In-Reply-To": "<1408456313-28812-1-git-send-email-declan.doherty@intel.com>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "X-BeenThere": "dev@dpdk.org",
        "References": "<1408456313-28812-1-git-send-email-declan.doherty@intel.com>",
        "X-Mailer": "git-send-email 1.7.0.7",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "To": "dev@dpdk.org",
        "Received": [
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n\tby dpdk.org (Postfix) with ESMTP id ED4ABB38B\n\tfor <dev@dpdk.org>; Mon,  1 Sep 2014 10:27:16 +0200 (CEST)",
            "from fmsmga002.fm.intel.com ([10.253.24.26])\n\tby fmsmga102.fm.intel.com with ESMTP; 01 Sep 2014 01:31:43 -0700",
            "from irvmail001.ir.intel.com ([163.33.26.43])\n\tby fmsmga002.fm.intel.com with ESMTP; 01 Sep 2014 01:31:38 -0700",
            "from sivswdev02.ir.intel.com (sivswdev02.ir.intel.com\n\t[10.237.217.46])\n\tby irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id\n\ts818VbC4010183; Mon, 1 Sep 2014 09:31:37 +0100",
            "from sivswdev02.ir.intel.com (localhost [127.0.0.1])\n\tby sivswdev02.ir.intel.com with ESMTP id s818Vb6U002122;\n\tMon, 1 Sep 2014 09:31:37 +0100",
            "(from dwdohert@localhost)\n\tby sivswdev02.ir.intel.com with  id s818VbSI002117;\n\tMon, 1 Sep 2014 09:31:37 +0100"
        ],
        "From": "Declan Doherty <declan.doherty@intel.com>",
        "Precedence": "list",
        "X-ExtLoop1": "1",
        "Message-Id": "<1409560289-29558-5-git-send-email-declan.doherty@intel.com>",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "Subject": "[dpdk-dev] [PATCH v2 4/6] bond: free mbufs if transmission fails in\n\tbonding tx_burst functions",
        "X-List-Received-Date": "Mon, 01 Sep 2014 08:27:19 -0000",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "Return-Path": "<dwdohert@ecsmtp.ir.intel.com>",
        "X-IronPort-AV": "E=Sophos;i=\"5.04,441,1406617200\"; d=\"scan'208\";a=\"592735595\"",
        "List-Post": "<mailto:dev@dpdk.org>",
        "X-Mailman-Version": "2.1.15"
    },
    "content": "Fixing a number of corner cases that if transmission failed on slave devices then this\ncould lead to leaked mbufs \n\nV2 addresses behaviouraly issues in the first version and packets are no longer freed in\nthe bonding layer, except in the case of broadcast mode where in failures happen on \nmore than a single slave then mbufs will be freed in all slaves except the one where\nthe least errors occured. Also contains new unit tests to test the transmission\n failure case in slaves for \nround-robin, balance, and broadcast modes.\n\n \nSigned-off-by: Declan Doherty <declan.doherty@intel.com>\n---\n app/test/test_link_bonding.c           |  393 +++++++++++++++++++++++++++++++-\n app/test/virtual_pmd.c                 |   80 +++++--\n app/test/virtual_pmd.h                 |    7 +\n lib/librte_pmd_bond/rte_eth_bond_pmd.c |   83 ++++++--\n 4 files changed, 525 insertions(+), 38 deletions(-)",
    "diff": "diff --git a/app/test/test_link_bonding.c b/app/test/test_link_bonding.c\nindex cce32ed..c5aaa80 100644\n--- a/app/test/test_link_bonding.c\n+++ b/app/test/test_link_bonding.c\n@@ -663,6 +663,9 @@ enable_bonded_slaves(void)\n \tint i;\n \n \tfor (i = 0; i < test_params->bonded_slave_count; i++) {\n+\t\tvirtual_ethdev_tx_burst_fn_set_success(test_params->slave_port_ids[i],\n+\t\t\t\t1);\n+\n \t\tvirtual_ethdev_simulate_link_status_interrupt(\n \t\t\t\ttest_params->slave_port_ids[i], 1);\n \t}\n@@ -1413,6 +1416,135 @@ test_roundrobin_tx_burst(void)\n }\n \n static int\n+verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)\n+{\n+\tint i, refcnt;\n+\n+\tfor (i = 0; i < nb_mbufs; i++) {\n+\t\trefcnt = rte_mbuf_refcnt_read(mbufs[i]);\n+\t\tTEST_ASSERT_EQUAL(refcnt, val,\n+\t\t\t\"mbuf ref count (%d)is not the expected value (%d)\",\n+\t\t\trefcnt, val);\n+\t}\n+\treturn 0;\n+}\n+\n+\n+static void\n+free_mbufs(struct rte_mbuf **mbufs, int nb_mbufs)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < nb_mbufs; i++)\n+\t\trte_pktmbuf_free(mbufs[i]);\n+}\n+\n+#define TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT\t\t(2)\n+#define TEST_RR_SLAVE_TX_FAIL_BURST_SIZE\t\t(64)\n+#define TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT\t\t(22)\n+#define TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX\t(1)\n+\n+static int\n+test_roundrobin_tx_burst_slave_tx_fail(void)\n+{\n+\tstruct rte_mbuf *pkt_burst[MAX_PKT_BURST];\n+\tstruct rte_mbuf *expected_tx_fail_pkts[MAX_PKT_BURST];\n+\n+\tstruct rte_eth_stats port_stats;\n+\n+\tint i, first_fail_idx, tx_count;\n+\n+\tTEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(\n+\t\t\tBONDING_MODE_ROUND_ROBIN, 0,\n+\t\t\tTEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT, 1),\n+\t\t\t\"Failed to intialise bonded device\");\n+\n+\t/* Generate test bursts of packets to transmit */\n+\tTEST_ASSERT_EQUAL(generate_test_burst(pkt_burst,\n+\t\t\tTEST_RR_SLAVE_TX_FAIL_BURST_SIZE, 0, 1, 0, 0, 0),\n+\t\t\tTEST_RR_SLAVE_TX_FAIL_BURST_SIZE,\n+\t\t\t\"Failed to generate test packet burst\");\n+\n+\t/* Copy references to packets which we expect not to be transmitted */\n+\tfirst_fail_idx = (TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -\n+\t\t\t(TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT *\n+\t\t\tTEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)) +\n+\t\t\tTEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX;\n+\n+\tfor (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {\n+\t\texpected_tx_fail_pkts[i] = pkt_burst[first_fail_idx +\n+\t\t\t\t(i * TEST_RR_SLAVE_TX_FAIL_SLAVE_COUNT)];\n+\t}\n+\n+\t/* Set virtual slave to only fail transmission of\n+\t * TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT packets in burst */\n+\tvirtual_ethdev_tx_burst_fn_set_success(\n+\t\t\ttest_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],\n+\t\t\t0);\n+\n+\tvirtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(\n+\t\t\ttest_params->slave_port_ids[TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],\n+\t\t\tTEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);\n+\n+\ttx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkt_burst,\n+\t\t\tTEST_RR_SLAVE_TX_FAIL_BURST_SIZE);\n+\n+\tTEST_ASSERT_EQUAL(tx_count, TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -\n+\t\t\tTEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,\n+\t\t\t\"Transmitted (%d) an unexpected (%d) number of packets\", tx_count,\n+\t\t\tTEST_RR_SLAVE_TX_FAIL_BURST_SIZE -\n+\t\t\tTEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);\n+\n+\t/* Verify that failed packet are expected failed packets */\n+\tfor (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {\n+\t\tTEST_ASSERT_EQUAL(expected_tx_fail_pkts[i], pkt_burst[i + tx_count],\n+\t\t\t\t\"expected mbuf (%d) pointer %p not expected pointer %p\",\n+\t\t\t\ti, expected_tx_fail_pkts[i], pkt_burst[i + tx_count]);\n+\t}\n+\n+\t/* Verify bonded port tx stats */\n+\trte_eth_stats_get(test_params->bonded_port_id, &port_stats);\n+\n+\tTEST_ASSERT_EQUAL(port_stats.opackets,\n+\t\t\t(uint64_t)TEST_RR_SLAVE_TX_FAIL_BURST_SIZE -\n+\t\t\tTEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT,\n+\t\t\t\"Bonded Port (%d) opackets value (%u) not as expected (%d)\",\n+\t\t\ttest_params->bonded_port_id, (unsigned int)port_stats.opackets,\n+\t\t\tTEST_RR_SLAVE_TX_FAIL_BURST_SIZE -\n+\t\t\tTEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);\n+\n+\t/* Verify slave ports tx stats */\n+\tfor (i = 0; i < test_params->bonded_slave_count; i++) {\n+\t\tint slave_expected_tx_count;\n+\n+\t\trte_eth_stats_get(test_params->slave_port_ids[i], &port_stats);\n+\n+\t\tslave_expected_tx_count = TEST_RR_SLAVE_TX_FAIL_BURST_SIZE /\n+\t\t\t\ttest_params->bonded_slave_count;\n+\n+\t\tif (i == TEST_RR_SLAVE_TX_FAIL_FAILING_SLAVE_IDX)\n+\t\t\tslave_expected_tx_count = slave_expected_tx_count -\n+\t\t\t\t\tTEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT;\n+\n+\t\tTEST_ASSERT_EQUAL(port_stats.opackets,\n+\t\t\t\t(uint64_t)slave_expected_tx_count,\n+\t\t\t\t\"Slave Port (%d) opackets value (%u) not as expected (%d)\",\n+\t\t\t\ttest_params->slave_port_ids[i],\n+\t\t\t\t(unsigned int)port_stats.opackets, slave_expected_tx_count);\n+\t}\n+\n+\t/* Verify that all mbufs have a ref value of zero */\n+\tTEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],\n+\t\t\tTEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),\n+\t\t\t\"mbufs refcnts not as expected\");\n+\n+\tfree_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);\n+\n+\t/* Clean up and remove slaves from bonded device */\n+\treturn remove_slaves_and_stop_bonded_device();\n+}\n+\n+static int\n test_roundrobin_rx_burst_on_single_slave(void)\n {\n \tstruct rte_mbuf *gen_pkt_burst[MAX_PKT_BURST] = { NULL };\n@@ -2900,6 +3032,141 @@ test_balance_l34_tx_burst_ipv6_toggle_udp_port(void)\n \treturn balance_l34_tx_burst(0, 0, 0, 0, 1);\n }\n \n+#define TEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT\t\t\t(2)\n+#define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1\t\t\t(40)\n+#define TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2\t\t\t(20)\n+#define TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT\t\t(25)\n+#define TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX\t(0)\n+\n+static int\n+test_balance_tx_burst_slave_tx_fail(void)\n+{\n+\tstruct rte_mbuf *pkts_burst_1[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1];\n+\tstruct rte_mbuf *pkts_burst_2[TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2];\n+\n+\tstruct rte_mbuf *expected_fail_pkts[TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT];\n+\n+\tstruct rte_eth_stats port_stats;\n+\n+\tint i, first_tx_fail_idx, tx_count_1, tx_count_2;\n+\n+\tTEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(\n+\t\t\tBONDING_MODE_BALANCE, 0,\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_SLAVE_COUNT, 1),\n+\t\t\t\"Failed to intialise bonded device\");\n+\n+\tTEST_ASSERT_SUCCESS(rte_eth_bond_xmit_policy_set(\n+\t\t\ttest_params->bonded_port_id, BALANCE_XMIT_POLICY_LAYER2),\n+\t\t\t\"Failed to set balance xmit policy.\");\n+\n+\n+\t/* Generate test bursts for transmission */\n+\tTEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_1,\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1, 0, 0, 0, 0, 0),\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1,\n+\t\t\t\"Failed to generate test packet burst 1\");\n+\n+\tfirst_tx_fail_idx = TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT;\n+\n+\t/* copy mbuf referneces for expected transmission failures */\n+\tfor (i = 0; i < TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {\n+\t\texpected_fail_pkts[i] = pkts_burst_1[i + first_tx_fail_idx];\n+\t}\n+\n+\tTEST_ASSERT_EQUAL(generate_test_burst(pkts_burst_2,\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2, 0, 0, 1, 0, 0),\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,\n+\t\t\t\"Failed to generate test packet burst 2\");\n+\n+\n+\t/* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail\n+\t * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */\n+\tvirtual_ethdev_tx_burst_fn_set_success(\n+\t\t\ttest_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],\n+\t\t\t0);\n+\n+\tvirtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(\n+\t\t\ttest_params->slave_port_ids[TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX],\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);\n+\n+\n+\t/* Transmit burst 1 */\n+\ttx_count_1 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_1,\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1);\n+\n+\tTEST_ASSERT_EQUAL(tx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,\n+\t\t\t\"Transmitted (%d) packets, expected to transmit (%d) packets\",\n+\t\t\ttx_count_1, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);\n+\n+\t/* Verify that failed packet are expected failed packets */\n+\tfor (i = 0; i < TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT; i++) {\n+\t\tTEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst_1[i + tx_count_1],\n+\t\t\t\t\"expected mbuf (%d) pointer %p not expected pointer %p\",\n+\t\t\t\ti, expected_fail_pkts[i], pkts_burst_1[i + tx_count_1]);\n+\t}\n+\n+\t/* Transmit burst 2 */\n+\ttx_count_2 = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst_2,\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);\n+\n+\tTEST_ASSERT_EQUAL(tx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,\n+\t\t\t\"Transmitted (%d) packets, expected to transmit (%d) packets\",\n+\t\t\ttx_count_2, TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);\n+\n+\n+\t/* Verify bonded port tx stats */\n+\trte_eth_stats_get(test_params->bonded_port_id, &port_stats);\n+\n+\tTEST_ASSERT_EQUAL(port_stats.opackets,\n+\t\t\t(uint64_t)((TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2),\n+\t\t\t\"Bonded Port (%d) opackets value (%u) not as expected (%d)\",\n+\t\t\ttest_params->bonded_port_id, (unsigned int)port_stats.opackets,\n+\t\t\t(TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT) +\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);\n+\n+\t/* Verify slave ports tx stats */\n+\n+\trte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);\n+\n+\tTEST_ASSERT_EQUAL(port_stats.opackets, (uint64_t)\n+\t\t\t\tTEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -\n+\t\t\t\tTEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT,\n+\t\t\t\t\"Slave Port (%d) opackets value (%u) not as expected (%d)\",\n+\t\t\t\ttest_params->slave_port_ids[0],\n+\t\t\t\t(unsigned int)port_stats.opackets,\n+\t\t\t\tTEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_1 -\n+\t\t\t\tTEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);\n+\n+\n+\n+\n+\trte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);\n+\n+\tTEST_ASSERT_EQUAL(port_stats.opackets,\n+\t\t\t\t(uint64_t)TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2,\n+\t\t\t\t\"Slave Port (%d) opackets value (%u) not as expected (%d)\",\n+\t\t\t\ttest_params->slave_port_ids[1],\n+\t\t\t\t(unsigned int)port_stats.opackets,\n+\t\t\t\tTEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);\n+\n+\t/* Verify that all mbufs have a ref value of zero */\n+\tTEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),\n+\t\t\t\"mbufs refcnts not as expected\");\n+\n+\tfree_mbufs(&pkts_burst_1[tx_count_1],\n+\t\t\tTEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);\n+\n+\t/* Clean up and remove slaves from bonded device */\n+\treturn remove_slaves_and_stop_bonded_device();\n+}\n+\n #define TEST_BALANCE_RX_BURST_SLAVE_COUNT (3)\n \n static int\n@@ -3412,7 +3679,7 @@ test_broadcast_tx_burst(void)\n \t/* Send burst on bonded port */\n \tnb_tx = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,\n \t\t\tburst_size);\n-\tif (nb_tx != burst_size * test_params->bonded_slave_count) {\n+\tif (nb_tx != burst_size) {\n \t\tprintf(\"Bonded Port (%d) rx burst failed, packets transmitted value (%u) not as expected (%d)\\n\",\n \t\t\t\ttest_params->bonded_port_id,\n \t\t\t\tnb_tx, burst_size);\n@@ -3455,6 +3722,125 @@ test_broadcast_tx_burst(void)\n \treturn remove_slaves_and_stop_bonded_device();\n }\n \n+\n+#define TEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT\t\t(3)\n+#define TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE\t\t\t(40)\n+#define TEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT\t(15)\n+#define TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT\t(10)\n+\n+static int\n+test_broadcast_tx_burst_slave_tx_fail(void)\n+{\n+\tstruct rte_mbuf *pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE];\n+\tstruct rte_mbuf *expected_fail_pkts[TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT];\n+\n+\tstruct rte_eth_stats port_stats;\n+\n+\tint i, tx_count;\n+\n+\tTEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(\n+\t\t\tBONDING_MODE_BROADCAST, 0,\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_SLAVE_COUNT, 1),\n+\t\t\t\"Failed to intialise bonded device\");\n+\n+\t/* Generate test bursts for transmission */\n+\tTEST_ASSERT_EQUAL(generate_test_burst(pkts_burst,\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE, 0, 0, 0, 0, 0),\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE,\n+\t\t\t\"Failed to generate test packet burst\");\n+\n+\tfor (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {\n+\t\texpected_fail_pkts[i] = pkts_burst[TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT + i];\n+\t}\n+\n+\t/* Set virtual slave TEST_BAL_SLAVE_TX_FAIL_FAILING_SLAVE_IDX to only fail\n+\t * transmission of TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT packets of burst */\n+\tvirtual_ethdev_tx_burst_fn_set_success(\n+\t\t\ttest_params->slave_port_ids[0],\n+\t\t\t0);\n+\tvirtual_ethdev_tx_burst_fn_set_success(\n+\t\t\ttest_params->slave_port_ids[1],\n+\t\t\t0);\n+\tvirtual_ethdev_tx_burst_fn_set_success(\n+\t\t\ttest_params->slave_port_ids[2],\n+\t\t\t0);\n+\n+\tvirtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(\n+\t\t\ttest_params->slave_port_ids[0],\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);\n+\n+\tvirtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(\n+\t\t\ttest_params->slave_port_ids[1],\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);\n+\n+\tvirtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(\n+\t\t\ttest_params->slave_port_ids[2],\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);\n+\n+\t/* Transmit burst */\n+\ttx_count = rte_eth_tx_burst(test_params->bonded_port_id, 0, pkts_burst,\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE);\n+\n+\tTEST_ASSERT_EQUAL(tx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,\n+\t\t\t\"Transmitted (%d) packets, expected to transmit (%d) packets\",\n+\t\t\ttx_count, TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);\n+\n+\t/* Verify that failed packet are expected failed packets */\n+\tfor (i = 0; i < TEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT; i++) {\n+\t\tTEST_ASSERT_EQUAL(expected_fail_pkts[i], pkts_burst[i + tx_count],\n+\t\t\t\t\"expected mbuf (%d) pointer %p not expected pointer %p\",\n+\t\t\t\ti, expected_fail_pkts[i], pkts_burst[i + tx_count]);\n+\t}\n+\n+\t/* Verify slave ports tx stats */\n+\n+\trte_eth_stats_get(test_params->slave_port_ids[0], &port_stats);\n+\n+\tTEST_ASSERT_EQUAL(port_stats.opackets,\n+\t\t\t(uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,\n+\t\t\t\"Port (%d) opackets value (%u) not as expected (%d)\",\n+\t\t\ttest_params->bonded_port_id, (unsigned int)port_stats.opackets,\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);\n+\n+\n+\trte_eth_stats_get(test_params->slave_port_ids[1], &port_stats);\n+\n+\tTEST_ASSERT_EQUAL(port_stats.opackets,\n+\t\t\t(uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT,\n+\t\t\t\"Port (%d) opackets value (%u) not as expected (%d)\",\n+\t\t\ttest_params->bonded_port_id, (unsigned int)port_stats.opackets,\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -s\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);\n+\n+\trte_eth_stats_get(test_params->slave_port_ids[2], &port_stats);\n+\n+\tTEST_ASSERT_EQUAL(port_stats.opackets,\n+\t\t\t(uint64_t)TEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT,\n+\t\t\t\"Port (%d) opackets value (%u) not as expected (%d)\",\n+\t\t\ttest_params->bonded_port_id, (unsigned int)port_stats.opackets,\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_BURST_SIZE -\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_MAX_PACKETS_COUNT);\n+\n+\n+\t/* Verify that all mbufs who transmission failed have a ref value of one */\n+\tTEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst[tx_count],\n+\t\t\tTEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT, 1),\n+\t\t\t\"mbufs refcnts not as expected\");\n+\n+\tfree_mbufs(&pkts_burst[tx_count],\n+\t\tTEST_BCAST_SLAVE_TX_FAIL_MIN_PACKETS_COUNT);\n+\n+\t/* Clean up and remove slaves from bonded device */\n+\treturn remove_slaves_and_stop_bonded_device();\n+}\n+\n #define BROADCAST_RX_BURST_NUM_OF_SLAVES (3)\n \n static int\n@@ -3767,7 +4153,7 @@ test_broadcast_verify_slave_link_status_change_behaviour(void)\n \t}\n \n \tif (rte_eth_tx_burst(test_params->bonded_port_id, 0, &pkt_burst[0][0],\n-\t\t\tburst_size) != (burst_size * slave_count)) {\n+\t\t\tburst_size) != burst_size) {\n \t\tprintf(\"rte_eth_tx_burst failed\\n\");\n \t\treturn -1;\n \t}\n@@ -3915,6 +4301,7 @@ static struct unit_test_suite link_bonding_test_suite  = {\n \t\tTEST_CASE(test_status_interrupt),\n \t\tTEST_CASE(test_adding_slave_after_bonded_device_started),\n \t\tTEST_CASE(test_roundrobin_tx_burst),\n+\t\tTEST_CASE(test_roundrobin_tx_burst_slave_tx_fail),\n \t\tTEST_CASE(test_roundrobin_rx_burst_on_single_slave),\n \t\tTEST_CASE(test_roundrobin_rx_burst_on_multiple_slaves),\n \t\tTEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),\n@@ -3938,11 +4325,13 @@ static struct unit_test_suite link_bonding_test_suite  = {\n \t\tTEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_ip_addr),\n \t\tTEST_CASE(test_balance_l34_tx_burst_vlan_ipv6_toggle_ip_addr),\n \t\tTEST_CASE(test_balance_l34_tx_burst_ipv6_toggle_udp_port),\n+\t\tTEST_CASE(test_balance_tx_burst_slave_tx_fail),\n \t\tTEST_CASE(test_balance_rx_burst),\n \t\tTEST_CASE(test_balance_verify_promiscuous_enable_disable),\n \t\tTEST_CASE(test_balance_verify_mac_assignment),\n \t\tTEST_CASE(test_balance_verify_slave_link_status_change_behaviour),\n \t\tTEST_CASE(test_broadcast_tx_burst),\n+\t\tTEST_CASE(test_broadcast_tx_burst_slave_tx_fail),\n \t\tTEST_CASE(test_broadcast_rx_burst),\n \t\tTEST_CASE(test_broadcast_verify_promiscuous_enable_disable),\n \t\tTEST_CASE(test_broadcast_verify_mac_assignment),\ndiff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c\nindex e861c5b..f9bd841 100644\n--- a/app/test/virtual_pmd.c\n+++ b/app/test/virtual_pmd.c\n@@ -48,6 +48,8 @@ struct virtual_ethdev_private {\n \n \tstruct rte_mbuf *rx_pkt_burst[MAX_PKT_BURST];\n \tint rx_pkt_burst_len;\n+\n+\tint tx_burst_fail_count;\n };\n \n struct virtual_ethdev_queue {\n@@ -350,42 +352,67 @@ virtual_ethdev_rx_burst_fail(void *queue __rte_unused,\n }\n \n static uint16_t\n-virtual_ethdev_tx_burst_success(void *queue,\n-\t\t\t\t\t\t\t struct rte_mbuf **bufs __rte_unused,\n-\t\t\t\t\t\t\t uint16_t nb_pkts)\n+virtual_ethdev_tx_burst_success(void *queue, struct rte_mbuf **bufs,\n+\t\tuint16_t nb_pkts)\n {\n+\tstruct virtual_ethdev_queue *tx_q = (struct virtual_ethdev_queue *)queue;\n+\n \tstruct rte_eth_dev *vrtl_eth_dev;\n-\tstruct virtual_ethdev_queue *tx_q;\n \tstruct virtual_ethdev_private *dev_private;\n-\tint i;\n \n-\ttx_q = (struct virtual_ethdev_queue *)queue;\n+\tint i;\n \n \tvrtl_eth_dev = &rte_eth_devices[tx_q->port_id];\n+\tdev_private = vrtl_eth_dev->data->dev_private;\n \n \tif (vrtl_eth_dev->data->dev_link.link_status) {\n-\t\tdev_private = vrtl_eth_dev->data->dev_private;\n+\t\t/* increment opacket count */\n \t\tdev_private->eth_stats.opackets += nb_pkts;\n \n-\t\treturn nb_pkts;\n-\t}\n-\n-\t/* free packets in burst */\n-\tfor (i = 0; i < nb_pkts; i++) {\n-\t\tif (bufs[i] != NULL)\n+\t\t/* free packets in burst */\n+\t\tfor (i = 0; i < nb_pkts; i++) {\n \t\t\trte_pktmbuf_free(bufs[i]);\n+\t\t\tbufs[i] = NULL;\n+\t\t}\n \n-\t\tbufs[i] = NULL;\n+\t\treturn nb_pkts;\n \t}\n \n \treturn 0;\n }\n \n-\n static uint16_t\n-virtual_ethdev_tx_burst_fail(void *queue __rte_unused,\n-\t\tstruct rte_mbuf **bufs __rte_unused, uint16_t nb_pkts __rte_unused)\n+virtual_ethdev_tx_burst_fail(void *queue, struct rte_mbuf **bufs,\n+\t\tuint16_t nb_pkts)\n {\n+\tstruct rte_eth_dev *vrtl_eth_dev = NULL;\n+\tstruct virtual_ethdev_queue *tx_q = NULL;\n+\tstruct virtual_ethdev_private *dev_private = NULL;\n+\n+\tint i;\n+\n+\ttx_q = (struct virtual_ethdev_queue *)queue;\n+\tvrtl_eth_dev = &rte_eth_devices[tx_q->port_id];\n+\tdev_private = vrtl_eth_dev->data->dev_private;\n+\n+\tif (dev_private->tx_burst_fail_count < nb_pkts) {\n+\t\tint successfully_txd = nb_pkts - dev_private->tx_burst_fail_count;\n+\n+\t\t/* increment opacket count */\n+\t\tdev_private->eth_stats.opackets += successfully_txd;\n+\n+\t\t/* free packets in burst */\n+\t\tfor (i = 0; i < successfully_txd; i++) {\n+\t\t\t/* free packets in burst */\n+\t\t\tif (bufs[i] != NULL)\n+\t\t\t\trte_pktmbuf_free(bufs[i]);\n+\n+\t\t\tbufs[i] = NULL;\n+\t\t}\n+\n+\t\treturn successfully_txd;\n+\t}\n+\n \treturn 0;\n }\n \n@@ -405,17 +432,34 @@ virtual_ethdev_rx_burst_fn_set_success(uint8_t port_id, uint8_t success)\n void\n virtual_ethdev_tx_burst_fn_set_success(uint8_t port_id, uint8_t success)\n {\n+\tstruct virtual_ethdev_private *dev_private = NULL;\n \tstruct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id];\n \n+\tdev_private = vrtl_eth_dev->data->dev_private;\n+\n \tif (success)\n \t\tvrtl_eth_dev->tx_pkt_burst = virtual_ethdev_tx_burst_success;\n \telse\n \t\tvrtl_eth_dev->tx_pkt_burst = virtual_ethdev_tx_burst_fail;\n+\n+\tdev_private->tx_burst_fail_count = 0;\n }\n \n+void\n+virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(uint8_t port_id,\n+\t\tuint8_t packet_fail_count)\n+{\n+\tstruct virtual_ethdev_private *dev_private = NULL;\n+\tstruct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id];\n+\n+\n+\tdev_private = vrtl_eth_dev->data->dev_private;\n+\tdev_private->tx_burst_fail_count = packet_fail_count;\n+}\n \n void\n-virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id, uint8_t link_status)\n+virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id,\n+\t\tuint8_t link_status)\n {\n \tstruct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id];\n \ndiff --git a/app/test/virtual_pmd.h b/app/test/virtual_pmd.h\nindex 766b6ac..3b5c911 100644\n--- a/app/test/virtual_pmd.h\n+++ b/app/test/virtual_pmd.h\n@@ -67,6 +67,13 @@ void virtual_ethdev_rx_burst_fn_set_success(uint8_t port_id, uint8_t success);\n \n void virtual_ethdev_tx_burst_fn_set_success(uint8_t port_id, uint8_t success);\n \n+/* if a value greater than zero is set for packet_fail_count then virtual\n+ * device tx burst function will fail that many packet from burst or all\n+ * packets if packet_fail_count is greater than the number of packets in the\n+ * burst */\n+void virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(uint8_t port_id,\n+\t\tuint8_t packet_fail_count);\n+\n #ifdef __cplusplus\n }\n #endif\ndiff --git a/lib/librte_pmd_bond/rte_eth_bond_pmd.c b/lib/librte_pmd_bond/rte_eth_bond_pmd.c\nindex 70123fc..38cc1ae 100644\n--- a/lib/librte_pmd_bond/rte_eth_bond_pmd.c\n+++ b/lib/librte_pmd_bond/rte_eth_bond_pmd.c\n@@ -101,10 +101,10 @@ bond_ethdev_tx_burst_round_robin(void *queue, struct rte_mbuf **bufs,\n \tuint8_t num_of_slaves;\n \tuint8_t slaves[RTE_MAX_ETHPORTS];\n \n-\tuint16_t num_tx_total = 0;\n+\tuint16_t num_tx_total = 0, num_tx_slave;\n \n \tstatic int slave_idx = 0;\n-\tint i, cs_idx = 0;\n+\tint i, cslave_idx = 0, tx_fail_total = 0;\n \n \tbd_tx_q = (struct bond_tx_queue *)queue;\n \tinternals = bd_tx_q->dev_private;\n@@ -120,19 +120,32 @@ bond_ethdev_tx_burst_round_robin(void *queue, struct rte_mbuf **bufs,\n \n \t/* Populate slaves mbuf with which packets are to be sent on it  */\n \tfor (i = 0; i < nb_pkts; i++) {\n-\t\tcs_idx = (slave_idx + i) % num_of_slaves;\n-\t\tslave_bufs[cs_idx][(slave_nb_pkts[cs_idx])++] = bufs[i];\n+\t\tcslave_idx = (slave_idx + i) % num_of_slaves;\n+\t\tslave_bufs[cslave_idx][(slave_nb_pkts[cslave_idx])++] = bufs[i];\n \t}\n \n \t/* increment current slave index so the next call to tx burst starts on the\n \t * next slave */\n-\tslave_idx = ++cs_idx;\n+\tslave_idx = ++cslave_idx;\n \n \t/* Send packet burst on each slave device */\n-\tfor (i = 0; i < num_of_slaves; i++)\n-\t\tif (slave_nb_pkts[i] > 0)\n-\t\t\tnum_tx_total += rte_eth_tx_burst(slaves[i],\n-\t\t\t\t\tbd_tx_q->queue_id, slave_bufs[i], slave_nb_pkts[i]);\n+\tfor (i = 0; i < num_of_slaves; i++) {\n+\t\tif (slave_nb_pkts[i] > 0) {\n+\t\t\tnum_tx_slave = rte_eth_tx_burst(slaves[i], bd_tx_q->queue_id,\n+\t\t\t\t\tslave_bufs[i], slave_nb_pkts[i]);\n+\n+\t\t\t/* if tx burst fails move packets to end of bufs */\n+\t\t\tif (unlikely(num_tx_slave < slave_nb_pkts[i])) {\n+\t\t\t\tint tx_fail_slave = slave_nb_pkts[i] - num_tx_slave;\n+\n+\t\t\t\ttx_fail_total += tx_fail_slave;\n+\n+\t\t\t\tmemcpy(&bufs[nb_pkts - tx_fail_total],\n+\t\t\t\t\t\t&slave_bufs[i][num_tx_slave], tx_fail_slave * sizeof(bufs[0]));\n+\t\t\t}\n+\t\t\tnum_tx_total += num_tx_slave;\n+\t\t}\n+\t}\n \n \treturn num_tx_total;\n }\n@@ -283,7 +296,7 @@ bond_ethdev_tx_burst_balance(void *queue, struct rte_mbuf **bufs,\n \tuint8_t num_of_slaves;\n \tuint8_t slaves[RTE_MAX_ETHPORTS];\n \n-\tuint16_t num_tx_total = 0;\n+\tuint16_t num_tx_total = 0, num_tx_slave = 0, tx_fail_total = 0;\n \n \tint i, op_slave_id;\n \n@@ -315,11 +328,23 @@ bond_ethdev_tx_burst_balance(void *queue, struct rte_mbuf **bufs,\n \t/* Send packet burst on each slave device */\n \tfor (i = 0; i < num_of_slaves; i++) {\n \t\tif (slave_nb_pkts[i] > 0) {\n-\t\t\tnum_tx_total += rte_eth_tx_burst(slaves[i], bd_tx_q->queue_id,\n+\t\t\tnum_tx_slave = rte_eth_tx_burst(slaves[i], bd_tx_q->queue_id,\n \t\t\t\t\tslave_bufs[i], slave_nb_pkts[i]);\n+\n+\t\t\t/* if tx burst fails move packets to end of bufs */\n+\t\t\tif (unlikely(num_tx_slave < slave_nb_pkts[i])) {\n+\t\t\t\tint slave_tx_fail_count = slave_nb_pkts[i] - num_tx_slave;\n+\n+\t\t\t\ttx_fail_total += slave_tx_fail_count;\n+\t\t\t\tmemcpy(bufs[nb_pkts - tx_fail_total],\n+\t\t\t\t\t\tslave_bufs[i][num_tx_slave], slave_tx_fail_count);\n+\t\t\t}\n+\n+\t\t\tnum_tx_total += num_tx_slave;\n \t\t}\n \t}\n \n+\n \treturn num_tx_total;\n }\n \n@@ -330,12 +355,13 @@ bond_ethdev_tx_burst_broadcast(void *queue, struct rte_mbuf **bufs,\n \tstruct bond_dev_private *internals;\n \tstruct bond_tx_queue *bd_tx_q;\n \n-\tuint8_t num_of_slaves;\n+\tuint8_t tx_failed_flag = 0, num_of_slaves;\n \tuint8_t slaves[RTE_MAX_ETHPORTS];\n \n-\tuint16_t num_tx_total = 0;\n+\tuint16_t max_nb_of_tx_pkts = 0;\n \n-\tint i;\n+\tint slave_tx_total[RTE_MAX_ETHPORTS];\n+\tint i, most_scuccesful_tx_slave;\n \n \tbd_tx_q = (struct bond_tx_queue *)queue;\n \tinternals = bd_tx_q->dev_private;\n@@ -354,11 +380,32 @@ bond_ethdev_tx_burst_broadcast(void *queue, struct rte_mbuf **bufs,\n \t\trte_mbuf_refcnt_update(bufs[i], num_of_slaves - 1);\n \n \t/* Transmit burst on each active slave */\n-\tfor (i = 0; i < num_of_slaves; i++)\n-\t\tnum_tx_total += rte_eth_tx_burst(slaves[i], bd_tx_q->queue_id,\n-\t\t\t\tbufs, nb_pkts);\n+\tfor (i = 0; i < num_of_slaves; i++) {\n+\t\tslave_tx_total[i] = rte_eth_tx_burst(slaves[i], bd_tx_q->queue_id,\n+\t\t\t\t\tbufs, nb_pkts);\n \n-\treturn num_tx_total;\n+\t\tif (unlikely(slave_tx_total[i] < nb_pkts))\n+\t\t\ttx_failed_flag = 1;\n+\n+\t\t/* record the value and slave index for the slave which transmits the\n+\t\t * maximum number of packets */\n+\t\tif (slave_tx_total[i] > max_nb_of_tx_pkts) {\n+\t\t\tmax_nb_of_tx_pkts = slave_tx_total[i];\n+\t\t\tmost_scuccesful_tx_slave = i;\n+\t\t}\n+\t}\n+\n+\t/* if slaves fail to transmit packets from burst, the calling application\n+\t * is not expected to know about multiple references to packets so we must\n+\t * handle failures of all packets except those of the most successful slave\n+\t */\n+\tif (unlikely(tx_failed_flag))\n+\t\tfor (i = 0; i < num_of_slaves; i++)\n+\t\t\tif (i != most_scuccesful_tx_slave)\n+\t\t\t\twhile (slave_tx_total[i] < nb_pkts)\n+\t\t\t\t\trte_pktmbuf_free(bufs[slave_tx_total[i]++]);\n+\n+\treturn max_nb_of_tx_pkts;\n }\n \n void\n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "4/6"
    ]
}