Skip to contentSkip to conversation

Link Bonding Library

PATCH Superseded [email protected] 10 participants 127 messages May 28, 2014 – Jul 1, 2014 44 messages not in the archive Library code Page 1 of 2

lore
Share & tools
lore
#0 lore raw

cover Link Bonding Library

From: Declan Doherty <[email protected]>

Initial release of Link Bonding Library (lib/librte_bond) with support for bonding modes :
0 - Round Robin
1 - Active Backup
2 - Balance l2 / l23 / l34
3 - Broadcast

patches split:
1 - library + makefile changes
2 - Unit test suite, including code to generate packet bursts for
testing rx and tx functionality of bonded device and a virtual/stubbed out ethdev for use as slave ethdev in testing
3 - Link bonding integration into testpmd, including :
- Includes the ability to create new bonded devices.
- Add /remove bonding slave devices.
- Interogate bonded device stats/configuration
- Change bonding modes and select balance transmit polices
4 - Add Link Bonding Library to Doxygen

 app/test-pmd/cmdline.c            |  550 +++++
 app/test-pmd/parameters.c         |    4 +-
 app/test-pmd/testpmd.c            |   28 +-
 app/test-pmd/testpmd.h            |    2 +
 app/test/Makefile                 |    3 +
 app/test/commands.c               |    3 +
 app/test/packet_burst_generator.c |  276 +++
 app/test/packet_burst_generator.h |   85 +
 app/test/test.h                   |    1 +
 app/test/test_link_bonding.c      | 4007 +++++++++++++++++++++++++++++++++++++
 app/test/virtual_pmd.c            |  580 ++++++
 app/test/virtual_pmd.h            |   74 +
 config/common_bsdapp              |    5 +
 config/common_linuxapp            |    5 +
 doc/doxy-api-index.md             |    1 +
 doc/doxy-api.conf                 |    1 +
 lib/Makefile                      |    1 +
 lib/librte_bond/Makefile          |   28 +
 lib/librte_bond/rte_bond.c        | 1679 ++++++++++++++++
 lib/librte_bond/rte_bond.h        |  228 +++
 mk/rte.app.mk                     |    5 +
 21 files changed, 7564 insertions(+), 2 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_bond/Makefile
 create mode 100644 lib/librte_bond/rte_bond.c
 create mode 100644 lib/librte_bond/rte_bond.h
Signature · 1 line
1.8.5.3

A message that is not in the archive (sent off-list or not yet received): cover.1401287412.git.declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#2 lore raw

PATCH 1/4 Link Bonding Library

From: Declan Doherty <[email protected]>

Link Bonding Library (lib/librte_bond) initial release with support for
Mode 0 - Round Robin
Mode 1 - Active Backup
Mode 2 - Balance -> Supports 3 transmit polices (layer 2, layer 2+3, layer Mode 3 - Broadcast

---
 config/common_bsdapp       |    5 +
 config/common_linuxapp     |    5 +
 lib/Makefile               |    1 +
 lib/librte_bond/Makefile   |   28 +
 lib/librte_bond/rte_bond.c | 1679 ++++++++++++++++++++++++++++++++++++++++++++
 lib/librte_bond/rte_bond.h |  228 ++++++
 mk/rte.app.mk              |    5 +
 7 files changed, 1951 insertions(+)
 create mode 100644 lib/librte_bond/Makefile
 create mode 100644 lib/librte_bond/rte_bond.c
 create mode 100644 lib/librte_bond/rte_bond.h
config/common_bsdapp +5 -0
index 2cc7b80..53ed8b9 100644
@@ -187,6 +187,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=y
 
 #
+# Compile link bonding library
+#
+CONFIG_RTE_LIBRTE_BOND=y
+
+#
 # Do prefetch of packet data within PMD driver receive function
 #
 CONFIG_RTE_PMD_PACKET_PREFETCH=y
config/common_linuxapp +5 -0
index 62619c6..35b525a 100644
@@ -211,6 +211,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=n
 
 
+#
+# Compile link bonding library
+#
+CONFIG_RTE_LIBRTE_BOND=y
+
 CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
 
 #
lib/Makefile +1 -0
index b92b392..9995ba8 100644
@@ -47,6 +47,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += librte_pmd_pcap
 DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += librte_pmd_virtio
 DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += librte_pmd_vmxnet3
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += librte_pmd_xenvirt
+DIRS-$(CONFIG_RTE_LIBRTE_BOND) += librte_bond
 DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash
 DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm
 DIRS-$(CONFIG_RTE_LIBRTE_NET) += librte_net
lib/librte_bond/Makefile new file +28 -0
new file mode 100644
index 0000000..7514378
@@ -0,0 +1,28 @@
+# <COPYRIGHT_TAG>
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bond.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_BOND) += rte_bond.c
+
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_bond.h
+
+# this lib depends upon:
+DEPDIRS-$(CONFIG_RTE_LIBRTE_BOND) += lib/librte_mbuf lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_BOND) += lib/librte_malloc
+
+include $(RTE_SDK)/mk/rte.lib.mk
lib/librte_bond/rte_bond.c new file +1679 -0

1,679 lines not on this page · raw message

lib/librte_bond/rte_bond.h new file +228 -0

228 lines not on this page · raw message

mk/rte.app.mk +5 -0
index a836577..a803a5c 100644
@@ -177,8 +177,13 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMD_PCAP),y)
 LDLIBS += -lrte_pmd_pcap -lpcap
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_BOND),y)
+LDLIBS += -lrte_bond
 endif
 
+endif
+
+
 LDLIBS += $(EXECENV_LDLIBS)
 
 LDLIBS += --end-group
Signature · 1 line
1.8.5.3

A message that is not in the archive (sent off-list or not yet received): 4d8e6bc2665fbaac641f0577714d7be9b0415d3c.1401287412.git.declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#4 lore raw

Hi Declan,
I'm worried about one thing in "bond_ethdev_tx_broadcast()" related to freeing of the broadcasted packets.

Quoted 24 lines
lib/librte_bond/rte_bond.c new file +24 -0
+static uint16_t
+bond_ethdev_tx_broadcast(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
+{
+	struct bond_dev_private *internals;
+	struct bond_tx_queue *bd_tx_q;
+
+	uint8_t num_of_slaves;
+	uint8_t slaves[RTE_MAX_ETHPORTS];
+
+	uint16_t num_tx_total = 0;
+
+	int i;
+
+	bd_tx_q = (struct bond_tx_queue *)queue;
+	internals = bd_tx_q->dev_private;
+
+	/* Copy slave list to protect against slave up/down changes during tx
+	 * bursting */
+	num_of_slaves = internals->active_slave_count;
+	memcpy(slaves, internals->active_slaves,
+			sizeof(internals->active_slaves[0]) * num_of_slaves);
+
+	if (num_of_slaves < 1)
+		return 0;

lib/librte_bond/rte_bond.c line 489

Quoted 10 lines
lib/librte_bond/rte_bond.c new file +10 -0
+
+
+	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);
+	}
+
+	return num_tx_total;
+}
+

Transmitting the same buffers on all slaves will cause problems when the PMD frees the mbufs for previously transmitted packets.
So if you broadcast 1 packet on 4 slaves, each of the 4 slaves will (eventually) have to free the same mbuf. Without updating the refcnt, you will end up incorrectly freeing the same mbuf 3 extra times.

Your test application does not catch this case since the max packets that are tested is 320, which is less than the size of the Tx descriptor rings (512). Try testing with more packets and you should see some latent segmentation faults. You should also see this with testpmd, if you try broadcasting enough packets.

Thanks,
Jeff

A message that is not in the archive (sent off-list or not yet received): 4032A54B6BB5F04B8C08B6CFF08C59285543C357-AtyAts71sc9Qxe9IK+vIArfspsVTdybXVpNB7YpNyf8@public.gmane.org

#6 lore raw
Quoted 61 lines

-----Original Message-----
From: Shaw, Jeffrey B
Sent: Wednesday, May 28, 2014 5:55 PM
To: Doherty, Declan; [email protected]
Subject: RE: [dpdk-dev] [PATCH 1/4] Link Bonding Library

Hi Declan,
I'm worried about one thing in "bond_ethdev_tx_broadcast()" related to freeing of the broadcasted packets.

Quoted 29 lines
lib/librte_bond/rte_bond.c new file +28 -0
+static uint16_t
+bond_ethdev_tx_broadcast(void *queue, struct rte_mbuf **bufs,
+uint16_t nb_pkts) {
+	struct bond_dev_private *internals;
+	struct bond_tx_queue *bd_tx_q;
+
+	uint8_t num_of_slaves;
+	uint8_t slaves[RTE_MAX_ETHPORTS];
+
+	uint16_t num_tx_total = 0;
+
+	int i;
+
+	bd_tx_q = (struct bond_tx_queue *)queue;
+	internals = bd_tx_q->dev_private;
+
+	/* Copy slave list to protect against slave up/down changes during tx
+	 * bursting */
+	num_of_slaves = internals->active_slave_count;
+	memcpy(slaves, internals->active_slaves,
+			sizeof(internals->active_slaves[0]) * num_of_slaves);
+
+	if (num_of_slaves < 1)
+		return 0;
+
+
+	for (i = 0; i < num_of_slaves; i++) {
+		num_tx_total += rte_eth_tx_burst(slaves[i], bd_tx_q-

queue_id,

lib/librte_bond/rte_bond.c line 489

Quoted 6 lines
lib/librte_bond/rte_bond.c new file +6 -0
+				bufs, nb_pkts);
+	}
+
+	return num_tx_total;
+}
+

Transmitting the same buffers on all slaves will cause problems when the PMD frees the mbufs for previously transmitted packets.
So if you broadcast 1 packet on 4 slaves, each of the 4 slaves will (eventually) have to free the same mbuf. Without updating the refcnt, you will end up incorrectly freeing the same mbuf 3 extra times.

Your test application does not catch this case since the max packets that are tested is 320, which is less than the size of the Tx descriptor rings (512). Try testing with more packets and you should see some latent segmentation faults. You should also see this with testpmd, if you try broadcasting enough packets.

Quoted 2 lines

Thanks,
Jeff

Hey Jeff, I'm not sure why I didn't see this in testing using on the test-pmd app, but it's obvious that this will cause issues. I'll add code to increment the refcnt in each mbuf by (num_of_slaves -1) in the bond_ethdev_tx_broadcast() function and also add a unit test to validate this in the next version of the patch.

Thanks,
Declan
--------------------------------------------------------------
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.

#7 lore raw

PATCH 2/4 Link bonding unit tests

In reply to a message not in the archive

From: Declan Doherty <[email protected]>

Link bonding unit tests, including code to generate packet bursts for testing rx and tx functionality of bonded device and a
virtual/stubbed out ethdev for use as slave ethdev in testing

---
 app/test/Makefile                 |    3 +
 app/test/commands.c               |    3 +
 app/test/packet_burst_generator.c |  276 +++
 app/test/packet_burst_generator.h |   85 +
 app/test/test.h                   |    1 +
 app/test/test_link_bonding.c      | 4007 +++++++++++++++++++++++++++++++++++++
 app/test/virtual_pmd.c            |  580 ++++++
 app/test/virtual_pmd.h            |   74 +
 8 files changed, 5029 insertions(+)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
app/test/Makefile +3 -0
index b49785e..ac55a11 100644
@@ -56,6 +56,7 @@ SRCS-$(CONFIG_RTE_APP_TEST) += test_ring_perf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_rwlock.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_timer.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_mempool.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_link_bonding.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_mempool_perf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_mbuf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_logs.c
@@ -94,6 +95,8 @@ SRCS-$(CONFIG_RTE_APP_TEST) += test_common.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_timer_perf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_ivshmem.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_devargs.c
+SRCS-$(CONFIG_RTE_APP_TEST) += virtual_pmd.c
+SRCS-$(CONFIG_RTE_APP_TEST) += packet_burst_generator.c
 
 ifeq ($(CONFIG_RTE_APP_TEST),y)
 SRCS-$(CONFIG_RTE_LIBRTE_ACL) += test_acl.c
app/test/commands.c +3 -0
index efa8566..4d0ec3b 100644
@@ -157,6 +157,8 @@ static void cmd_autotest_parsed(void *parsed_result,
 		ret = test_timer();
 	if (!strcmp(res->autotest, "timer_perf_autotest"))
 		ret = test_timer_perf();
+	if (!strcmp(res->autotest, "link_bonding_autotest"))
+		ret = test_link_bonding();
 	if (!strcmp(res->autotest, "mempool_autotest"))
 		ret = test_mempool();
 	if (!strcmp(res->autotest, "mempool_perf_autotest"))
@@ -221,6 +223,7 @@ cmdline_parse_token_string_t cmd_autotest_autotest =
 			"alarm_autotest#interrupt_autotest#"
 			"version_autotest#eal_fs_autotest#"
 			"cmdline_autotest#func_reentrancy_autotest#"
+			"link_bonding_autotest#"
 			"mempool_perf_autotest#hash_perf_autotest#"
 			"memcpy_perf_autotest#ring_perf_autotest#"
 			"red_autotest#meter_autotest#sched_autotest#"
app/test/packet_burst_generator.c new file +276 -0

276 lines not on this page · raw message

app/test/packet_burst_generator.h new file +85 -0

85 lines not on this page · raw message

app/test/test.h +1 -0
index 1945d29..7213e1a 100644
@@ -94,6 +94,7 @@ int test_pmd_ring(void);
 int test_ivshmem(void);
 int test_kvargs(void);
 int test_devargs(void);
+int test_link_bonding(void);
 
 int test_pci_run;
 
app/test/test_link_bonding.c new file +4007 -0

2,602 lines not on this page · raw message

app/test/virtual_pmd.c new file +580 -0

580 lines not on this page · raw message

app/test/virtual_pmd.h new file +74 -0

74 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.8.5.3

Part of the diff is not shown here. View the raw message.

#8 lore raw

PATCH 3/4 Link bonding integration into testpmd

In reply to a message not in the archive

From: Declan Doherty <[email protected]>

Adding link bonding support to testpmd.
- Includes the ability to create new bonded devices.
- Add /remove bonding slave devices.
- Interogate bonded device stats/configuration
- Change bonding modes and select balance transmit polices

---
 app/test-pmd/cmdline.c    | 550 ++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/parameters.c |   4 +-
 app/test-pmd/testpmd.c    |  28 ++-
 app/test-pmd/testpmd.h    |   2 +
 4 files changed, 582 insertions(+), 2 deletions(-)
app/test-pmd/cmdline.c +550 -0
index 0be28f6..7c7c9f3 100644
@@ -84,6 +84,9 @@
 #include <cmdline_socket.h>
 #include <cmdline.h>
 #include <rte_pci_dev_ids.h>
+#ifdef RTE_LIBRTE_BOND
+#include <rte_bond.h>
+#endif
 
 #include "testpmd.h"
 
@@ -393,6 +396,31 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"   Show the bypass configuration for a bypass enabled NIC"
 			" using the lowest port on the NIC.\n\n"
 #endif
+#ifdef RTE_LIBRTE_BOND
+			"create bonded device (mode) (socket)\n"
+			"	Create a new bonded device with specific bonding mode and socket.\n\n"
+
+			"add bonding slave (slave_id) (port_id)\n"
+			"	Add a slave device to a bonded device.\n\n"
+
+			"remove bonding slave (slave_id) (port_id)\n"
+			"	Remove a slave device from a bonded device.\n\n"
+
+			"set bonding mode (value) (port_id)\n"
+			"	Set the bonding mode on a bonded device.\n\n"
+
+			"set bonding primary (slave_id) (port_id)\n"
+			"	Set the primary slave for a bonded device.\n\n"
+
+			"show bonding config (port_id)\n"
+			"	Show the bonding config for port_id.\n\n"
+
+			"set bonding mac_addr (port_id) (address)\n"
+			"	Set the MAC address of a bonded device.\n\n"
+
+			"set bonding xmit_balance_policy (port_id) (l2|l23|l34)\n"
+			"	Set the transmit balance policy for bonded device running in balance mode.\n\n"
+#endif
 
 			, list_pkt_forwarding_modes()
 		);
@@ -2849,6 +2877,518 @@ cmdline_parse_inst_t cmd_show_bypass_config = {
 };
 #endif
 
+#ifdef RTE_LIBRTE_BOND
+/* *** SET BONDING MODE *** */
+struct cmd_set_bonding_mode_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t mode;
+	uint8_t value;
+	uint8_t port_id;
+};
+
+static void cmd_set_bonding_mode_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_mode_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+
+	/* Set the bonding mode for the relevant port. */
+	if (0 != rte_eth_bond_mode_set(port_id, res->value)) {
+		printf("\t Failed to set bonding mode for port = %d.\n", port_id);
+	}
+}
+
+cmdline_parse_token_string_t cmd_setbonding_mode_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_mode_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_mode_mode =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		mode, "mode");
+cmdline_parse_token_num_t cmd_setbonding_mode_value =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+		value, UINT8);
+cmdline_parse_token_num_t cmd_setbonding_mode_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bonding_mode = { .f = cmd_set_bonding_mode_parsed,
+		.help_str = "set bonding mode (mode_value) (port_id): "
+				"Set the bonding mode for port_id", .data = NULL, .tokens = {
+				(void *) &cmd_setbonding_mode_set,
+				(void *) &cmd_setbonding_mode_bonding,
+				(void *) &cmd_setbonding_mode_mode,
+				(void *) &cmd_setbonding_mode_value,
+				(void *) &cmd_setbonding_mode_port,
+				NULL, }, };
+
+/* *** SET BALANCE XMIT POLICY *** */
+struct cmd_set_bonding_balance_xmit_policy_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t balance_xmit_policy;
+	uint8_t port_id;
+	cmdline_fixed_string_t policy;
+};
+
+static void cmd_set_bonding_balance_xmit_policy_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_balance_xmit_policy_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+	uint8_t policy;
+
+	if (!strcmp(res->policy, "l2")) {
+		policy = BALANCE_XMIT_POLICY_LAYER2;
+	} else if (!strcmp(res->policy, "l23")) {
+		policy = BALANCE_XMIT_POLICY_LAYER23;
+	} else if (!strcmp(res->policy, "l34")) {
+		policy = BALANCE_XMIT_POLICY_LAYER34;
+	} else {
+		printf("\t Invalid xmit policy selection");
+		return;
+	}
+
+	/* Set the bonding mode for the relevant port. */
+	if (0 != rte_eth_bond_xmit_policy_set(port_id, policy)) {
+		printf("\t Failed to set bonding balance xmit policy for port = %d.\n",
+				port_id);
+	}
+}
+
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_balance_xmit_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		balance_xmit_policy, "balance_xmit_policy");
+cmdline_parse_token_num_t cmd_setbonding_balance_xmit_policy_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		port_id, UINT8);
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		policy, "l2#l23#l34");
+
+cmdline_parse_inst_t cmd_set_balance_xmit_policy =
+		{ .f = cmd_set_bonding_balance_xmit_policy_parsed, .help_str =
+				"set bonding balance_xmit_policy (port_id) (policy_value): "
+						"Set the bonding balance_xmit_policy for port_id",
+				.data = NULL,
+				.tokens =
+						{ (void *) &cmd_setbonding_balance_xmit_policy_set,
+								(void *) &cmd_setbonding_balance_xmit_policy_bonding,
+								(void *) &cmd_setbonding_balance_xmit_policy_balance_xmit_policy,
+								(void *) &cmd_setbonding_balance_xmit_policy_port,
+								(void *) &cmd_setbonding_balance_xmit_policy_policy,
+								NULL, }, };
+
+/* *** SHOW NIC BONDING CONFIGURATION *** */
+struct cmd_show_bonding_config_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+};
+
+static void cmd_show_bonding_config_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_show_bonding_config_result *res = parsed_result;
+	int bonding_mode;
+	const uint8_t *slaves;
+	int num_slaves, num_active_slaves;
+	int primary_id;
+	int i;
+	portid_t port_id = res->port_id;
+
+	/* Display the bonding mode.*/
+	bonding_mode = rte_eth_bond_mode_get(port_id);
+	if (bonding_mode < 0) {
+		printf("\tFailed to get bonding mode for port = %d\n", port_id);
+		return;
+	} else
+		printf("\tBonding mode: %d\n", bonding_mode);
+
+	if (bonding_mode == BONDING_MODE_BALANCE) {
+		int balance_xmit_policy;
+
+		balance_xmit_policy = rte_eth_bond_xmit_policy_get(port_id);
+		if (balance_xmit_policy < 0) {
+			printf("\tFailed to get balance xmit policy for port = %d\n",
+					port_id);
+			return;
+		} else {
+			printf("\tBalance Xmit Policy: ");
+
+			switch (balance_xmit_policy) {
+			case BALANCE_XMIT_POLICY_LAYER2:
+				printf("BALANCE_XMIT_POLICY_LAYER2");
+				break;
+			case BALANCE_XMIT_POLICY_LAYER23:
+				printf("BALANCE_XMIT_POLICY_LAYER23");
+				break;
+			case BALANCE_XMIT_POLICY_LAYER34:
+				printf("BALANCE_XMIT_POLICY_LAYER34");
+				break;
+			}
+			printf("\n");
+		}
+	}
+
+	num_slaves = rte_eth_bond_slaves_get(port_id, &slaves);
+
+	if (num_slaves < 0) {
+		printf("\tFailed to get slave list for port = %d\n", port_id);
+		return;
+	}
+	if (num_slaves > 0) {
+		printf("\tSlaves (%d): [", num_slaves);
+		for (i = 0; i < num_slaves - 1; i++) {
+			printf("%d ", slaves[i]);
+		}
+		printf("%d]\n", slaves[num_slaves - 1]);
+	} else {
+		printf("\tSlaves: []\n");
+
+	}
+
+	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, &slaves);
+
+	if (num_active_slaves < 0) {
+		printf("\tFailed to get active slave list for port = %d\n", port_id);
+		return;
+	}
+	if (num_active_slaves > 0) {
+		printf("\tActive Slaves (%d): [", num_active_slaves);
+		for (i = 0; i < num_active_slaves - 1; i++) {
+			printf("%d ", slaves[i]);
+		}
+		printf("%d]\n", slaves[num_active_slaves - 1]);
+
+	} else {
+		printf("\tActive Slaves: []\n");
+
+	}
+
+	primary_id = rte_eth_bond_primary_get(port_id);
+	if (primary_id < 0) {
+		printf("\tFailed to get primary slave for port = %d\n", port_id);
+		return;
+	} else
+		printf("\tPrimary: [%d]\n", primary_id);
+
+}
+
+cmdline_parse_token_string_t cmd_showbonding_config_show =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		show, "show");
+cmdline_parse_token_string_t cmd_showbonding_config_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_showbonding_config_config =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		config, "config");
+cmdline_parse_token_num_t cmd_showbonding_config_port =
+TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_config_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_show_bonding_config = { .f =
+		cmd_show_bonding_config_parsed, .help_str =
+		"show bonding config (port_id): "
+				"Show the bonding config for port_id", .data = NULL, .tokens = {
+		(void *) &cmd_showbonding_config_show,
+		(void *) &cmd_showbonding_config_bonding,
+		(void *) &cmd_showbonding_config_config,
+		(void *) &cmd_showbonding_config_port,
+		NULL, }, };
+
+/* *** SET BONDING PRIMARY *** */
+struct cmd_set_bonding_primary_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t primary;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_set_bonding_primary_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_primary_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_primary_set(master_port_id, slave_port_id)) {
+		printf("\t Failed to set primary slave for port = %d.\n",
+				master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_setbonding_primary_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_primary_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_primary_primary =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		primary, "primary");
+cmdline_parse_token_num_t cmd_setbonding_primary_slave =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+		slave_id, UINT8);
+cmdline_parse_token_num_t cmd_setbonding_primary_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bonding_primary = { .f =
+		cmd_set_bonding_primary_parsed, .help_str =
+		"set bonding primary (slave_id) (port_id): "
+				"Set the primary slave for port_id", .data = NULL, .tokens = {
+		(void *) &cmd_setbonding_primary_set,
+		(void *) &cmd_setbonding_primary_bonding,
+		(void *) &cmd_setbonding_primary_primary,
+		(void *) &cmd_setbonding_primary_slave,
+		(void *) &cmd_setbonding_primary_port,
+		NULL, }, };
+
+/* *** ADD SLAVE *** */
+struct cmd_add_bonding_slave_result {
+	cmdline_fixed_string_t add;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t slave;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_add_bonding_slave_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_add_bonding_slave_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_slave_add(master_port_id, slave_port_id)) {
+		printf("\t Failed to add slave %d to master port = %d.\n",
+				slave_port_id, master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_addbonding_slave_add =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		add, "add");
+cmdline_parse_token_string_t cmd_addbonding_slave_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_addbonding_slave_slave =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		slave, "slave");
+cmdline_parse_token_num_t cmd_addbonding_slave_slaveid =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+		slave_id, UINT8);
+cmdline_parse_token_num_t cmd_addbonding_slave_port =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_add_bonding_slave = {
+		.f = cmd_add_bonding_slave_parsed, .help_str =
+				"add bonding slave (slave_id) (port_id): "
+						"Add a slave device to a bonded device", .data = NULL,
+		.tokens = { (void *) &cmd_addbonding_slave_add,
+				(void *) &cmd_addbonding_slave_bonding,
+				(void *) &cmd_addbonding_slave_slave,
+				(void *) &cmd_addbonding_slave_slaveid,
+				(void *) &cmd_addbonding_slave_port,
+				NULL, }, };
+
+/* *** REMOVE SLAVE *** */
+struct cmd_remove_bonding_slave_result {
+	cmdline_fixed_string_t remove;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t slave;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_remove_bonding_slave_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_remove_bonding_slave_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_slave_remove(master_port_id, slave_port_id)) {
+		printf("\t Failed to remove slave %d from master port = %d.\n",
+				slave_port_id, master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_removebonding_slave_remove =
+TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+		remove, "remove");
+cmdline_parse_token_string_t cmd_removebonding_slave_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_removebonding_slave_slave =
+TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+		slave, "slave");
+cmdline_parse_token_num_t cmd_removebonding_slave_slaveid =
+TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+		slave_id, UINT8);
+cmdline_parse_token_num_t cmd_removebonding_slave_port =
+TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_remove_bonding_slave = { .f =
+		cmd_remove_bonding_slave_parsed, .help_str =
+		"remove bonding slave (slave_id) (port_id): "
+				"Remove a slave device from a bonded device", .data = NULL,
+		.tokens = { (void *) &cmd_removebonding_slave_remove,
+				(void *) &cmd_removebonding_slave_bonding,
+				(void *) &cmd_removebonding_slave_slave,
+				(void *) &cmd_removebonding_slave_slaveid,
+				(void *) &cmd_removebonding_slave_port,
+				NULL, }, };
+
+/* *** CREATE BONDED DEVICE *** */
+struct cmd_create_bonded_device_result {
+	cmdline_fixed_string_t create;
+	cmdline_fixed_string_t bonded;
+	cmdline_fixed_string_t device;
+	uint8_t mode;
+	uint8_t socket;
+};
+
+static void cmd_create_bonded_device_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_create_bonded_device_result *res = parsed_result;
+
+	int port_id;
+	if (test_done == 0) {
+		printf("Please stop forwarding first\n");
+		return;
+	}
+
+	port_id = rte_eth_bond_create("testpmd-bonded-dev", res->mode, res->socket);
+	/* Create a new bonded device. */
+	if (port_id < 0) {
+		printf("\t Failed to create bonded device.\n");
+		return;
+	} else {
+		printf("\t Created new bonded device (port %d).\n", port_id);
+		/* Update number of ports */
+		nb_ports = rte_eth_dev_count();
+		reconfig(port_id);
+		rte_eth_promiscuous_enable(port_id);
+	}
+
+}
+
+cmdline_parse_token_string_t cmd_createbonded_device_create =
+TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+		create, "create");
+cmdline_parse_token_string_t cmd_createbonded_device_bonded =
+TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+		bonded, "bonded");
+cmdline_parse_token_string_t cmd_createbonded_device_device =
+TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+		device, "device");
+cmdline_parse_token_num_t cmd_createbonded_device_mode =
+TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+		mode, UINT8);
+cmdline_parse_token_num_t cmd_createbonded_device_socket =
+TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+		socket, UINT8);
+
+cmdline_parse_inst_t cmd_create_bonded_device =
+		{ .f = cmd_create_bonded_device_parsed,
+				.help_str =
+						"create bonded device (mode) (socket): "
+								"Create a new bonded device with specific bonding mode and socket",
+				.data = NULL, .tokens = {
+						(void *) &cmd_createbonded_device_create,
+						(void *) &cmd_createbonded_device_bonded,
+						(void *) &cmd_createbonded_device_device,
+						(void *) &cmd_createbonded_device_mode,
+						(void *) &cmd_createbonded_device_socket,
+						NULL, }, };
+
+/* *** SET MAC ADDRESS IN BONDED DEVICE *** */
+struct cmd_set_bond_mac_addr_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t mac_addr;
+	uint8_t port_num;
+	struct ether_addr address;
+};
+
+static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bond_mac_addr_result *res = parsed_result;
+	int ret;
+
+	if (res->port_num >= nb_ports) {
+		printf("Port id %d must be less than %d\n", res->port_num, nb_ports);
+		return;
+	}
+
+	ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
+
+	/* check the return value and print it if is < 0 */
+	if (ret < 0)
+		printf("set_bond_mac_addr error: (%s)\n", strerror(-ret));
+}
+
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, set,
+		"set");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, bonding,
+		"bonding");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, mac_addr,
+		"mac_addr");
+cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result, port_num, UINT8);
+cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr =
+TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result, address);
+
+cmdline_parse_inst_t cmd_set_bond_mac_addr = {
+		.f = cmd_set_bond_mac_addr_parsed, .data = (void *) 0, .help_str =
+				"set bonding mac_addr (port_id) (address): ", .tokens = {
+				(void *) &cmd_set_bond_mac_addr_set,
+				(void *) &cmd_set_bond_mac_addr_bonding,
+				(void *) &cmd_set_bond_mac_addr_mac,
+				(void *) &cmd_set_bond_mac_addr_portnum,
+				(void *) &cmd_set_bond_mac_addr_addr,
+				NULL, }, };
+
+#endif /* RTE_LIBRTE_BOND */
+
 /* *** SET FORWARDING MODE *** */
 struct cmd_set_fwd_mode_result {
 	cmdline_fixed_string_t set;
@@ -5333,6 +5873,16 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_bypass_timeout,
 	(cmdline_parse_inst_t *)&cmd_show_bypass_config,
 #endif
+#ifdef RTE_LIBRTE_BOND
+	(cmdline_parse_inst_t *) &cmd_set_bonding_mode,
+	(cmdline_parse_inst_t *) &cmd_show_bonding_config,
+	(cmdline_parse_inst_t *) &cmd_set_bonding_primary,
+	(cmdline_parse_inst_t *) &cmd_add_bonding_slave,
+	(cmdline_parse_inst_t *) &cmd_remove_bonding_slave,
+	(cmdline_parse_inst_t *) &cmd_create_bonded_device,
+	(cmdline_parse_inst_t *) &cmd_set_bond_mac_addr,
+	(cmdline_parse_inst_t *) &cmd_set_balance_xmit_policy,
+#endif
 	(cmdline_parse_inst_t *)&cmd_vlan_offload,
 	(cmdline_parse_inst_t *)&cmd_vlan_tpid,
 	(cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all,
app/test-pmd/parameters.c +3 -1
index 7a60048..6b44ef0 100644
@@ -75,7 +75,9 @@
 #include <cmdline_parse.h>
 #include <cmdline_parse_etheraddr.h>
 #endif
-
+#ifdef RTE_LIBRTE_BOND
+#include <rte_bond.h>
+#endif
 #include "testpmd.h"
 
 static void
app/test-pmd/testpmd.c +27 -1
index bc38305..a49b322 100644
@@ -300,7 +300,7 @@ struct rte_fdir_conf fdir_conf = {
 	.drop_queue = 127,
 };
 
-static volatile int test_done = 1; /* stop packet forwarding when set to 1. */
+volatile int test_done = 1; /* stop packet forwarding when set to 1. */
 
 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
@@ -625,6 +625,32 @@ init_config(void)
 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
 }
 
+
+void
+reconfig(portid_t new_port_id)
+{
+	struct rte_port *port;
+
+	/* Reconfiguration of Ethernet ports. */
+	ports = rte_realloc(ports,
+			    sizeof(struct rte_port) * nb_ports,
+			    CACHE_LINE_SIZE);
+	if (ports == NULL) {
+		rte_exit(EXIT_FAILURE, "rte_realloc(%d struct rte_port) "
+							"failed\n", nb_ports);
+	}
+
+	port = &ports[new_port_id];
+	rte_eth_dev_info_get(new_port_id, &port->dev_info);
+
+	/* set flag to initialize port/queue */
+	port->need_reconfig = 1;
+	port->need_reconfig_queues = 1;
+
+	init_port_config();
+}
+
+
 int
 init_fwd_streams(void)
 {
app/test-pmd/testpmd.h +2 -0
index 0cf5a92..1f54787 100644
@@ -279,6 +279,7 @@ extern uint16_t port_topology; /**< set by "--port-topology" parameter */
 extern uint8_t no_flush_rx; /**<set by "--no-flush-rx" parameter */
 extern uint8_t  mp_anon; /**< set by "--mp-anon" parameter */
 extern uint8_t no_link_check; /**<set by "--disable-link-check" parameter */
+extern volatile int test_done; /* stop packet forwarding when set to 1. */
 
 #ifdef RTE_NIC_BYPASS
 extern uint32_t bypass_timeout; /**< Store the NIC bypass watchdog timeout */
@@ -452,6 +453,7 @@ void fwd_config_display(void);
 void rxtx_config_display(void);
 void fwd_config_setup(void);
 void set_def_fwd_config(void);
+void reconfig(portid_t new_port_id);
 int init_fwd_streams(void);
 
 
Signature · 1 line
1.8.5.3
#9 lore raw

PATCH 4/4 Add Link Bonding Library to Doxygen

In reply to a message not in the archive

From: Declan Doherty <[email protected]>

---
 doc/doxy-api-index.md | 1 +
 doc/doxy-api.conf     | 1 +
 2 files changed, 2 insertions(+)
doc/doxy-api-index.md +1 -0
index 2825c08..2206c68 100644
@@ -36,6 +36,7 @@ API {#index}
 There are many libraries, so their headers may be grouped by topics:
 
 - **device**:
+  [bond]               (@ref rte_bond.h),
   [ethdev]             (@ref rte_ethdev.h),
   [devargs]            (@ref rte_devargs.h),
   [KNI]                (@ref rte_kni.h),
doc/doxy-api.conf +1 -0
index 642f77a..a9c5b30 100644
@@ -30,6 +30,7 @@
 
 PROJECT_NAME            = DPDK
 INPUT                   = doc/doxy-api-index.md \
+                          lib/librte_bond \
                           lib/librte_eal/common/include \
                           lib/librte_ether \
                           lib/librte_hash \
Signature · 1 line
1.8.5.3
#10 lore raw
In reply to a message not in the archive
Quoted 9 lines · On Wed, May 28, 2014 at 04:32:00PM +0100…

From: Declan Doherty <[email protected]>

Initial release of Link Bonding Library (lib/librte_bond) with support for bonding modes :
0 - Round Robin
1 - Active Backup
2 - Balance l2 / l23 / l34
3 - Broadcast

Why make this a separate library? That requires exposure of yet another API to applications. Instead, why not write a PMD that can enslave other PMD's and treat them all as a single interface? That way this all works with the existing API.

Neil

Quoted 48 lines

patches split:
1 - library + makefile changes
2 - Unit test suite, including code to generate packet bursts for
testing rx and tx functionality of bonded device and a virtual/stubbed out ethdev for use as slave ethdev in testing
3 - Link bonding integration into testpmd, including :
- Includes the ability to create new bonded devices.
- Add /remove bonding slave devices.
- Interogate bonded device stats/configuration
- Change bonding modes and select balance transmit polices
4 - Add Link Bonding Library to Doxygen

 app/test-pmd/cmdline.c            |  550 +++++
 app/test-pmd/parameters.c         |    4 +-
 app/test-pmd/testpmd.c            |   28 +-
 app/test-pmd/testpmd.h            |    2 +
 app/test/Makefile                 |    3 +
 app/test/commands.c               |    3 +
 app/test/packet_burst_generator.c |  276 +++
 app/test/packet_burst_generator.h |   85 +
 app/test/test.h                   |    1 +
 app/test/test_link_bonding.c      | 4007 +++++++++++++++++++++++++++++++++++++
 app/test/virtual_pmd.c            |  580 ++++++
 app/test/virtual_pmd.h            |   74 +
 config/common_bsdapp              |    5 +
 config/common_linuxapp            |    5 +
 doc/doxy-api-index.md             |    1 +
 doc/doxy-api.conf                 |    1 +
 lib/Makefile                      |    1 +
 lib/librte_bond/Makefile          |   28 +
 lib/librte_bond/rte_bond.c        | 1679 ++++++++++++++++
 lib/librte_bond/rte_bond.h        |  228 +++
 mk/rte.app.mk                     |    5 +
 21 files changed, 7564 insertions(+), 2 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_bond/Makefile
 create mode 100644 lib/librte_bond/rte_bond.c
 create mode 100644 lib/librte_bond/rte_bond.h
Signature · 1 line
1.8.5.3

A message that is not in the archive (sent off-list or not yet received): 20140528174908.GB2648-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]

#12 lore raw

-----Original Message-----

Quoted 16 lines

From: Neil Horman [mailto:[email protected]]
Sent: Wednesday, May 28, 2014 6:49 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH 0/4] Link Bonding Library

Quoted 9 lines · On Wed, May 28, 2014 at 04:32:00PM +0100…

From: Declan Doherty <[email protected]>

Initial release of Link Bonding Library (lib/librte_bond) with support for bonding modes :
0 - Round Robin
1 - Active Backup
2 - Balance l2 / l23 / l34
3 - Broadcast

Quoted 3 lines

Why make this a separate library? That requires exposure of yet another API to applications. Instead, why > not write a PMD that can enslave other PMD's and treat them all as a single interface? That way this all > > works with the existing API.

Neil

Hi Neil,
the link bonding device is essentially a software PMD, and as such supports all the standard PMD APIs, the only new APIs which the link bonding library introduces are for the control operations of the bonded device which are currently unsupported by the standard PMD API. Operations such as creating, adding/removing slaves, and configuring the modes of operation of the device have no analogous APIs in the current PMD API and required new ones to be created .

Declan
--------------------------------------------------------------
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.

A message that is not in the archive (sent off-list or not yet received): 345C63BAECC1AD42A2EC8C63AFFC3ADC13D3327C-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org

#14 lore raw
Quoted 17 lines · Declan

-----Original Message-----

Quoted 16 lines

From: Neil Horman [mailto:[email protected]]
Sent: Wednesday, May 28, 2014 6:49 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH 0/4] Link Bonding Library

Quoted 9 lines · On Wed, May 28, 2014 at 04:32:00PM +0100…

From: Declan Doherty <[email protected]>

Initial release of Link Bonding Library (lib/librte_bond) with support for bonding modes :
0 - Round Robin
1 - Active Backup
2 - Balance l2 / l23 / l34
3 - Broadcast

Quoted 6 lines
Quoted 3 lines

Why make this a separate library? That requires exposure of yet another API to applications. Instead, why > not write a PMD that can enslave other PMD's and treat them all as a single interface? That way this all > > works with the existing API.

Neil

Hi Neil,
the link bonding device is essentially a software PMD, and as such supports all the standard PMD APIs, the only new APIs which the link bonding library introduces are for the control operations of the bonded device which are currently unsupported by the standard PMD API. Operations such as creating, adding/removing slaves, and configuring the modes of operation of the device have no analogous APIs in the current PMD API and required new ones to be created .

Thats really only true in spirit, in the sense that this library transmits and receives frames like a PMD does. In practice it doesn't work and isn't architected the same way. You don't register the driver using the same method as the other PMDs, which means that using --vdev on the command line wont work for this type of device. It also implies that applications have to be made specifically aware of the fact that they are using a bonded interface (i.e. they need to call the bonding setup routines to create the bond). I would recommend:

1) Register the pmd using the PMD_DRIVER_REGISTER macro, like other PMD's
2) Use the kvargs library to support configuration via the --vdev command line option, so bonds can be created administratively, rather than just programatically
3) Separate the command api from the PMD functionality into separate libraries (use control mbufs to communicate configuration changes to the pmd). This will allow users to dynamically load the pmd functionality (without compile or run time linking requirements), and then optionally use the programatic interface (or not if they want to save memory)

Regards
Neil

Quoted 13 lines

Declan
--------------------------------------------------------------
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.

#15 lore raw
In reply to a message not in the archive

Hi declan,

Do you send out Patch 1,2, 3 for link bonding?
Only see patch 0 and 4.

Thanks
Waterman

-----Original Message-----
From: dev [mailto:[email protected]] On Behalf Of [email protected]
Sent: Wednesday, May 28, 2014 11:32 PM
To: [email protected]; [email protected]
Subject: [dpdk-dev] [PATCH 0/4] Link Bonding Library

From: Declan Doherty <[email protected]>

Initial release of Link Bonding Library (lib/librte_bond) with support for bonding modes :
0 - Round Robin
1 - Active Backup
2 - Balance l2 / l23 / l34
3 - Broadcast

patches split:
1 - library + makefile changes
2 - Unit test suite, including code to generate packet bursts for
testing rx and tx functionality of bonded device and a virtual/stubbed out ethdev for use as slave ethdev in testing
3 - Link bonding integration into testpmd, including :
- Includes the ability to create new bonded devices.
- Add /remove bonding slave devices.
- Interogate bonded device stats/configuration
- Change bonding modes and select balance transmit polices
4 - Add Link Bonding Library to Doxygen

 app/test-pmd/cmdline.c            |  550 +++++
 app/test-pmd/parameters.c         |    4 +-
 app/test-pmd/testpmd.c            |   28 +-
 app/test-pmd/testpmd.h            |    2 +
 app/test/Makefile                 |    3 +
 app/test/commands.c               |    3 +
 app/test/packet_burst_generator.c |  276 +++
 app/test/packet_burst_generator.h |   85 +
 app/test/test.h                   |    1 +
 app/test/test_link_bonding.c      | 4007 +++++++++++++++++++++++++++++++++++++
 app/test/virtual_pmd.c            |  580 ++++++
 app/test/virtual_pmd.h            |   74 +
 config/common_bsdapp              |    5 +
 config/common_linuxapp            |    5 +
 doc/doxy-api-index.md             |    1 +
 doc/doxy-api.conf                 |    1 +
 lib/Makefile                      |    1 +
 lib/librte_bond/Makefile          |   28 +
 lib/librte_bond/rte_bond.c        | 1679 ++++++++++++++++
 lib/librte_bond/rte_bond.h        |  228 +++
 mk/rte.app.mk                     |    5 +
 21 files changed, 7564 insertions(+), 2 deletions(-)  create mode 100644 app/test/packet_burst_generator.c  create mode 100644 app/test/packet_burst_generator.h  create mode 100644 app/test/test_link_bonding.c  create mode 100644 app/test/virtual_pmd.c  create mode 100644 app/test/virtual_pmd.h  create mode 100644 lib/librte_bond/Makefile  create mode 100644 lib/librte_bond/rte_bond.c  create mode 100644 lib/librte_bond/rte_bond.h

--
1.8.5.3

A message that is not in the archive (sent off-list or not yet received): AA3F441F262C58498CD6D0C1801DE7EB0AA89A63-0J0gbvR4kTggGBtAFL8yw7fspsVTdybXVpNB7YpNyf8@public.gmane.org

#17 lore raw
Quoted 6 lines

From: Cao, Waterman
Sent: Thursday, May 29, 2014 4:23 AM
To: Doherty, Declan; [email protected]; [email protected]
Cc: Cao, Waterman
Subject: RE: [dpdk-dev] [PATCH 0/4] Link Bonding Library

Quoted 7 lines

Hi declan,

Do you send out Patch 1,2, 3 for link bonding?
Only see patch 0 and 4.

Thanks
Waterman

Hi Waterman,

As far as I can see all the patches have been submitted, and are visible on the mailing list archives.

Declan
--------------------------------------------------------------
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.

#18 lore raw

v2 cover Link Bonding Library

In reply to a message not in the archive

From: Declan Doherty <[email protected]>

v2 patch additions,
fix for tx burst broadcast, incrementing the reference count on each mbuf by the number of slaves - 1 add/remove slave behavior chnange to fix primary slave port assignment
patchcheck code fixes

Initial release of Link Bonding Library (lib/librte_bond) with support for bonding modes :
0 - Round Robin
1 - Active Backup
2 - Balance l2 / l23 / l34
3 - Broadcast

patches split:
1 - library + makefile changes
2 - Unit test suite, including code to generate packet bursts for
testing rx and tx functionality of bonded device and a virtual/stubbed out ethdev for use as slave ethdev in testing
3 - Link bonding integration into testpmd, including :
- Includes the ability to create new bonded devices.
- Add /remove bonding slave devices.
- Interogate bonded device stats/configuration
- Change bonding modes and select balance transmit polices
4 - Add Link Bonding Library to Doxygen

 app/test-pmd/cmdline.c            |  570 ++++++
 app/test-pmd/config.c             |    4 +-
 app/test-pmd/parameters.c         |    4 +-
 app/test-pmd/testpmd.c            |   37 +-
 app/test-pmd/testpmd.h            |    2 +
 app/test/Makefile                 |    3 +
 app/test/commands.c               |    3 +
 app/test/packet_burst_generator.c |  289 +++
 app/test/packet_burst_generator.h |   78 +
 app/test/test.h                   |    1 +
 app/test/test_link_bonding.c      | 3943 +++++++++++++++++++++++++++++++++++++
 app/test/virtual_pmd.c            |  574 ++++++
 app/test/virtual_pmd.h            |   74 +
 config/common_bsdapp              |    5 +
 config/common_linuxapp            |    5 +
 doc/doxy-api-index.md             |    1 +
 doc/doxy-api.conf                 |    1 +
 lib/Makefile                      |    1 +
 lib/librte_bond/Makefile          |   28 +
 lib/librte_bond/rte_bond.c        | 1682 ++++++++++++++++
 lib/librte_bond/rte_bond.h        |  228 +++
 mk/rte.app.mk                     |    5 +
 22 files changed, 7531 insertions(+), 7 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_bond/Makefile
 create mode 100644 lib/librte_bond/rte_bond.c
 create mode 100644 lib/librte_bond/rte_bond.h
Signature · 1 line
1.8.5.3
#19 lore raw

PATCH v2 1/4 Link Bonding Library

In reply to a message not in the archive

From: Declan Doherty <[email protected]>

- Broadcast TX burst broadcast bug fix
- Add/remove slave behavior fix
- Checkpatch fixes

---
 config/common_bsdapp       |    5 +
 config/common_linuxapp     |    5 +
 lib/Makefile               |    1 +
 lib/librte_bond/Makefile   |   28 +
 lib/librte_bond/rte_bond.c | 1682 ++++++++++++++++++++++++++++++++++++++++++++
 lib/librte_bond/rte_bond.h |  228 ++++++
 mk/rte.app.mk              |    5 +
 7 files changed, 1954 insertions(+)
 create mode 100644 lib/librte_bond/Makefile
 create mode 100644 lib/librte_bond/rte_bond.c
 create mode 100644 lib/librte_bond/rte_bond.h
config/common_bsdapp +5 -0
index 2cc7b80..53ed8b9 100644
@@ -187,6 +187,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=y
 
 #
+# Compile link bonding library
+#
+CONFIG_RTE_LIBRTE_BOND=y
+
+#
 # Do prefetch of packet data within PMD driver receive function
 #
 CONFIG_RTE_PMD_PACKET_PREFETCH=y
config/common_linuxapp +5 -0
index 62619c6..35b525a 100644
@@ -211,6 +211,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=n
 
 
+#
+# Compile link bonding library
+#
+CONFIG_RTE_LIBRTE_BOND=y
+
 CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
 
 #
lib/Makefile +1 -0
index b92b392..9995ba8 100644
@@ -47,6 +47,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += librte_pmd_pcap
 DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += librte_pmd_virtio
 DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += librte_pmd_vmxnet3
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += librte_pmd_xenvirt
+DIRS-$(CONFIG_RTE_LIBRTE_BOND) += librte_bond
 DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash
 DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm
 DIRS-$(CONFIG_RTE_LIBRTE_NET) += librte_net
lib/librte_bond/Makefile new file +28 -0
new file mode 100644
index 0000000..7514378
@@ -0,0 +1,28 @@
+# <COPYRIGHT_TAG>
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bond.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_BOND) += rte_bond.c
+
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_bond.h
+
+# this lib depends upon:
+DEPDIRS-$(CONFIG_RTE_LIBRTE_BOND) += lib/librte_mbuf lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_BOND) += lib/librte_malloc
+
+include $(RTE_SDK)/mk/rte.lib.mk
lib/librte_bond/rte_bond.c new file +1682 -0

1,682 lines not on this page · raw message

lib/librte_bond/rte_bond.h new file +228 -0

228 lines not on this page · raw message

mk/rte.app.mk +5 -0
index a836577..a803a5c 100644
@@ -177,8 +177,13 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMD_PCAP),y)
 LDLIBS += -lrte_pmd_pcap -lpcap
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_BOND),y)
+LDLIBS += -lrte_bond
 endif
 
+endif
+
+
 LDLIBS += $(EXECENV_LDLIBS)
 
 LDLIBS += --end-group
Signature · 1 line
1.8.5.3

A message that is not in the archive (sent off-list or not yet received): e6e8ecba5e2ba9d1a0e5299e042e7c54757e8644.1401891670.git.declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#21 lore raw
Quoted 7 lines · On Wed, 4 Jun 2014 16:18:02 +0100 declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public…

From: Declan Doherty <[email protected]>

- Broadcast TX burst broadcast bug fix
- Add/remove slave behavior fix
- Checkpatch fixes

There are some pretty weak hash functions in there.

What about using:

lib/librte_eal/common/include/rte_common.h +25 -0
@@ -365,6 +365,31 @@ rte_str_to_size(const char *str)
 }
 
 /**
+ * Multiplicative hash functions useful to distrbute
+ * a uniform set of consective keys
+ *
+ * @param val
+ *	The input uniform key
+ * @param bits
+ *	Number of bits desired
+ */
+#define GOLDEN_RATIO_32      2654404609U
+static inline uint32_t
+rte_fib_hash32(uint32_t val, unsigned int bits)
+{
+	val *= GOLDEN_RATIO_32;
+	return val >> (32 - bits);
+}
+
+#define	GOLDEN_RATIO_64	0x9e37fffffffc0001UL
+static inline uint64_t
+rte_fib_hash64(uint64_t val, unsigned bits)
+{
+	val *= GOLDEN_RATIO_64;
+	return val >> (64 - bits);
+}
+
+/**
  * Function to terminate the application immediately, printing an error
  * message and returning the exit_code back to the shell.
  *
lib/librte_ether/rte_ether.h +76 -0

88 lines not on this page · raw message

A message that is not in the archive (sent off-list or not yet received): 20140605081557.42a797e8-We1ePj4FEcvRI77zikRAJc56i+j3xesD0e7PPNI6Mm0@public.gmane.org

#23 lore raw
Quoted 16 lines

-----Original Message-----
From: Stephen Hemminger [mailto:[email protected]]
Sent: Thursday, June 5, 2014 4:16 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v2 1/4] Link Bonding Library

Quoted 6 lines · On Wed, 4 Jun 2014 16:18:02 +0100 declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public…

From: Declan Doherty <[email protected]>

- Broadcast TX burst broadcast bug fix
- Add/remove slave behavior fix
- Checkpatch fixes

Quoted 6 lines
Quoted 1 line

There are some pretty weak hash functions in there.

What about using:
.....

Hi Stephen,

I suppose the naming of these as hash functions is probably misleading, the aim is not to create a unique hash for each flow with minimal collisions but to help balance traffic flows across the slaves of the bonded device, and as we are doing a modulus calculation based on the number of slaves attached, which I believe will typically be in the 2-4 range, I'm not sure that a stronger hashing function will give a better balance of flows across the slaves. For example in the Linux kernel implementation of the link bonding driver the mac hashing only uses the last byte of src & dst mac addresses to calculate it's eth hash.

/* L2 hash helper */
static inline u32 bond_eth_hash(struct sk_buff *skb)

{
	struct ethhdr *data = (struct ethhdr *)skb->data;

	if (skb_headlen(skb) >= offsetof(struct ethhdr, h_proto))
		return data->h_dest[5] ^ data->h_source[5];

	return 0;
}

I'll investigate and see if a stronger hashing function will result in a better balancing of flows.
--------------------------------------------------------------
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.

A message that is not in the archive (sent off-list or not yet received): 345C63BAECC1AD42A2EC8C63AFFC3ADC13D3737A-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org

#25 lore raw
Quoted 46 lines · Declan
Quoted 16 lines

-----Original Message-----
From: Stephen Hemminger [mailto:[email protected]]
Sent: Thursday, June 5, 2014 4:16 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v2 1/4] Link Bonding Library

Quoted 6 lines · On Wed, 4 Jun 2014 16:18:02 +0100 declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public…

From: Declan Doherty <[email protected]>

- Broadcast TX burst broadcast bug fix
- Add/remove slave behavior fix
- Checkpatch fixes

Quoted 6 lines
Quoted 1 line

There are some pretty weak hash functions in there.

What about using:
.....

Hi Stephen,

I suppose the naming of these as hash functions is probably misleading, the aim is not to create a unique hash for each flow with minimal collisions but to help balance traffic flows across the slaves of the bonded device, and as we are doing a modulus calculation based on the number of slaves attached, which I believe will typically be in the 2-4 range, I'm not sure that a stronger hashing function will give a better balance of flows across the slaves. For example in the Linux kernel implementation of the link bonding driver the mac hashing only uses the last byte of src & dst mac addresses to calculate it's eth hash.

/* L2 hash helper */
static inline u32 bond_eth_hash(struct sk_buff *skb)

{
	struct ethhdr *data = (struct ethhdr *)skb->data;

	if (skb_headlen(skb) >= offsetof(struct ethhdr, h_proto))
		return data->h_dest[5] ^ data->h_source[5];

	return 0;
}

I'll investigate and see if a stronger hashing function will result in a better balancing of flows.
--------------------------------------------------------------
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

Quoted 3 lines

This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.

The ether hash is very quick using multplicative hash on 64 bit value.

#26 lore raw
In reply to a message not in the archive
Quoted 3 lines · Declan Doherty

- Broadcast TX burst broadcast bug fix
- Add/remove slave behavior fix
- Checkpatch fixes

Declan, would you consider the following change to rte_bond.c? The two header files from librte_cmdline don't seem to be necessary.

Eric

lib/librte_bond/rte_bond.c +0 -3
@@ -44,9 +44,6 @@
 #include <rte_ip.h>
 #include <rte_udp.h>
 
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-
 #include "rte_bond.h"
 
 static const char *driver_name = "Link Bonding PMD";

A message that is not in the archive (sent off-list or not yet received): 20140609211054.GA4853-5G/Vjf02Nsf/[email protected]

#28 lore raw
Quoted 21 lines

-----Original Message-----
From: Eric Kinzie [mailto:[email protected]]
Sent: Monday, June 9, 2014 10:11 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v2 1/4] Link Bonding Library

Quoted 3 lines · Declan Doherty

- Broadcast TX burst broadcast bug fix
- Add/remove slave behavior fix
- Checkpatch fixes

Declan, would you consider the following change to rte_bond.c? The two header files from librte_cmdline don't seem to be necessary.

Eric

lib/librte_bond/rte_bond.c line 49

Quoted 9 lines
lib/librte_bond/rte_bond.c +0 -3
@@ -44,9 +44,6 @@
 #include <rte_ip.h>
 #include <rte_udp.h>
 
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-
 #include "rte_bond.h"
 
 static const char *driver_name = "Link Bonding PMD";

Hi Eric,
I've cleaned up the includes in v3 of the patch, but the those headers are now actually required for the kvarg parsing.

Regards
Declan

#29 lore raw

PATCH v2 2/4 Link bonding unit tests, including: - code to generate packet bursts for testing rx and tx functionality of bonded device - virtual/stubbed out ethdev for use as slave ethdev in testing - checkpack fixes

In reply to a message not in the archive

From: Declan Doherty <[email protected]>

---
 app/test/Makefile                 |    3 +
 app/test/commands.c               |    3 +
 app/test/packet_burst_generator.c |  289 +++
 app/test/packet_burst_generator.h |   78 +
 app/test/test.h                   |    1 +
 app/test/test_link_bonding.c      | 3943 +++++++++++++++++++++++++++++++++++++
 app/test/virtual_pmd.c            |  574 ++++++
 app/test/virtual_pmd.h            |   74 +
 8 files changed, 4965 insertions(+)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
app/test/Makefile +3 -0
index b49785e..ac55a11 100644
@@ -56,6 +56,7 @@ SRCS-$(CONFIG_RTE_APP_TEST) += test_ring_perf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_rwlock.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_timer.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_mempool.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_link_bonding.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_mempool_perf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_mbuf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_logs.c
@@ -94,6 +95,8 @@ SRCS-$(CONFIG_RTE_APP_TEST) += test_common.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_timer_perf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_ivshmem.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_devargs.c
+SRCS-$(CONFIG_RTE_APP_TEST) += virtual_pmd.c
+SRCS-$(CONFIG_RTE_APP_TEST) += packet_burst_generator.c
 
 ifeq ($(CONFIG_RTE_APP_TEST),y)
 SRCS-$(CONFIG_RTE_LIBRTE_ACL) += test_acl.c
app/test/commands.c +3 -0
index efa8566..4d0ec3b 100644
@@ -157,6 +157,8 @@ static void cmd_autotest_parsed(void *parsed_result,
 		ret = test_timer();
 	if (!strcmp(res->autotest, "timer_perf_autotest"))
 		ret = test_timer_perf();
+	if (!strcmp(res->autotest, "link_bonding_autotest"))
+		ret = test_link_bonding();
 	if (!strcmp(res->autotest, "mempool_autotest"))
 		ret = test_mempool();
 	if (!strcmp(res->autotest, "mempool_perf_autotest"))
@@ -221,6 +223,7 @@ cmdline_parse_token_string_t cmd_autotest_autotest =
 			"alarm_autotest#interrupt_autotest#"
 			"version_autotest#eal_fs_autotest#"
 			"cmdline_autotest#func_reentrancy_autotest#"
+			"link_bonding_autotest#"
 			"mempool_perf_autotest#hash_perf_autotest#"
 			"memcpy_perf_autotest#ring_perf_autotest#"
 			"red_autotest#meter_autotest#sched_autotest#"
app/test/packet_burst_generator.c new file +289 -0

289 lines not on this page · raw message

app/test/packet_burst_generator.h new file +78 -0

78 lines not on this page · raw message

app/test/test.h +1 -0
index 1945d29..7213e1a 100644
@@ -94,6 +94,7 @@ int test_pmd_ring(void);
 int test_ivshmem(void);
 int test_kvargs(void);
 int test_devargs(void);
+int test_link_bonding(void);
 
 int test_pci_run;
 
app/test/test_link_bonding.c new file +3943 -0

2,596 lines not on this page · raw message

app/test/virtual_pmd.c new file +574 -0

574 lines not on this page · raw message

app/test/virtual_pmd.h new file +74 -0

74 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.8.5.3

Part of the diff is not shown here. View the raw message.

#30 lore raw

v2 cover Link Bonding Library

In reply to a message not in the archive

From: Declan Doherty <[email protected]>

v2 patch additions,
fix for tx burst broadcast, incrementing the reference count on each mbuf by the number of slaves - 1 add/remove slave behavior chnange to fix primary slave port assignment
patchcheck code fixes

Initial release of Link Bonding Library (lib/librte_bond) with support for bonding modes :
0 - Round Robin
1 - Active Backup
2 - Balance l2 / l23 / l34
3 - Broadcast

patches split:
1 - library + makefile changes
2 - Unit test suite, including code to generate packet bursts for
testing rx and tx functionality of bonded device and a virtual/stubbed out ethdev for use as slave ethdev in testing
3 - Link bonding integration into testpmd, including :
- Includes the ability to create new bonded devices.
- Add /remove bonding slave devices.
- Interogate bonded device stats/configuration
- Change bonding modes and select balance transmit polices
4 - Add Link Bonding Library to Doxygen

 app/test-pmd/cmdline.c            |  570 ++++++
 app/test-pmd/config.c             |    4 +-
 app/test-pmd/parameters.c         |    4 +-
 app/test-pmd/testpmd.c            |   37 +-
 app/test-pmd/testpmd.h            |    2 +
 app/test/Makefile                 |    3 +
 app/test/commands.c               |    3 +
 app/test/packet_burst_generator.c |  289 +++
 app/test/packet_burst_generator.h |   78 +
 app/test/test.h                   |    1 +
 app/test/test_link_bonding.c      | 3943 +++++++++++++++++++++++++++++++++++++
 app/test/virtual_pmd.c            |  574 ++++++
 app/test/virtual_pmd.h            |   74 +
 config/common_bsdapp              |    5 +
 config/common_linuxapp            |    5 +
 doc/doxy-api-index.md             |    1 +
 doc/doxy-api.conf                 |    1 +
 lib/Makefile                      |    1 +
 lib/librte_bond/Makefile          |   28 +
 lib/librte_bond/rte_bond.c        | 1682 ++++++++++++++++
 lib/librte_bond/rte_bond.h        |  228 +++
 mk/rte.app.mk                     |    5 +
 22 files changed, 7531 insertions(+), 7 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_bond/Makefile
 create mode 100644 lib/librte_bond/rte_bond.c
 create mode 100644 lib/librte_bond/rte_bond.h
Signature · 1 line
1.8.5.3
#31 lore raw

PATCH v2 1/4 Link Bonding Library

In reply to a message not in the archive

From: Declan Doherty <[email protected]>

- Broadcast TX burst broadcast bug fix
- Add/remove slave behavior fix
- Checkpatch fixes

---
 config/common_bsdapp       |    5 +
 config/common_linuxapp     |    5 +
 lib/Makefile               |    1 +
 lib/librte_bond/Makefile   |   28 +
 lib/librte_bond/rte_bond.c | 1682 ++++++++++++++++++++++++++++++++++++++++++++
 lib/librte_bond/rte_bond.h |  228 ++++++
 mk/rte.app.mk              |    5 +
 7 files changed, 1954 insertions(+)
 create mode 100644 lib/librte_bond/Makefile
 create mode 100644 lib/librte_bond/rte_bond.c
 create mode 100644 lib/librte_bond/rte_bond.h
config/common_bsdapp +5 -0
index 2cc7b80..53ed8b9 100644
@@ -187,6 +187,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=y
 
 #
+# Compile link bonding library
+#
+CONFIG_RTE_LIBRTE_BOND=y
+
+#
 # Do prefetch of packet data within PMD driver receive function
 #
 CONFIG_RTE_PMD_PACKET_PREFETCH=y
config/common_linuxapp +5 -0
index 62619c6..35b525a 100644
@@ -211,6 +211,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=n
 
 
+#
+# Compile link bonding library
+#
+CONFIG_RTE_LIBRTE_BOND=y
+
 CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
 
 #
lib/Makefile +1 -0
index b92b392..9995ba8 100644
@@ -47,6 +47,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += librte_pmd_pcap
 DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += librte_pmd_virtio
 DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += librte_pmd_vmxnet3
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += librte_pmd_xenvirt
+DIRS-$(CONFIG_RTE_LIBRTE_BOND) += librte_bond
 DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash
 DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm
 DIRS-$(CONFIG_RTE_LIBRTE_NET) += librte_net
lib/librte_bond/Makefile new file +28 -0
new file mode 100644
index 0000000..7514378
@@ -0,0 +1,28 @@
+# <COPYRIGHT_TAG>
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_bond.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_BOND) += rte_bond.c
+
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_bond.h
+
+# this lib depends upon:
+DEPDIRS-$(CONFIG_RTE_LIBRTE_BOND) += lib/librte_mbuf lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_BOND) += lib/librte_malloc
+
+include $(RTE_SDK)/mk/rte.lib.mk
lib/librte_bond/rte_bond.c new file +1682 -0

1,682 lines not on this page · raw message

lib/librte_bond/rte_bond.h new file +228 -0

228 lines not on this page · raw message

mk/rte.app.mk +5 -0
index a836577..a803a5c 100644
@@ -177,8 +177,13 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMD_PCAP),y)
 LDLIBS += -lrte_pmd_pcap -lpcap
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_BOND),y)
+LDLIBS += -lrte_bond
 endif
 
+endif
+
+
 LDLIBS += $(EXECENV_LDLIBS)
 
 LDLIBS += --end-group
Signature · 1 line
1.8.5.3
#32 lore raw

PATCH v2 2/4 Link bonding unit tests, including: - code to generate packet bursts for testing rx and tx functionality of bonded device - virtual/stubbed out ethdev for use as slave ethdev in testing - checkpack fixes

In reply to a message not in the archive

From: Declan Doherty <[email protected]>

---
 app/test/Makefile                 |    3 +
 app/test/commands.c               |    3 +
 app/test/packet_burst_generator.c |  289 +++
 app/test/packet_burst_generator.h |   78 +
 app/test/test.h                   |    1 +
 app/test/test_link_bonding.c      | 3943 +++++++++++++++++++++++++++++++++++++
 app/test/virtual_pmd.c            |  574 ++++++
 app/test/virtual_pmd.h            |   74 +
 8 files changed, 4965 insertions(+)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
app/test/Makefile +3 -0
index b49785e..ac55a11 100644
@@ -56,6 +56,7 @@ SRCS-$(CONFIG_RTE_APP_TEST) += test_ring_perf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_rwlock.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_timer.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_mempool.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_link_bonding.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_mempool_perf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_mbuf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_logs.c
@@ -94,6 +95,8 @@ SRCS-$(CONFIG_RTE_APP_TEST) += test_common.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_timer_perf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_ivshmem.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_devargs.c
+SRCS-$(CONFIG_RTE_APP_TEST) += virtual_pmd.c
+SRCS-$(CONFIG_RTE_APP_TEST) += packet_burst_generator.c
 
 ifeq ($(CONFIG_RTE_APP_TEST),y)
 SRCS-$(CONFIG_RTE_LIBRTE_ACL) += test_acl.c
app/test/commands.c +3 -0
index efa8566..4d0ec3b 100644
@@ -157,6 +157,8 @@ static void cmd_autotest_parsed(void *parsed_result,
 		ret = test_timer();
 	if (!strcmp(res->autotest, "timer_perf_autotest"))
 		ret = test_timer_perf();
+	if (!strcmp(res->autotest, "link_bonding_autotest"))
+		ret = test_link_bonding();
 	if (!strcmp(res->autotest, "mempool_autotest"))
 		ret = test_mempool();
 	if (!strcmp(res->autotest, "mempool_perf_autotest"))
@@ -221,6 +223,7 @@ cmdline_parse_token_string_t cmd_autotest_autotest =
 			"alarm_autotest#interrupt_autotest#"
 			"version_autotest#eal_fs_autotest#"
 			"cmdline_autotest#func_reentrancy_autotest#"
+			"link_bonding_autotest#"
 			"mempool_perf_autotest#hash_perf_autotest#"
 			"memcpy_perf_autotest#ring_perf_autotest#"
 			"red_autotest#meter_autotest#sched_autotest#"
app/test/packet_burst_generator.c new file +289 -0

289 lines not on this page · raw message

app/test/packet_burst_generator.h new file +78 -0

78 lines not on this page · raw message

app/test/test.h +1 -0
index 1945d29..7213e1a 100644
@@ -94,6 +94,7 @@ int test_pmd_ring(void);
 int test_ivshmem(void);
 int test_kvargs(void);
 int test_devargs(void);
+int test_link_bonding(void);
 
 int test_pci_run;
 
app/test/test_link_bonding.c new file +3943 -0

2,596 lines not on this page · raw message

app/test/virtual_pmd.c new file +574 -0

574 lines not on this page · raw message

app/test/virtual_pmd.h new file +74 -0

74 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.8.5.3

Part of the diff is not shown here. View the raw message.

#33 lore raw

PATCH v2 3/4 Adding link bonding support to testpmd. - Includes the ability to create new bonded devices. - Add /remove bonding slave devices. - Interogate bonded device stats/configuration - Change bonding modes and select balance transmit polices

In reply to a message not in the archive

From: Declan Doherty <[email protected]>

- Display of port mac address fix
- Checkpatch fixes

---
 app/test-pmd/cmdline.c    | 570 ++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/config.c     |   4 +-
 app/test-pmd/parameters.c |   4 +-
 app/test-pmd/testpmd.c    |  37 ++-
 app/test-pmd/testpmd.h    |   2 +
 5 files changed, 610 insertions(+), 7 deletions(-)
app/test-pmd/cmdline.c +570 -0
index 0be28f6..27909f3 100644
@@ -84,6 +84,9 @@
 #include <cmdline_socket.h>
 #include <cmdline.h>
 #include <rte_pci_dev_ids.h>
+#ifdef RTE_LIBRTE_BOND
+#include <rte_bond.h>
+#endif
 
 #include "testpmd.h"
 
@@ -393,6 +396,31 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"   Show the bypass configuration for a bypass enabled NIC"
 			" using the lowest port on the NIC.\n\n"
 #endif
+#ifdef RTE_LIBRTE_BOND
+			"create bonded device (mode) (socket)\n"
+			"	Create a new bonded device with specific bonding mode and socket.\n\n"
+
+			"add bonding slave (slave_id) (port_id)\n"
+			"	Add a slave device to a bonded device.\n\n"
+
+			"remove bonding slave (slave_id) (port_id)\n"
+			"	Remove a slave device from a bonded device.\n\n"
+
+			"set bonding mode (value) (port_id)\n"
+			"	Set the bonding mode on a bonded device.\n\n"
+
+			"set bonding primary (slave_id) (port_id)\n"
+			"	Set the primary slave for a bonded device.\n\n"
+
+			"show bonding config (port_id)\n"
+			"	Show the bonding config for port_id.\n\n"
+
+			"set bonding mac_addr (port_id) (address)\n"
+			"	Set the MAC address of a bonded device.\n\n"
+
+			"set bonding xmit_balance_policy (port_id) (l2|l23|l34)\n"
+			"	Set the transmit balance policy for bonded device running in balance mode.\n\n"
+#endif
 
 			, list_pkt_forwarding_modes()
 		);
@@ -2849,6 +2877,538 @@ cmdline_parse_inst_t cmd_show_bypass_config = {
 };
 #endif
 
+#ifdef RTE_LIBRTE_BOND
+/* *** SET BONDING MODE *** */
+struct cmd_set_bonding_mode_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t mode;
+	uint8_t value;
+	uint8_t port_id;
+};
+
+static void cmd_set_bonding_mode_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_mode_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+
+	/* Set the bonding mode for the relevant port. */
+	if (0 != rte_eth_bond_mode_set(port_id, res->value))
+		printf("\t Failed to set bonding mode for port = %d.\n", port_id);
+}
+
+cmdline_parse_token_string_t cmd_setbonding_mode_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_mode_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_mode_mode =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		mode, "mode");
+cmdline_parse_token_num_t cmd_setbonding_mode_value =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+		value, UINT8);
+cmdline_parse_token_num_t cmd_setbonding_mode_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bonding_mode = {
+		.f = cmd_set_bonding_mode_parsed,
+		.help_str = "set bonding mode (mode_value) (port_id): Set the bonding mode for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *) &cmd_setbonding_mode_set,
+				(void *) &cmd_setbonding_mode_bonding,
+				(void *) &cmd_setbonding_mode_mode,
+				(void *) &cmd_setbonding_mode_value,
+				(void *) &cmd_setbonding_mode_port,
+				NULL
+		}
+};
+
+/* *** SET BALANCE XMIT POLICY *** */
+struct cmd_set_bonding_balance_xmit_policy_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t balance_xmit_policy;
+	uint8_t port_id;
+	cmdline_fixed_string_t policy;
+};
+
+static void cmd_set_bonding_balance_xmit_policy_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_balance_xmit_policy_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+	uint8_t policy;
+
+	if (!strcmp(res->policy, "l2")) {
+		policy = BALANCE_XMIT_POLICY_LAYER2;
+	} else if (!strcmp(res->policy, "l23")) {
+		policy = BALANCE_XMIT_POLICY_LAYER23;
+	} else if (!strcmp(res->policy, "l34")) {
+		policy = BALANCE_XMIT_POLICY_LAYER34;
+	} else {
+		printf("\t Invalid xmit policy selection");
+		return;
+	}
+
+	/* Set the bonding mode for the relevant port. */
+	if (0 != rte_eth_bond_xmit_policy_set(port_id, policy)) {
+		printf("\t Failed to set bonding balance xmit policy for port = %d.\n",
+				port_id);
+	}
+}
+
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_balance_xmit_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		balance_xmit_policy, "balance_xmit_policy");
+cmdline_parse_token_num_t cmd_setbonding_balance_xmit_policy_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		port_id, UINT8);
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		policy, "l2#l23#l34");
+
+cmdline_parse_inst_t cmd_set_balance_xmit_policy = {
+		.f = cmd_set_bonding_balance_xmit_policy_parsed,
+		.help_str = "set bonding balance_xmit_policy (port_id) (policy_value): Set the bonding balance_xmit_policy for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_setbonding_balance_xmit_policy_set,
+				(void *)&cmd_setbonding_balance_xmit_policy_bonding,
+				(void *)&cmd_setbonding_balance_xmit_policy_balance_xmit_policy,
+				(void *)&cmd_setbonding_balance_xmit_policy_port,
+				(void *)&cmd_setbonding_balance_xmit_policy_policy,
+				NULL
+		}
+};
+
+/* *** SHOW NIC BONDING CONFIGURATION *** */
+struct cmd_show_bonding_config_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+};
+
+static void cmd_show_bonding_config_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_show_bonding_config_result *res = parsed_result;
+	int bonding_mode;
+	const uint8_t *slaves;
+	int num_slaves, num_active_slaves;
+	int primary_id;
+	int i;
+	portid_t port_id = res->port_id;
+
+	/* Display the bonding mode.*/
+	bonding_mode = rte_eth_bond_mode_get(port_id);
+	if (bonding_mode < 0) {
+		printf("\tFailed to get bonding mode for port = %d\n", port_id);
+		return;
+	} else
+		printf("\tBonding mode: %d\n", bonding_mode);
+
+	if (bonding_mode == BONDING_MODE_BALANCE) {
+		int balance_xmit_policy;
+
+		balance_xmit_policy = rte_eth_bond_xmit_policy_get(port_id);
+		if (balance_xmit_policy < 0) {
+			printf("\tFailed to get balance xmit policy for port = %d\n",
+					port_id);
+			return;
+		} else {
+			printf("\tBalance Xmit Policy: ");
+
+			switch (balance_xmit_policy) {
+			case BALANCE_XMIT_POLICY_LAYER2:
+				printf("BALANCE_XMIT_POLICY_LAYER2");
+				break;
+			case BALANCE_XMIT_POLICY_LAYER23:
+				printf("BALANCE_XMIT_POLICY_LAYER23");
+				break;
+			case BALANCE_XMIT_POLICY_LAYER34:
+				printf("BALANCE_XMIT_POLICY_LAYER34");
+				break;
+			}
+			printf("\n");
+		}
+	}
+
+	num_slaves = rte_eth_bond_slaves_get(port_id, &slaves);
+
+	if (num_slaves < 0) {
+		printf("\tFailed to get slave list for port = %d\n", port_id);
+		return;
+	}
+	if (num_slaves > 0) {
+		printf("\tSlaves (%d): [", num_slaves);
+		for (i = 0; i < num_slaves - 1; i++)
+			printf("%d ", slaves[i]);
+
+		printf("%d]\n", slaves[num_slaves - 1]);
+	} else {
+		printf("\tSlaves: []\n");
+
+	}
+
+	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, &slaves);
+
+	if (num_active_slaves < 0) {
+		printf("\tFailed to get active slave list for port = %d\n", port_id);
+		return;
+	}
+	if (num_active_slaves > 0) {
+		printf("\tActive Slaves (%d): [", num_active_slaves);
+		for (i = 0; i < num_active_slaves - 1; i++)
+			printf("%d ", slaves[i]);
+
+		printf("%d]\n", slaves[num_active_slaves - 1]);
+
+	} else {
+		printf("\tActive Slaves: []\n");
+
+	}
+
+	primary_id = rte_eth_bond_primary_get(port_id);
+	if (primary_id < 0) {
+		printf("\tFailed to get primary slave for port = %d\n", port_id);
+		return;
+	} else
+		printf("\tPrimary: [%d]\n", primary_id);
+
+}
+
+cmdline_parse_token_string_t cmd_showbonding_config_show =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		show, "show");
+cmdline_parse_token_string_t cmd_showbonding_config_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_showbonding_config_config =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		config, "config");
+cmdline_parse_token_num_t cmd_showbonding_config_port =
+TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_config_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_show_bonding_config = {
+		.f = cmd_show_bonding_config_parsed,
+		.help_str =	"show bonding config (port_id): Show the bonding config for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_showbonding_config_show,
+				(void *)&cmd_showbonding_config_bonding,
+				(void *)&cmd_showbonding_config_config,
+				(void *)&cmd_showbonding_config_port,
+				NULL
+		}
+};
+
+/* *** SET BONDING PRIMARY *** */
+struct cmd_set_bonding_primary_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t primary;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_set_bonding_primary_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_primary_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_primary_set(master_port_id, slave_port_id)) {
+		printf("\t Failed to set primary slave for port = %d.\n",
+				master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_setbonding_primary_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_primary_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_primary_primary =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		primary, "primary");
+cmdline_parse_token_num_t cmd_setbonding_primary_slave =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+		slave_id, UINT8);
+cmdline_parse_token_num_t cmd_setbonding_primary_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bonding_primary = {
+		.f = cmd_set_bonding_primary_parsed,
+		.help_str = "set bonding primary (slave_id) (port_id): Set the primary slave for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_setbonding_primary_set,
+				(void *)&cmd_setbonding_primary_bonding,
+				(void *)&cmd_setbonding_primary_primary,
+				(void *)&cmd_setbonding_primary_slave,
+				(void *)&cmd_setbonding_primary_port,
+				NULL
+		}
+};
+
+/* *** ADD SLAVE *** */
+struct cmd_add_bonding_slave_result {
+	cmdline_fixed_string_t add;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t slave;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_add_bonding_slave_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_add_bonding_slave_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_slave_add(master_port_id, slave_port_id)) {
+		printf("\t Failed to add slave %d to master port = %d.\n",
+				slave_port_id, master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_addbonding_slave_add =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		add, "add");
+cmdline_parse_token_string_t cmd_addbonding_slave_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_addbonding_slave_slave =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		slave, "slave");
+cmdline_parse_token_num_t cmd_addbonding_slave_slaveid =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+		slave_id, UINT8);
+cmdline_parse_token_num_t cmd_addbonding_slave_port =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_add_bonding_slave = {
+		.f = cmd_add_bonding_slave_parsed,
+		.help_str = "add bonding slave (slave_id) (port_id): Add a slave device to a bonded device",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_addbonding_slave_add,
+				(void *)&cmd_addbonding_slave_bonding,
+				(void *)&cmd_addbonding_slave_slave,
+				(void *)&cmd_addbonding_slave_slaveid,
+				(void *)&cmd_addbonding_slave_port,
+				NULL
+		}
+};
+
+/* *** REMOVE SLAVE *** */
+struct cmd_remove_bonding_slave_result {
+	cmdline_fixed_string_t remove;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t slave;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_remove_bonding_slave_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_remove_bonding_slave_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_slave_remove(master_port_id, slave_port_id)) {
+		printf("\t Failed to remove slave %d from master port = %d.\n",
+				slave_port_id, master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_removebonding_slave_remove =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				remove, "remove");
+cmdline_parse_token_string_t cmd_removebonding_slave_bonding =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				bonding, "bonding");
+cmdline_parse_token_string_t cmd_removebonding_slave_slave =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				slave, "slave");
+cmdline_parse_token_num_t cmd_removebonding_slave_slaveid =
+		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				slave_id, UINT8);
+cmdline_parse_token_num_t cmd_removebonding_slave_port =
+		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				port_id, UINT8);
+
+cmdline_parse_inst_t cmd_remove_bonding_slave = {
+		.f = cmd_remove_bonding_slave_parsed,
+		.help_str = "remove bonding slave (slave_id) (port_id): Remove a slave device from a bonded device",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_removebonding_slave_remove,
+				(void *)&cmd_removebonding_slave_bonding,
+				(void *)&cmd_removebonding_slave_slave,
+				(void *)&cmd_removebonding_slave_slaveid,
+				(void *)&cmd_removebonding_slave_port,
+				NULL
+		}
+};
+
+/* *** CREATE BONDED DEVICE *** */
+struct cmd_create_bonded_device_result {
+	cmdline_fixed_string_t create;
+	cmdline_fixed_string_t bonded;
+	cmdline_fixed_string_t device;
+	uint8_t mode;
+	uint8_t socket;
+};
+
+static void cmd_create_bonded_device_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_create_bonded_device_result *res = parsed_result;
+
+	int port_id;
+	if (test_done == 0) {
+		printf("Please stop forwarding first\n");
+		return;
+	}
+
+	port_id = rte_eth_bond_create("testpmd-bonded-dev", res->mode, res->socket);
+	/* Create a new bonded device. */
+	if (port_id < 0) {
+		printf("\t Failed to create bonded device.\n");
+		return;
+	} else {
+		printf("\t Created new bonded device (port %d).\n", port_id);
+		/* Update number of ports */
+		nb_ports = rte_eth_dev_count();
+		reconfig(port_id);
+		rte_eth_promiscuous_enable(port_id);
+	}
+
+}
+
+cmdline_parse_token_string_t cmd_createbonded_device_create =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				create, "create");
+cmdline_parse_token_string_t cmd_createbonded_device_bonded =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				bonded, "bonded");
+cmdline_parse_token_string_t cmd_createbonded_device_device =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				device, "device");
+cmdline_parse_token_num_t cmd_createbonded_device_mode =
+		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+				mode, UINT8);
+cmdline_parse_token_num_t cmd_createbonded_device_socket =
+		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+				socket, UINT8);
+
+cmdline_parse_inst_t cmd_create_bonded_device = {
+		.f = cmd_create_bonded_device_parsed,
+		.help_str = "create bonded device (mode) (socket): Create a new bonded device with specific bonding mode and socket",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_createbonded_device_create,
+				(void *)&cmd_createbonded_device_bonded,
+				(void *)&cmd_createbonded_device_device,
+				(void *)&cmd_createbonded_device_mode,
+				(void *)&cmd_createbonded_device_socket,
+				NULL
+		}
+};
+
+/* *** SET MAC ADDRESS IN BONDED DEVICE *** */
+struct cmd_set_bond_mac_addr_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t mac_addr;
+	uint8_t port_num;
+	struct ether_addr address;
+};
+
+static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bond_mac_addr_result *res = parsed_result;
+	int ret;
+
+	if (res->port_num >= nb_ports) {
+		printf("Port id %d must be less than %d\n", res->port_num, nb_ports);
+		return;
+	}
+
+	ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
+
+	/* check the return value and print it if is < 0 */
+	if (ret < 0)
+		printf("set_bond_mac_addr error: (%s)\n", strerror(-ret));
+}
+
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_set =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, set, "set");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, bonding,
+				"bonding");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, mac_addr,
+				"mac_addr");
+cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum =
+		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result, port_num, UINT8);
+cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr =
+		TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result, address);
+
+cmdline_parse_inst_t cmd_set_bond_mac_addr = {
+		.f = cmd_set_bond_mac_addr_parsed,
+		.data = (void *) 0,
+		.help_str = "set bonding mac_addr (port_id) (address): ",
+		.tokens = {
+				(void *)&cmd_set_bond_mac_addr_set,
+				(void *)&cmd_set_bond_mac_addr_bonding,
+				(void *)&cmd_set_bond_mac_addr_mac,
+				(void *)&cmd_set_bond_mac_addr_portnum,
+				(void *)&cmd_set_bond_mac_addr_addr,
+				NULL
+		}
+};
+
+#endif /* RTE_LIBRTE_BOND */
+
 /* *** SET FORWARDING MODE *** */
 struct cmd_set_fwd_mode_result {
 	cmdline_fixed_string_t set;
@@ -5333,6 +5893,16 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_bypass_timeout,
 	(cmdline_parse_inst_t *)&cmd_show_bypass_config,
 #endif
+#ifdef RTE_LIBRTE_BOND
+	(cmdline_parse_inst_t *) &cmd_set_bonding_mode,
+	(cmdline_parse_inst_t *) &cmd_show_bonding_config,
+	(cmdline_parse_inst_t *) &cmd_set_bonding_primary,
+	(cmdline_parse_inst_t *) &cmd_add_bonding_slave,
+	(cmdline_parse_inst_t *) &cmd_remove_bonding_slave,
+	(cmdline_parse_inst_t *) &cmd_create_bonded_device,
+	(cmdline_parse_inst_t *) &cmd_set_bond_mac_addr,
+	(cmdline_parse_inst_t *) &cmd_set_balance_xmit_policy,
+#endif
 	(cmdline_parse_inst_t *)&cmd_vlan_offload,
 	(cmdline_parse_inst_t *)&cmd_vlan_tpid,
 	(cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all,
app/test-pmd/config.c +3 -1
index d6291e7..1ef9a39 100644
@@ -242,6 +242,7 @@ void
 port_infos_display(portid_t port_id)
 {
 	struct rte_port *port;
+	struct ether_addr mac_addr;
 	struct rte_eth_link link;
 	int vlan_offload;
 	struct rte_mempool * mp;
@@ -255,7 +256,8 @@ port_infos_display(portid_t port_id)
 	rte_eth_link_get_nowait(port_id, &link);
 	printf("\n%s Infos for port %-2d %s\n",
 	       info_border, port_id, info_border);
-	print_ethaddr("MAC address: ", &port->eth_addr);
+	rte_eth_macaddr_get(port_id, &mac_addr);
+	print_ethaddr("MAC address: ", &mac_addr);
 	printf("\nConnect to socket: %u", port->socket_id);
 
 	if (port_numa[port_id] != NUMA_NO_CONFIG) {
app/test-pmd/parameters.c +3 -1
index 7a60048..6b44ef0 100644
@@ -75,7 +75,9 @@
 #include <cmdline_parse.h>
 #include <cmdline_parse_etheraddr.h>
 #endif
-
+#ifdef RTE_LIBRTE_BOND
+#include <rte_bond.h>
+#endif
 #include "testpmd.h"
 
 static void
app/test-pmd/testpmd.c +32 -5
index bc38305..823c973 100644
@@ -300,7 +300,7 @@ struct rte_fdir_conf fdir_conf = {
 	.drop_queue = 127,
 };
 
-static volatile int test_done = 1; /* stop packet forwarding when set to 1. */
+volatile int test_done = 1; /* stop packet forwarding when set to 1. */
 
 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
@@ -625,6 +625,32 @@ init_config(void)
 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
 }
 
+
+void
+reconfig(portid_t new_port_id)
+{
+	struct rte_port *port;
+
+	/* Reconfiguration of Ethernet ports. */
+	ports = rte_realloc(ports,
+			    sizeof(struct rte_port) * nb_ports,
+			    CACHE_LINE_SIZE);
+	if (ports == NULL) {
+		rte_exit(EXIT_FAILURE, "rte_realloc(%d struct rte_port) failed\n",
+				nb_ports);
+	}
+
+	port = &ports[new_port_id];
+	rte_eth_dev_info_get(new_port_id, &port->dev_info);
+
+	/* set flag to initialize port/queue */
+	port->need_reconfig = 1;
+	port->need_reconfig_queues = 1;
+
+	init_port_config();
+}
+
+
 int
 init_fwd_streams(void)
 {
@@ -1232,7 +1258,7 @@ start_port(portid_t pid)
 	portid_t pi;
 	queueid_t qi;
 	struct rte_port *port;
-	uint8_t *mac_addr;
+	struct ether_addr mac_addr;
 
 	if (test_done == 0) {
 		printf("Please stop forwarding first\n");
@@ -1360,10 +1386,11 @@ start_port(portid_t pid)
 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
 			printf("Port %d can not be set into started\n", pi);
 
-		mac_addr = port->eth_addr.addr_bytes;
+		rte_eth_macaddr_get(pi, &mac_addr);
 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
-		       mac_addr[0], mac_addr[1], mac_addr[2],
-		       mac_addr[3], mac_addr[4], mac_addr[5]);
+				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
+				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
+				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
 
 		/* at least one port started, need checking link status */
 		need_check_link_status = 1;
app/test-pmd/testpmd.h +2 -0
index 0cf5a92..1f54787 100644
@@ -279,6 +279,7 @@ extern uint16_t port_topology; /**< set by "--port-topology" parameter */
 extern uint8_t no_flush_rx; /**<set by "--no-flush-rx" parameter */
 extern uint8_t  mp_anon; /**< set by "--mp-anon" parameter */
 extern uint8_t no_link_check; /**<set by "--disable-link-check" parameter */
+extern volatile int test_done; /* stop packet forwarding when set to 1. */
 
 #ifdef RTE_NIC_BYPASS
 extern uint32_t bypass_timeout; /**< Store the NIC bypass watchdog timeout */
@@ -452,6 +453,7 @@ void fwd_config_display(void);
 void rxtx_config_display(void);
 void fwd_config_setup(void);
 void set_def_fwd_config(void);
+void reconfig(portid_t new_port_id);
 int init_fwd_streams(void);
 
 
Signature · 1 line
1.8.5.3
#34 lore raw

PATCH v2 4/4 Add Link Bonding Library to Doxygen

In reply to a message not in the archive

From: Declan Doherty <[email protected]>

---
 doc/doxy-api-index.md | 1 +
 doc/doxy-api.conf     | 1 +
 2 files changed, 2 insertions(+)
doc/doxy-api-index.md +1 -0
index 2825c08..2206c68 100644
@@ -36,6 +36,7 @@ API {#index}
 There are many libraries, so their headers may be grouped by topics:
 
 - **device**:
+  [bond]               (@ref rte_bond.h),
   [ethdev]             (@ref rte_ethdev.h),
   [devargs]            (@ref rte_devargs.h),
   [KNI]                (@ref rte_kni.h),
doc/doxy-api.conf +1 -0
index 642f77a..a9c5b30 100644
@@ -30,6 +30,7 @@
 
 PROJECT_NAME            = DPDK
 INPUT                   = doc/doxy-api-index.md \
+                          lib/librte_bond \
                           lib/librte_eal/common/include \
                           lib/librte_ether \
                           lib/librte_hash \
Signature · 1 line
1.8.5.3

A message that is not in the archive (sent off-list or not yet received): cover.1401891670.git.declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#36 lore raw

Sorry for the double submission of the first 3 parts of this patch set. It was meant to be a test directed to my own email account. Regards
Declan

Quoted 68 lines

-----Original Message-----
From: Doherty, Declan
Sent: Wednesday, June 4, 2014 4:19 PM
To: [email protected]; [email protected]
Cc: Doherty, Declan
Subject: [PATCH v2 0/4] Link Bonding Library

From: Declan Doherty <[email protected]>

v2 patch additions,
fix for tx burst broadcast, incrementing the reference count on each mbuf by the number of slaves - 1
add/remove slave behavior chnange to fix primary slave port assignment patchcheck code fixes

Initial release of Link Bonding Library (lib/librte_bond) with support for bonding modes :
0 - Round Robin
1 - Active Backup
2 - Balance l2 / l23 / l34
3 - Broadcast

patches split:
1 - library + makefile changes
2 - Unit test suite, including code to generate packet bursts for
testing rx and tx functionality of bonded device and a virtual/stubbed out ethdev for use as slave ethdev in testing
3 - Link bonding integration into testpmd, including :
- Includes the ability to create new bonded devices.
- Add /remove bonding slave devices.
- Interogate bonded device stats/configuration
- Change bonding modes and select balance transmit polices
4 - Add Link Bonding Library to Doxygen

 app/test-pmd/cmdline.c            |  570 ++++++
 app/test-pmd/config.c             |    4 +-
 app/test-pmd/parameters.c         |    4 +-
 app/test-pmd/testpmd.c            |   37 +-
 app/test-pmd/testpmd.h            |    2 +
 app/test/Makefile                 |    3 +
 app/test/commands.c               |    3 +
 app/test/packet_burst_generator.c |  289 +++
 app/test/packet_burst_generator.h |   78 +
 app/test/test.h                   |    1 +
 app/test/test_link_bonding.c      | 3943
+++++++++++++++++++++++++++++++++++++
 app/test/virtual_pmd.c            |  574 ++++++
 app/test/virtual_pmd.h            |   74 +
 config/common_bsdapp              |    5 +
 config/common_linuxapp            |    5 +
 doc/doxy-api-index.md             |    1 +
 doc/doxy-api.conf                 |    1 +
 lib/Makefile                      |    1 +
 lib/librte_bond/Makefile          |   28 +
 lib/librte_bond/rte_bond.c        | 1682 ++++++++++++++++
 lib/librte_bond/rte_bond.h        |  228 +++
 mk/rte.app.mk                     |    5 +
 22 files changed, 7531 insertions(+), 7 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_bond/Makefile
 create mode 100644 lib/librte_bond/rte_bond.c
 create mode 100644 lib/librte_bond/rte_bond.h
Quoted 2 lines

--
1.8.5.3

--------------------------------------------------------------
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.

#37 lore raw
In reply to a message not in the archive
Quoted 67 lines

-----Original Message-----
From: dev [mailto:[email protected]] On Behalf Of [email protected]
Sent: Wednesday, June 04, 2014 4:18 PM
To: [email protected]; [email protected]
Subject: [dpdk-dev] [PATCH v2 0/4] Link Bonding Library

From: Declan Doherty <[email protected]>

v2 patch additions,
fix for tx burst broadcast, incrementing the reference count on each mbuf by the number of slaves - 1 add/remove slave behavior chnange to fix primary slave port assignment patchcheck code fixes

Initial release of Link Bonding Library (lib/librte_bond) with support for bonding modes :
0 - Round Robin
1 - Active Backup
2 - Balance l2 / l23 / l34
3 - Broadcast

patches split:
1 - library + makefile changes
2 - Unit test suite, including code to generate packet bursts for
testing rx and tx functionality of bonded device and a virtual/stubbed out ethdev for use as slave ethdev in testing
3 - Link bonding integration into testpmd, including :
- Includes the ability to create new bonded devices.
- Add /remove bonding slave devices.
- Interogate bonded device stats/configuration
- Change bonding modes and select balance transmit polices
4 - Add Link Bonding Library to Doxygen

 app/test-pmd/cmdline.c            |  570 ++++++
 app/test-pmd/config.c             |    4 +-
 app/test-pmd/parameters.c         |    4 +-
 app/test-pmd/testpmd.c            |   37 +-
 app/test-pmd/testpmd.h            |    2 +
 app/test/Makefile                 |    3 +
 app/test/commands.c               |    3 +
 app/test/packet_burst_generator.c |  289 +++
 app/test/packet_burst_generator.h |   78 +
 app/test/test.h                   |    1 +
 app/test/test_link_bonding.c      | 3943
+++++++++++++++++++++++++++++++++++++
 app/test/virtual_pmd.c            |  574 ++++++
 app/test/virtual_pmd.h            |   74 +
 config/common_bsdapp              |    5 +
 config/common_linuxapp            |    5 +
 doc/doxy-api-index.md             |    1 +
 doc/doxy-api.conf                 |    1 +
 lib/Makefile                      |    1 +
 lib/librte_bond/Makefile          |   28 +
 lib/librte_bond/rte_bond.c        | 1682 ++++++++++++++++
 lib/librte_bond/rte_bond.h        |  228 +++
 mk/rte.app.mk                     |    5 +
 22 files changed, 7531 insertions(+), 7 deletions(-)  create mode 100644

app/test/packet_burst_generator.c create mode 100644 app/test/packet_burst_generator.h create mode 100644 app/test/test_link_bonding.c create mode 100644 app/test/virtual_pmd.c create mode 100644 app/test/virtual_pmd.h create mode 100644 lib/librte_bond/Makefile create mode 100644 lib/librte_bond/rte_bond.c create mode 100644 lib/librte_bond/rte_bond.h

--
1.8.5.3

#38 lore raw
In reply to a message not in the archive
Quoted 49 lines · On Wed, Jun 04, 2014 at 04:18:01PM +0100…

From: Declan Doherty <[email protected]>

v2 patch additions,
fix for tx burst broadcast, incrementing the reference count on each mbuf by the number of slaves - 1 add/remove slave behavior chnange to fix primary slave port assignment
patchcheck code fixes

Initial release of Link Bonding Library (lib/librte_bond) with support for bonding modes :
0 - Round Robin
1 - Active Backup
2 - Balance l2 / l23 / l34
3 - Broadcast

patches split:
1 - library + makefile changes
2 - Unit test suite, including code to generate packet bursts for
testing rx and tx functionality of bonded device and a virtual/stubbed out ethdev for use as slave ethdev in testing
3 - Link bonding integration into testpmd, including :
- Includes the ability to create new bonded devices.
- Add /remove bonding slave devices.
- Interogate bonded device stats/configuration
- Change bonding modes and select balance transmit polices
4 - Add Link Bonding Library to Doxygen

 app/test-pmd/cmdline.c            |  570 ++++++
 app/test-pmd/config.c             |    4 +-
 app/test-pmd/parameters.c         |    4 +-
 app/test-pmd/testpmd.c            |   37 +-
 app/test-pmd/testpmd.h            |    2 +
 app/test/Makefile                 |    3 +
 app/test/commands.c               |    3 +
 app/test/packet_burst_generator.c |  289 +++
 app/test/packet_burst_generator.h |   78 +
 app/test/test.h                   |    1 +
 app/test/test_link_bonding.c      | 3943 +++++++++++++++++++++++++++++++++++++
 app/test/virtual_pmd.c            |  574 ++++++
 app/test/virtual_pmd.h            |   74 +
 config/common_bsdapp              |    5 +
 config/common_linuxapp            |    5 +
 doc/doxy-api-index.md             |    1 +
 doc/doxy-api.conf                 |    1 +
 lib/Makefile                      |    1 +
 lib/librte_bond/Makefile          |   28 +
 lib/librte_bond/rte_bond.c        | 1682 ++++++++++++++++
 lib/librte_bond/rte_bond.h        |  228 +++
 mk/rte.app.mk                     |    5 +
 22 files changed, 7531 insertions(+), 7 deletions(-)
Quoted 13 lines
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_bond/Makefile
 create mode 100644 lib/librte_bond/rte_bond.c
 create mode 100644 lib/librte_bond/rte_bond.h
Signature · 1 line
1.8.5.3

This doesn't address any of the comments I made previously. Neil

A message that is not in the archive (sent off-list or not yet received): 20140605110340.GB20841-B26myB8xz7F8NnZeBjwnZQMhkBWG/[email protected]

#40 lore raw
Quoted 86 lines

-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Thursday, May 29, 2014 12:34 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH 0/4] Link Bonding Library

Quoted 8 lines · Declan

-----Original Message-----

Quoted 7 lines

From: Neil Horman [mailto:[email protected]]
Sent: Wednesday, May 28, 2014 6:49 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH 0/4] Link Bonding Library

On Wed, May 28, 2014 at 04:32:00PM +0100, [email protected]

Quoted 11 lines · wrote:
Quoted 11 lines
Quoted 9 lines

From: Declan Doherty <[email protected]>

Initial release of Link Bonding Library (lib/librte_bond) with support for bonding modes :
0 - Round Robin
1 - Active Backup
2 - Balance l2 / l23 / l34
3 - Broadcast

Why make this a separate library? That requires exposure of yet another

API to applications. Instead, why > not write a PMD that can enslave other PMD's and treat them all as a single interface? That way this all > > works with the existing API.

Quoted 6 lines
Quoted 2 lines

Neil

Hi Neil,
the link bonding device is essentially a software PMD, and as such supports

all the standard PMD APIs, the only new APIs which the link bonding library introduces are for the control operations of the bonded device which are currently unsupported by the standard PMD API. Operations such as creating, adding/removing slaves, and configuring the modes of operation of the device have no analogous APIs in the current PMD API and required new ones to be created .

Thats really only true in spirit, in the sense that this library transmits and receives frames like a PMD does. In practice it doesn't work and isn't architected the same way. You don't register the driver using the same method as the other PMDs, which means that using --vdev on the command line wont work for this type of device. It also implies that applications have to be made specifically aware of the fact that they are using a bonded interface (i.e. they need to call the bonding setup routines to create the bond). I would recommend:

1) Register the pmd using the PMD_DRIVER_REGISTER macro, like other PMD's
2) Use the kvargs library to support configuration via the --vdev command line option, so bonds can be created administratively, rather than just programatically
3) Separate the command api from the PMD functionality into separate libraries (use control mbufs to communicate configuration changes to the pmd). This will allow users to dynamically load the pmd functionality (without compile or run time linking requirements), and then optionally use the programatic interface (or not if they want to save memory)

Regards
Neil
-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Thursday, June 5, 2014 12:04 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v2 0/4] Link Bonding Library

Quoted 9 lines · On Wed, Jun 04, 2014 at 04:18:01PM +0100…

From: Declan Doherty <[email protected]>

v2 patch additions,
fix for tx burst broadcast, incrementing the reference count on each mbuf by the number of slaves - 1 add/remove slave behavior chnange to fix primary slave port assignment patchcheck code fixes

Quoted 2 lines

This doesn't address any of the comments I made previously. Neil

Hi Neil,

sorry for not replying regarding this earlier, in relation to your recommendations 1 and 2, I'm currently working on the implementation of both and should have an additional patch within the next couple of days to add this functionality.

Regarding your third recommendation, I have no problem splitting the library into separate API and PMD libraries although this does seem to break convention with the other non hw based pmd's, such as pmd_pcap, so would prefer not to go down that route. Also, I don't see the ability to dynamically load the pmd as justification for the use of a control mbufs interface, this would require that either additional queues be created to handle control messages, or that the data TX queues have the ability to identify and process control mbufs, and either of these options will have a performance hit, for the core handling the separate control messages or directly to the tx burst performance. I am not currently aware of any functional requirements or use cases for bonded devices to be used over multiple processes which is the only reason I can see for using an interface based on control mbufs, and by providing a --vdev configuration options the user can still write their applications without any knowledge of the additional link bonding programmatic interface. If in the future a use case does emerge which requires multi-process control of bonded devices, I think it would make sense then to add an additional library to provide this functionality.

Regards
Declan
--------------------------------------------------------------
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.

A message that is not in the archive (sent off-list or not yet received): 345C63BAECC1AD42A2EC8C63AFFC3ADC13D37331-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org

#42 lore raw
Quoted 90 lines · Declan
Quoted 86 lines

-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Thursday, May 29, 2014 12:34 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH 0/4] Link Bonding Library

Quoted 8 lines · Declan

-----Original Message-----

Quoted 7 lines

From: Neil Horman [mailto:[email protected]]
Sent: Wednesday, May 28, 2014 6:49 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH 0/4] Link Bonding Library

On Wed, May 28, 2014 at 04:32:00PM +0100, [email protected]

Quoted 11 lines · wrote:
Quoted 11 lines
Quoted 9 lines

From: Declan Doherty <[email protected]>

Initial release of Link Bonding Library (lib/librte_bond) with support for bonding modes :
0 - Round Robin
1 - Active Backup
2 - Balance l2 / l23 / l34
3 - Broadcast

Why make this a separate library? That requires exposure of yet another

API to applications. Instead, why > not write a PMD that can enslave other PMD's and treat them all as a single interface? That way this all > > works with the existing API.

Quoted 6 lines
Quoted 2 lines

Neil

Hi Neil,
the link bonding device is essentially a software PMD, and as such supports

all the standard PMD APIs, the only new APIs which the link bonding library introduces are for the control operations of the bonded device which are currently unsupported by the standard PMD API. Operations such as creating, adding/removing slaves, and configuring the modes of operation of the device have no analogous APIs in the current PMD API and required new ones to be created .

Thats really only true in spirit, in the sense that this library transmits and receives frames like a PMD does. In practice it doesn't work and isn't architected the same way. You don't register the driver using the same method as the other PMDs, which means that using --vdev on the command line wont work for this type of device. It also implies that applications have to be made specifically aware of the fact that they are using a bonded interface (i.e. they need to call the bonding setup routines to create the bond). I would recommend:

1) Register the pmd using the PMD_DRIVER_REGISTER macro, like other PMD's
2) Use the kvargs library to support configuration via the --vdev command line option, so bonds can be created administratively, rather than just programatically
3) Separate the command api from the PMD functionality into separate libraries (use control mbufs to communicate configuration changes to the pmd). This will allow users to dynamically load the pmd functionality (without compile or run time linking requirements), and then optionally use the programatic interface (or not if they want to save memory)

Regards
Neil
-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Thursday, June 5, 2014 12:04 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v2 0/4] Link Bonding Library

Quoted 9 lines · On Wed, Jun 04, 2014 at 04:18:01PM +0100…

From: Declan Doherty <[email protected]>

v2 patch additions,
fix for tx burst broadcast, incrementing the reference count on each mbuf by the number of slaves - 1 add/remove slave behavior chnange to fix primary slave port assignment patchcheck code fixes

Quoted 2 lines

This doesn't address any of the comments I made previously. Neil

Quoted 5 lines

Hi Neil,

sorry for not replying regarding this earlier, in relation to your recommendations 1 and 2, I'm currently working on the implementation of both and should have an additional patch within the next couple of days to add this functionality.

Regarding your third recommendation, I have no problem splitting the library into separate API and PMD libraries although this does seem to break convention with the other non hw based pmd's, such as pmd_pcap,

I'm not at all sure what you mean here. pmd_pcap registers a driver with the registration mechanism, allowing for the use of the --vdev option on the command line, same as all the other virtual drivers. The physical drivers do the same thing using the --whitelist and --blacklist options. How is the bonding driver following convention with pmd_pcap?

Quoted 1 line

so would prefer not to go down that route. Also, I don't see the ability to dynamically load the pmd as justification for the use of a control mbufs interface, this would require that either additional queues be created to handle control messages, or that the data TX queues have the ability to identify and process control mbufs, and either of these options will have a performance hit,

Well, you're correct in that the driver would have to identify control messages, but I don't see how thats a performance hit at all. If you create a control channel queue, then all you have to introduce to the datapath is a single branch to see which queue is transmitting, and your done. If control mbufs are just that hurtful to performance, it seems thats an area that really needs improvement then.

Another alternative is to add a control packet method to the rte_eth_dev structure allowing you to pass control mbufs directly to a pmd out of line with the datapath. That could avoid any additional branches in the datapath, and still allow you to separate user api from driver implementation.

Quoted 1 line

for the core handling the separate control messages or directly to the tx burst performance. I am not currently aware of any functional requirements or use cases for bonded devices to be used over multiple processes which is the only reason I can see for using an interface based on control mbufs,

The reason is administrative. Its got nothing to do with how many processes want to use an interface, it has to do with an interface knowing if its using the bonding driver or not (it shouldn't ever have to, but with your patch set, its required to use the bonding api to create the interface and add slaves.

Quoted 1 line

and by providing a --vdev configuration options the user can still write their applications without any knowledge of the additional link bonding programmatic interface. If in the future a use case does emerge which requires multi-process control of bonded devices, I think it would make sense then to add an additional library to provide this functionality.

How exactly does that happen? At what point does the bonding library in its current form register a driver with rte_ethdev without the application first calling some function in the bonding library to do so. Because until that happens, --vdev is non functional for this pmd.

FWIW, the concern for me here is one of packaging. I don't want users to have to pull in a library that they don't absolutely need. the way you have this put together right now, they need the entire bonding library even if they just want a statically configured bond interface

Neil

Quoted 14 lines

Regards
Declan
--------------------------------------------------------------
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.

A message that is not in the archive (sent off-list or not yet received): 20140606145426.GA2543-B26myB8xz7F8NnZeBjwnZQMhkBWG/[email protected]

#44 lore raw
Quoted 155 lines

-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Friday, June 6, 2014 3:54 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v2 0/4] Link Bonding Library

Quoted 86 lines · Declan
Quoted 86 lines

-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Thursday, May 29, 2014 12:34 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH 0/4] Link Bonding Library

Quoted 8 lines · Declan

-----Original Message-----

Quoted 7 lines

From: Neil Horman [mailto:[email protected]]
Sent: Wednesday, May 28, 2014 6:49 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH 0/4] Link Bonding Library

On Wed, May 28, 2014 at 04:32:00PM +0100, [email protected]

Quoted 11 lines · wrote:
Quoted 11 lines
Quoted 9 lines

From: Declan Doherty <[email protected]>

Initial release of Link Bonding Library (lib/librte_bond) with support for bonding modes :
0 - Round Robin
1 - Active Backup
2 - Balance l2 / l23 / l34
3 - Broadcast

Why make this a separate library? That requires exposure of yet another

API to applications. Instead, why > not write a PMD that can enslave other PMD's and treat them all as a single interface? That way this all > > works with the existing API.

Quoted 6 lines
Quoted 2 lines

Neil

Hi Neil,
the link bonding device is essentially a software PMD, and as such supports

all the standard PMD APIs, the only new APIs which the link bonding library introduces are for the control operations of the bonded device which are currently unsupported by the standard PMD API. Operations such as creating, adding/removing slaves, and configuring the modes of operation of the device have no analogous APIs in the current PMD API and required new ones to be created .

Thats really only true in spirit, in the sense that this library transmits and receives frames like a PMD does. In practice it doesn't work and isn't architected the same way. You don't register the driver using the same method as the other PMDs, which means that using --vdev on the command line wont work for this type of device. It also implies that applications have to be made specifically aware of the fact that they are using a bonded interface (i.e. they need to call the bonding setup routines to create the bond). I would recommend:

1) Register the pmd using the PMD_DRIVER_REGISTER macro, like other PMD's
2) Use the kvargs library to support configuration via the --vdev command line option, so bonds can be created administratively, rather than just programatically
3) Separate the command api from the PMD functionality into separate libraries (use control mbufs to communicate configuration changes to the pmd). This will allow users to dynamically load the pmd functionality (without compile or run time linking requirements), and then optionally use the programatic interface (or not if they want to save memory)

Regards
Neil
-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Thursday, June 5, 2014 12:04 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v2 0/4] Link Bonding Library

Quoted 9 lines · On Wed, Jun 04, 2014 at 04:18:01PM +0100…

From: Declan Doherty <[email protected]>

v2 patch additions,
fix for tx burst broadcast, incrementing the reference count on each mbuf by the number of slaves - 1 add/remove slave behavior chnange to fix primary slave port assignment patchcheck code fixes

Quoted 7 lines
Quoted 2 lines

This doesn't address any of the comments I made previously. Neil

Hi Neil,

sorry for not replying regarding this earlier, in relation to your

recommendations 1 and 2, I'm currently working on the implementation of both and should have an additional patch within the next couple of days to add this functionality.

Quoted 2 lines

Regarding your third recommendation, I have no problem splitting the library

into separate API and PMD libraries although this does seem to break convention with the other non hw based pmd's, such as pmd_pcap,
I'm not at all sure what you mean here. pmd_pcap registers a driver with the registration mechanism, allowing for the use of the --vdev option on the command line, same as all the other virtual drivers. The physical drivers do the same thing using the --whitelist and --blacklist options. How is the bonding driver following convention with pmd_pcap?

Quoted 1 line

so would prefer not to go down that route. Also, I don't see the ability to

dynamically load the pmd as justification for the use of a control mbufs interface, this would require that either additional queues be created to handle control messages, or that the data TX queues have the ability to identify and process control mbufs, and either of these options will have a performance hit,

Well, you're correct in that the driver would have to identify control messages, but I don't see how thats a performance hit at all. If you create a control channel queue, then all you have to introduce to the datapath is a single branch to see which queue is transmitting, and your done. If control mbufs are just that hurtful to performance, it seems thats an area that really needs improvement then.

Another alternative is to add a control packet method to the rte_eth_dev structure allowing you to pass control mbufs directly to a pmd out of line with the datapath. That could avoid any additional branches in the datapath, and still allow you to separate user api from driver implementation.

Quoted 1 line

for the core handling the separate control messages or directly to the tx burst

performance. I am not currently aware of any functional requirements or use cases for bonded devices to be used over multiple processes which is the only reason I can see for using an interface based on control mbufs,

The reason is administrative. Its got nothing to do with how many processes want to use an interface, it has to do with an interface knowing if its using the bonding driver or not (it shouldn't ever have to, but with your patch set, its required to use the bonding api to create the interface and add slaves.

Quoted 1 line

and by providing a --vdev configuration options the user can still write their

applications without any knowledge of the additional link bonding programmatic interface. If in the future a use case does emerge which requires multi-process control of bonded devices, I think it would make sense then to add an additional library to provide this functionality.

How exactly does that happen? At what point does the bonding library in its current form register a driver with rte_ethdev without the application first calling some function in the bonding library to do so. Because until that happens, --vdev is non functional for this pmd.

Quoted 12 lines

FWIW, the concern for me here is one of packaging. I don't want users to have to pull in a library that they don't absolutely need. the way you have this put together right now, they need the entire bonding library even if they just want a statically configured bond interface

Neil

Quoted 4 lines

Regards
Declan
--------------------------------------------------------------

Hi Neil,
I waited to reply to this until I had v3 of the patch ready to submit. I think you mistook the intent of my last
response, but anyway I think v3 of the patch addresses the majority of your concerns regarding the bonded device. Which can now be initialized using the --vdev options and supports both virtual and physical devices to be specified as slaves and no knowledge of the bonding API is required by the user application if the bonding ports are configure at runtime.

Regards

A message that is not in the archive (sent off-list or not yet received): 345C63BAECC1AD42A2EC8C63AFFC3ADC13D38DBF-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org

#46 lore raw
Quoted 168 lines · Declan
Quoted 155 lines

-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Friday, June 6, 2014 3:54 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v2 0/4] Link Bonding Library

Quoted 86 lines · Declan
Quoted 86 lines

-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Thursday, May 29, 2014 12:34 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH 0/4] Link Bonding Library

Quoted 8 lines · Declan

-----Original Message-----

Quoted 7 lines

From: Neil Horman [mailto:[email protected]]
Sent: Wednesday, May 28, 2014 6:49 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH 0/4] Link Bonding Library

On Wed, May 28, 2014 at 04:32:00PM +0100, [email protected]

Quoted 11 lines · wrote:
Quoted 11 lines
Quoted 9 lines

From: Declan Doherty <[email protected]>

Initial release of Link Bonding Library (lib/librte_bond) with support for bonding modes :
0 - Round Robin
1 - Active Backup
2 - Balance l2 / l23 / l34
3 - Broadcast

Why make this a separate library? That requires exposure of yet another

API to applications. Instead, why > not write a PMD that can enslave other PMD's and treat them all as a single interface? That way this all > > works with the existing API.

Quoted 6 lines
Quoted 2 lines

Neil

Hi Neil,
the link bonding device is essentially a software PMD, and as such supports

all the standard PMD APIs, the only new APIs which the link bonding library introduces are for the control operations of the bonded device which are currently unsupported by the standard PMD API. Operations such as creating, adding/removing slaves, and configuring the modes of operation of the device have no analogous APIs in the current PMD API and required new ones to be created .

Thats really only true in spirit, in the sense that this library transmits and receives frames like a PMD does. In practice it doesn't work and isn't architected the same way. You don't register the driver using the same method as the other PMDs, which means that using --vdev on the command line wont work for this type of device. It also implies that applications have to be made specifically aware of the fact that they are using a bonded interface (i.e. they need to call the bonding setup routines to create the bond). I would recommend:

1) Register the pmd using the PMD_DRIVER_REGISTER macro, like other PMD's
2) Use the kvargs library to support configuration via the --vdev command line option, so bonds can be created administratively, rather than just programatically
3) Separate the command api from the PMD functionality into separate libraries (use control mbufs to communicate configuration changes to the pmd). This will allow users to dynamically load the pmd functionality (without compile or run time linking requirements), and then optionally use the programatic interface (or not if they want to save memory)

Regards
Neil
-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Thursday, June 5, 2014 12:04 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v2 0/4] Link Bonding Library

Quoted 9 lines · On Wed, Jun 04, 2014 at 04:18:01PM +0100…

From: Declan Doherty <[email protected]>

v2 patch additions,
fix for tx burst broadcast, incrementing the reference count on each mbuf by the number of slaves - 1 add/remove slave behavior chnange to fix primary slave port assignment patchcheck code fixes

Quoted 7 lines
Quoted 2 lines

This doesn't address any of the comments I made previously. Neil

Hi Neil,

sorry for not replying regarding this earlier, in relation to your

recommendations 1 and 2, I'm currently working on the implementation of both and should have an additional patch within the next couple of days to add this functionality.

Quoted 2 lines

Regarding your third recommendation, I have no problem splitting the library

into separate API and PMD libraries although this does seem to break convention with the other non hw based pmd's, such as pmd_pcap,
I'm not at all sure what you mean here. pmd_pcap registers a driver with the registration mechanism, allowing for the use of the --vdev option on the command line, same as all the other virtual drivers. The physical drivers do the same thing using the --whitelist and --blacklist options. How is the bonding driver following convention with pmd_pcap?

Quoted 1 line

so would prefer not to go down that route. Also, I don't see the ability to

dynamically load the pmd as justification for the use of a control mbufs interface, this would require that either additional queues be created to handle control messages, or that the data TX queues have the ability to identify and process control mbufs, and either of these options will have a performance hit,

Well, you're correct in that the driver would have to identify control messages, but I don't see how thats a performance hit at all. If you create a control channel queue, then all you have to introduce to the datapath is a single branch to see which queue is transmitting, and your done. If control mbufs are just that hurtful to performance, it seems thats an area that really needs improvement then.

Another alternative is to add a control packet method to the rte_eth_dev structure allowing you to pass control mbufs directly to a pmd out of line with the datapath. That could avoid any additional branches in the datapath, and still allow you to separate user api from driver implementation.

Quoted 1 line

for the core handling the separate control messages or directly to the tx burst

performance. I am not currently aware of any functional requirements or use cases for bonded devices to be used over multiple processes which is the only reason I can see for using an interface based on control mbufs,

The reason is administrative. Its got nothing to do with how many processes want to use an interface, it has to do with an interface knowing if its using the bonding driver or not (it shouldn't ever have to, but with your patch set, its required to use the bonding api to create the interface and add slaves.

Quoted 1 line

and by providing a --vdev configuration options the user can still write their

applications without any knowledge of the additional link bonding programmatic interface. If in the future a use case does emerge which requires multi-process control of bonded devices, I think it would make sense then to add an additional library to provide this functionality.

How exactly does that happen? At what point does the bonding library in its current form register a driver with rte_ethdev without the application first calling some function in the bonding library to do so. Because until that happens, --vdev is non functional for this pmd.

Quoted 12 lines

FWIW, the concern for me here is one of packaging. I don't want users to have to pull in a library that they don't absolutely need. the way you have this put together right now, they need the entire bonding library even if they just want a statically configured bond interface

Neil

Quoted 4 lines

Regards
Declan
--------------------------------------------------------------

Quoted 7 lines

Hi Neil,
I waited to reply to this until I had v3 of the patch ready to submit. I think you mistook the intent of my last
response, but anyway I think v3 of the patch addresses the majority of your concerns regarding the bonded device. Which can now be initialized using the --vdev options and supports both virtual and physical devices to be specified as slaves and no knowledge of the bonding API is required by the user application if the bonding ports are configure at runtime.

Sounds great, I look forward to seeing it.

Thanks!
Neil

Quoted 2 lines

Regards

Tested-by
#47 lore raw
In reply to a message not in the archive

This patch is updated version for Link Bonding library. It's compose of 5 files including cover letter, tested by Intel. Please see environment information:
Fedora 20 x86_64, Linux Kernel 3.11.10-301, GCC 4.8.2 Intel Xeon CPU E5-2680 v2 @ 2.80GHz NIC: Intel Niantic 82599
Total cases Passed Failed
18 18 0

Please see test Case list as the following:
Case1: Basic bonding--Create bonded devices and slaves
Case2: Basic bonding--MAC Address Test
Case3: Basic bonding--Device Promiscuous Mode Test
Case4: Mode 0(Round Robin) TX/RX test
Case5: Mode 0(Round Robin) Bring one slave link down
Case6: Mode 0(Round Robin) Bring all slave links down
Case7: Mode 1(Active Backup) TX/RX Test
Case8: Mode 1(Active Backup) Change active slave, RX/TX test
Case9: Mode 1(Active Backup) Link up/down active eth dev
Case10: Mode 1(Active Backup) Bring all slave links down
Case11: Mode 2(Balance XOR) TX Load Balance test
Case12: Mode 2(Balance XOR) TX Load Balance Link down
Case13: Mode 2(Balance XOR) Bring all slave links down
Case14: Mode 2(Balance XOR) Layer 3+4 forwarding
Case15: Mode 2(Balance XOR) RX test
Case16: Mode 3(Broadcast) TX/RX Test
Case17: Mode 3(Broadcast) Bring one slave link down
Case18: Mode 3(Broadcast) Bring all slave links down

#48 lore raw
In reply to a message not in the archive

Hi Declan,

Do you think you can send another version of your serie soon? Some comments need to be addressed.

2 formatting comments:
- I saw some strange alignments of comments
- you should send your patches as children of the cover letter

Thanks

Signature · 1 line
Thomas
#49 lore raw
Quoted 12 lines

-----Original Message-----
From: Thomas Monjalon [mailto:[email protected]]
Sent: Wednesday, June 11, 2014 5:33 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v2 0/4] Link Bonding Library

Hi Declan,

Do you think you can send another version of your serie soon? Some comments need to be addressed.

Quoted 7 lines

2 formatting comments:
- I saw some strange alignments of comments
- you should send your patches as children of the cover letter

Thanks
--
Thomas

Hi Thomas,
I've just submitted v3 of the patch, which should address the majority of the comments and any formatting issues.

Regards
Declan

A message that is not in the archive (sent off-list or not yet received): 345C63BAECC1AD42A2EC8C63AFFC3ADC13D38CDE-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org

#51 lore raw

2014-06-13 14:08, Doherty, Declan:

Quoted 10 lines

From: Thomas Monjalon [mailto:[email protected]]

Quoted 6 lines

Do you think you can send another version of your serie soon? Some comments need to be addressed.

2 formatting comments:
- I saw some strange alignments of comments
- you should send your patches as children of the cover letter

Hi Thomas,
I've just submitted v3 of the patch, which should address the majority of the comments and any formatting issues.

Thanks. We are now waiting for Neil's acknowledgement.

On the formatting side, please check these errors:
ERROR: "foo* bar" should be "foo *bar"
ERROR: space prohibited before that close parenthesis ')'

About git-send-email, I'd prefer you conform to this scheme for man page:
"
So for example when --thread and --no-chain-reply-to are specified, the second and subsequent patches will be replies to the first one like in the illustration below where [PATCH v2 0/3] is in reply to [PATCH 0/2]:

[PATCH 0/2] Here is what I did...
[PATCH 1/2] Clean up and tests
[PATCH 2/2] Implementation
[PATCH v2 0/3] Here is a reroll
[PATCH v2 1/3] Clean up
[PATCH v2 2/3] New tests
[PATCH v2 3/3] Implementation
"

Thanks

Signature · 1 line
Thomas
#52 lore raw

v3 cover Link Bonding PMD Library

In reply to a message not in the archive

This patch contains the initial release of the Link Bonding PMD Library

Supporting bonding modes:
0 - Round Robin
1 - Active Backup
2 - Balance (Supporting 3 transmission polices)

	layer 2, layer 2+3, layer 3+4

3 - Broadcast

Version 3 of this patch set add the following functionality changes
- Link bonding command line option parsing / initialization support
- Unique name identifier to rte_eth_dev_data struct to identify virtual ethdev's which are to be added to bondded device from command line.
- Updates to EAL to support initialization of link bonding devices

Patch Set Description:
0001 - librte_pmd_bond + makefile changes
0002 - librte_eal / librte_ether changes to support bonding device intialization 0003 - link bonding unti test suite
0004 - testpmd link bonding support changes
0005 - doxygen additions

 app/test-pmd/cmdline.c                      |  571 ++++
 app/test-pmd/config.c                       |    4 +-
 app/test-pmd/parameters.c                   |    3 +
 app/test-pmd/testpmd.c                      |   37 +-
 app/test-pmd/testpmd.h                      |    2 +
 app/test/Makefile                           |    4 +-
 app/test/commands.c                         |    7 +
 app/test/packet_burst_generator.c           |  288 ++
 app/test/packet_burst_generator.h           |   78 +
 app/test/test.h                             |    1 +
 app/test/test_link_bonding.c                | 3958 +++++++++++++++++++++++++++
 app/test/virtual_pmd.c                      |  574 ++++
 app/test/virtual_pmd.h                      |   74 +
 config/common_bsdapp                        |    5 +
 config/common_linuxapp                      |    5 +
 doc/doxy-api-index.md                       |    1 +
 doc/doxy-api.conf                           |    1 +
 lib/Makefile                                |    1 +
 lib/librte_eal/common/eal_common_dev.c      |   66 +-
 lib/librte_eal/common/eal_common_pci.c      |    6 +
 lib/librte_eal/common/include/eal_private.h |    7 +
 lib/librte_eal/common/include/rte_dev.h     |    1 +
 lib/librte_ether/rte_ethdev.c               |   34 +-
 lib/librte_ether/rte_ethdev.h               |    7 +-
 lib/librte_pmd_bond/Makefile                |   32 +
 lib/librte_pmd_bond/rte_eth_bond.c          | 2149 +++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond.h          |  255 ++
 lib/librte_pmd_pcap/rte_eth_pcap.c          |   22 +-
 lib/librte_pmd_ring/rte_eth_ring.c          |   32 +-
 lib/librte_pmd_ring/rte_eth_ring.h          |    3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |    2 +-
 mk/rte.app.mk                               |    5 +
 32 files changed, 8192 insertions(+), 43 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h
Signature · 1 line
1.8.5.3
#53 lore raw

PATCH v3 1/5 Link Bonding PMD Library

In reply to a message not in the archive

Link Bonding Library (lib/librte_pmd_bond) initial release with support for
Mode 0 - Round Robin
Mode 1 - Active Backup
Mode 2 - Balance -> Supports 3 transmit polices (layer 2, layer 2+3, layer 3+4) Mode 3 - Broadcast

---
 config/common_bsdapp               |    5 +
 config/common_linuxapp             |    5 +
 lib/Makefile                       |    1 +
 lib/librte_pmd_bond/Makefile       |   32 +
 lib/librte_pmd_bond/rte_eth_bond.c | 2149 ++++++++++++++++++++++++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond.h |  255 +++++
 mk/rte.app.mk                      |    5 +
 7 files changed, 2452 insertions(+)
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h
config/common_bsdapp +5 -0
index ec7b159..545d760 100644
@@ -187,6 +187,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=y
 
 #
+# Compile link bonding pmd library
+#
+CONFIG_RTE_LIBRTE_PMD_BOND=y
+
+#
 # Do prefetch of packet data within PMD driver receive function
 #
 CONFIG_RTE_PMD_PACKET_PREFETCH=y
config/common_linuxapp +5 -0
index 7c143eb..eb2e3d0 100644
@@ -216,6 +216,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=n
 
 #
+# Compile link bonding pmd library
+#
+CONFIG_RTE_LIBRTE_PMD_BOND=y
+
+#
 # Compile Xen PMD
 #
 CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
lib/Makefile +1 -0
index 8cdfa7d..66232a9 100644
@@ -47,6 +47,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += librte_pmd_pcap
 DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += librte_pmd_virtio
 DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += librte_pmd_vmxnet3
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += librte_pmd_xenvirt
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += librte_pmd_bond
 DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash
 DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm
 DIRS-$(CONFIG_RTE_LIBRTE_NET) += librte_net
lib/librte_pmd_bond/Makefile new file +32 -0
new file mode 100644
index 0000000..9275830
@@ -0,0 +1,32 @@
+# <COPYRIGHT_TAG>
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_bond.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond.c
+
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_eth_bond.h
+
+
+# this lib depends upon:
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_mbuf
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_malloc
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_kvargs
+
+include $(RTE_SDK)/mk/rte.lib.mk
lib/librte_pmd_bond/rte_eth_bond.c new file +2149 -0

2,149 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond.h new file +255 -0

255 lines not on this page · raw message

mk/rte.app.mk +5 -0
index 914c568..66de6a8 100644
@@ -181,8 +181,13 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMD_PCAP),y)
 LDLIBS += -lrte_pmd_pcap -lpcap
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_PMD_BOND),y)
+LDLIBS += -lrte_pmd_bond
 endif
 
+endif
+
+
 LDLIBS += $(EXECENV_LDLIBS)
 
 LDLIBS += --end-group
Signature · 1 line
1.8.5.3
#54 lore raw

PATCH v3 2/5 Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

In reply to a message not in the archive

Updating functionality in EAL to support adding link bonding devices via –vdev option. Link bonding devices will be initialized after all physical devices have been probed and initialized.

---
 lib/librte_eal/common/eal_common_dev.c      | 66 +++++++++++++++++++++++++++--
 lib/librte_eal/common/eal_common_pci.c      |  6 +++
 lib/librte_eal/common/include/eal_private.h |  7 +++
 lib/librte_eal/common/include/rte_dev.h     |  1 +
 lib/librte_ether/rte_ethdev.c               | 34 +++++++++++++--
 lib/librte_ether/rte_ethdev.h               |  7 ++-
 lib/librte_pmd_pcap/rte_eth_pcap.c          | 22 +++++-----
 lib/librte_pmd_ring/rte_eth_ring.c          | 32 +++++++-------
 lib/librte_pmd_ring/rte_eth_ring.h          |  3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |  2 +-
 10 files changed, 144 insertions(+), 36 deletions(-)
lib/librte_eal/common/eal_common_dev.c +62 -4
index eae5656..b50c908 100644
@@ -75,14 +75,28 @@ rte_eal_dev_init(void)
 
 	/* call the init function for each virtual device */
 	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		uint8_t bdev = 0;
 
 		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
 			continue;
 
 		TAILQ_FOREACH(driver, &dev_driver_list, next) {
-			if (driver->type != PMD_VDEV)
+			/* RTE_DEVTYPE_VIRTUAL can only be a virtual or bonded device*/
+			if (driver->type != PMD_VDEV && driver->type != PMD_BDEV)
 				continue;
 
+			/*
+			 * Bonded devices are not initialize here, we do it later in
+			 * rte_eal_bonded_dev_init() after all physical devices have been
+			 * probed and initialized
+			 */
+			if (driver->type == PMD_BDEV &&
+					!strncmp(driver->name, devargs->virtual.drv_name,
+							strlen(driver->name))) {
+				bdev = 1;
+				break;
+			}
+
 			/* search a driver prefix in virtual device name */
 			if (!strncmp(driver->name, devargs->virtual.drv_name,
 					strlen(driver->name))) {
@@ -92,9 +106,9 @@ rte_eal_dev_init(void)
 			}
 		}
 
-		if (driver == NULL) {
-			rte_panic("no driver found for %s\n",
-				  devargs->virtual.drv_name);
+		if (driver == NULL && !bdev) {
+			rte_panic("no driver found for %s and is not a bonded vdev %d\n",
+				  devargs->virtual.drv_name, bdev);
 		}
 	}
 
@@ -107,3 +121,47 @@ rte_eal_dev_init(void)
 	}
 	return 0;
 }
+
+#ifdef RTE_LIBRTE_PMD_BOND
+int
+rte_eal_bonded_dev_init(void)
+{
+	struct rte_devargs *devargs;
+	struct rte_driver *driver;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		int vdev = 0;
+
+		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
+			continue;
+
+		TAILQ_FOREACH(driver, &dev_driver_list, next) {
+			if (driver->type != PMD_VDEV && driver->type != PMD_BDEV)
+				continue;
+
+			/* Virtual devices have already been initialized so we skip them
+			 * here*/
+			if (driver->type == PMD_VDEV &&
+					!strncmp(driver->name, devargs->virtual.drv_name,
+							strlen(driver->name))) {
+				vdev = 1;
+				break;
+			}
+
+			/* search a driver prefix in bonded device name */
+			if (!strncmp(driver->name, devargs->virtual.drv_name,
+					strlen(driver->name))) {
+				driver->init(devargs->virtual.drv_name, devargs->args);
+				break;
+			}
+		}
+
+		if (driver == NULL && !vdev) {
+			rte_panic("no driver found for %s\n",
+					devargs->virtual.drv_name);
+		}
+	}
+	return 0;
+}
+#endif
+
lib/librte_eal/common/eal_common_pci.c +6 -0
index 4d877ea..9b584f5 100644
@@ -166,7 +166,13 @@ rte_eal_pci_probe(void)
 				 dev->addr.devid, dev->addr.function);
 	}
 
+#ifdef RTE_LIBRTE_PMD_BOND
+	/* After all physical PCI devices have been probed and initialized then we
+	 * initialize the bonded devices */
+	return rte_eal_bonded_dev_init();
+#else
 	return 0;
+#endif
 }
 
 /* dump one device */
lib/librte_eal/common/include/eal_private.h +7 -0
index 232fcec..f6081bb 100644
@@ -203,4 +203,11 @@ int rte_eal_alarm_init(void);
  */
 int rte_eal_dev_init(void);
 
+#ifdef RTE_LIBRTE_PMD_BOND
+/**
+ * Initialize the bonded devices
+ */
+int rte_eal_bonded_dev_init(void);
+#endif
+
 #endif /* _EAL_PRIVATE_H_ */
lib/librte_eal/common/include/rte_dev.h +1 -0
index f7e3a10..f0a780a 100644
@@ -62,6 +62,7 @@ typedef int (rte_dev_init_t)(const char *name, const char *args);
 enum pmd_type {
 	PMD_VDEV = 0,
 	PMD_PDEV = 1,
+	PMD_BDEV = 2,	/**< Poll Mode Driver Bonded Device*/
 };
 
 /**
lib/librte_ether/rte_ethdev.c +31 -3
index 8011b8b..4c2f1d3 100644
@@ -64,6 +64,7 @@
 #include <rte_mbuf.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
+#include <rte_string_fns.h>
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"
@@ -152,8 +153,21 @@ rte_eth_dev_data_alloc(void)
 				RTE_MAX_ETHPORTS * sizeof(*rte_eth_dev_data));
 }
 
+static int
+rte_eth_dev_name_unique(const char* name)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_ports; i++) {
+		if (strcmp(rte_eth_devices[i].data->name, name) == 0)
+			return -1;
+	}
+
+	return 0;
+}
+
 struct rte_eth_dev *
-rte_eth_dev_allocate(void)
+rte_eth_dev_allocate(const char* name)
 {
 	struct rte_eth_dev *eth_dev;
 
@@ -165,23 +179,37 @@ rte_eth_dev_allocate(void)
 	if (rte_eth_dev_data == NULL)
 		rte_eth_dev_data_alloc();
 
+	if (rte_eth_dev_name_unique(name)) {
+		PMD_DEBUG_TRACE("Ethernet Device with name %s already allocated!\n");
+		return NULL;
+	}
+
 	eth_dev = &rte_eth_devices[nb_ports];
 	eth_dev->data = &rte_eth_dev_data[nb_ports];
+	rte_snprintf(eth_dev->data->name , sizeof(eth_dev->data->name ),
+			"%s", name);
 	eth_dev->data->port_id = nb_ports++;
 	return eth_dev;
 }
 
 static int
 rte_eth_dev_init(struct rte_pci_driver *pci_drv,
-		 struct rte_pci_device *pci_dev)
+		struct rte_pci_device *pci_dev)
 {
 	struct eth_driver    *eth_drv;
 	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
 	int diag;
 
 	eth_drv = (struct eth_driver *)pci_drv;
 
-	eth_dev = rte_eth_dev_allocate();
+	/* Create unique ethdev name by concatenating drive name and number of
+	 * ports */
+	rte_snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "%d:%d.%d",
+			pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
+
+	eth_dev = rte_eth_dev_allocate(ethdev_name);
 	if (eth_dev == NULL)
 		return -ENOMEM;
 
lib/librte_ether/rte_ethdev.h +6 -1
index 67eda50..27ed0ab 100644
@@ -1233,6 +1233,8 @@ struct rte_eth_dev_sriov {
 };
 #define RTE_ETH_DEV_SRIOV(dev)         ((dev)->data->sriov)
 
+#define RTE_ETH_NAME_MAX_LEN (32)
+
 /**
  * @internal
  * The data part, with no function pointers, associated with each ethernet device.
@@ -1241,6 +1243,8 @@ struct rte_eth_dev_sriov {
  * processes in a multi-process configuration.
  */
 struct rte_eth_dev_data {
+	char name[RTE_ETH_NAME_MAX_LEN]; /**< Unique identifier name */
+
 	void **rx_queues; /**< Array of pointers to RX queues. */
 	void **tx_queues; /**< Array of pointers to TX queues. */
 	uint16_t nb_rx_queues; /**< Number of RX queues. */
@@ -1293,10 +1297,11 @@ extern uint8_t rte_eth_dev_count(void);
  * Allocates a new ethdev slot for an ethernet device and returns the pointer
  * to that slot for the driver to use.
  *
+ * @param	name	Unique identifier name for each Ethernet device
  * @return
  *   - Slot in the rte_dev_devices array for a new device;
  */
-struct rte_eth_dev *rte_eth_dev_allocate(void);
+struct rte_eth_dev *rte_eth_dev_allocate(const char *name);
 
 struct eth_driver;
 /**
lib/librte_pmd_pcap/rte_eth_pcap.c +11 -11
index b3dbbda..cd6c0e1 100644
@@ -534,7 +534,7 @@ open_tx_iface(const char *key __rte_unused, const char *value, void *extra_args)
 
 
 static int
-rte_pmd_init_internals(const unsigned nb_rx_queues,
+rte_pmd_init_internals(const char* name, const unsigned nb_rx_queues,
 		const unsigned nb_tx_queues,
 		const unsigned numa_node,
 		struct pmd_internals **internals,
@@ -558,20 +558,20 @@ rte_pmd_init_internals(const unsigned nb_rx_queues,
 	/* now do all data allocation - for eth_dev structure, dummy pci driver
 	 * and internal (private) data
 	 */
-	data = rte_zmalloc_socket(NULL, sizeof(*data), 0, numa_node);
+	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
 	if (data == NULL)
 		goto error;
 
-	pci_dev = rte_zmalloc_socket(NULL, sizeof(*pci_dev), 0, numa_node);
+	pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, numa_node);
 	if (pci_dev == NULL)
 		goto error;
 
-	*internals = rte_zmalloc_socket(NULL, sizeof(**internals), 0, numa_node);
+	*internals = rte_zmalloc_socket(name, sizeof(**internals), 0, numa_node);
 	if (*internals == NULL)
 		goto error;
 
 	/* reserve an ethdev entry */
-	*eth_dev = rte_eth_dev_allocate();
+	*eth_dev = rte_eth_dev_allocate(name);
 	if (*eth_dev == NULL)
 		goto error;
 
@@ -617,7 +617,7 @@ rte_pmd_init_internals(const unsigned nb_rx_queues,
 }
 
 static int
-rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
+rte_eth_from_pcaps_n_dumpers(const char *name, pcap_t * const rx_queues[],
 		const unsigned nb_rx_queues,
 		pcap_dumper_t * const tx_queues[],
 		const unsigned nb_tx_queues,
@@ -634,7 +634,7 @@ rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
 	if (tx_queues == NULL && nb_tx_queues > 0)
 		return -1;
 
-	if (rte_pmd_init_internals(nb_rx_queues, nb_tx_queues, numa_node,
+	if (rte_pmd_init_internals(name, nb_rx_queues, nb_tx_queues, numa_node,
 			&internals, &eth_dev, kvlist) < 0)
 		return -1;
 
@@ -652,7 +652,7 @@ rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
 }
 
 static int
-rte_eth_from_pcaps(pcap_t * const rx_queues[],
+rte_eth_from_pcaps(const char *name, pcap_t * const rx_queues[],
 		const unsigned nb_rx_queues,
 		pcap_t * const tx_queues[],
 		const unsigned nb_tx_queues,
@@ -669,7 +669,7 @@ rte_eth_from_pcaps(pcap_t * const rx_queues[],
 	if (tx_queues == NULL && nb_tx_queues > 0)
 		return -1;
 
-	if (rte_pmd_init_internals(nb_rx_queues, nb_tx_queues, numa_node,
+	if (rte_pmd_init_internals(name, nb_rx_queues, nb_tx_queues, numa_node,
 			&internals, &eth_dev, kvlist) < 0)
 		return -1;
 
@@ -760,10 +760,10 @@ rte_pmd_pcap_devinit(const char *name, const char *params)
 		return -1;
 
 	if (using_dumpers)
-		return rte_eth_from_pcaps_n_dumpers(pcaps.pcaps, pcaps.num_of_rx,
+		return rte_eth_from_pcaps_n_dumpers(name, pcaps.pcaps, pcaps.num_of_rx,
 				dumpers.dumpers, dumpers.num_of_tx, numa_node, kvlist);
 
-	return rte_eth_from_pcaps(pcaps.pcaps, pcaps.num_of_rx, dumpers.pcaps,
+	return rte_eth_from_pcaps(name, pcaps.pcaps, pcaps.num_of_rx, dumpers.pcaps,
 			dumpers.num_of_tx, numa_node, kvlist);
 
 }
lib/librte_pmd_ring/rte_eth_ring.c +17 -15
index 10d4e24..e6779c4 100644
@@ -219,7 +219,7 @@ static struct eth_dev_ops ops = {
 };
 
 int
-rte_eth_from_rings(struct rte_ring *const rx_queues[],
+rte_eth_from_rings(const char* name, struct rte_ring *const rx_queues[],
 		const unsigned nb_rx_queues,
 		struct rte_ring *const tx_queues[],
 		const unsigned nb_tx_queues,
@@ -243,20 +243,20 @@ rte_eth_from_rings(struct rte_ring *const rx_queues[],
 	/* now do all data allocation - for eth_dev structure, dummy pci driver
 	 * and internal (private) data
 	 */
-	data = rte_zmalloc_socket(NULL, sizeof(*data), 0, numa_node);
+	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
 	if (data == NULL)
 		goto error;
 
-	pci_dev = rte_zmalloc_socket(NULL, sizeof(*pci_dev), 0, numa_node);
+	pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, numa_node);
 	if (pci_dev == NULL)
 		goto error;
 
-	internals = rte_zmalloc_socket(NULL, sizeof(*internals), 0, numa_node);
+	internals = rte_zmalloc_socket(name, sizeof(*internals), 0, numa_node);
 	if (internals == NULL)
 		goto error;
 
 	/* reserve an ethdev entry */
-	eth_dev = rte_eth_dev_allocate();
+	eth_dev = rte_eth_dev_allocate(name);
 	if (eth_dev == NULL)
 		goto error;
 
@@ -335,7 +335,7 @@ eth_dev_ring_create(const char *name, const unsigned numa_node,
 			return -1;
 	}
 
-	if (rte_eth_from_rings(rxtx, num_rings, rxtx, num_rings, numa_node))
+	if (rte_eth_from_rings(name, rxtx, num_rings, rxtx, num_rings, numa_node))
 		return -1;
 
 	return 0;
@@ -352,29 +352,31 @@ eth_dev_ring_pair_create(const char *name, const unsigned numa_node,
 	struct rte_ring *rx[RTE_PMD_RING_MAX_RX_RINGS];
 	struct rte_ring *tx[RTE_PMD_RING_MAX_TX_RINGS];
 	unsigned i;
-	char rng_name[RTE_RING_NAMESIZE];
+	char rx_rng_name[RTE_RING_NAMESIZE];
+	char tx_rng_name[RTE_RING_NAMESIZE];
 	unsigned num_rings = RTE_MIN(RTE_PMD_RING_MAX_RX_RINGS,
 			RTE_PMD_RING_MAX_TX_RINGS);
 
 	for (i = 0; i < num_rings; i++) {
-		rte_snprintf(rng_name, sizeof(rng_name), "ETH_RX%u_%s", i, name);
+		rte_snprintf(rx_rng_name, sizeof(rx_rng_name), "ETH_RX%u_%s", i, name);
 		rx[i] = (action == DEV_CREATE) ?
-				rte_ring_create(rng_name, 1024, numa_node,
+				rte_ring_create(rx_rng_name, 1024, numa_node,
 						RING_F_SP_ENQ|RING_F_SC_DEQ) :
-				rte_ring_lookup(rng_name);
+				rte_ring_lookup(rx_rng_name);
 		if (rx[i] == NULL)
 			return -1;
-		rte_snprintf(rng_name, sizeof(rng_name), "ETH_TX%u_%s", i, name);
+		rte_snprintf(tx_rng_name, sizeof(tx_rng_name), "ETH_TX%u_%s", i, name);
 		tx[i] = (action == DEV_CREATE) ?
-				rte_ring_create(rng_name, 1024, numa_node,
+				rte_ring_create(tx_rng_name, 1024, numa_node,
 						RING_F_SP_ENQ|RING_F_SC_DEQ):
-				rte_ring_lookup(rng_name);
+				rte_ring_lookup(tx_rng_name);
 		if (tx[i] == NULL)
 			return -1;
 	}
 
-	if (rte_eth_from_rings(rx, num_rings, tx, num_rings, numa_node) ||
-			rte_eth_from_rings(tx, num_rings, rx, num_rings, numa_node) )
+	if (rte_eth_from_rings(rx_rng_name, rx, num_rings, tx, num_rings,
+			numa_node) || rte_eth_from_rings(tx_rng_name, tx, num_rings, rx,
+					num_rings, numa_node) )
 		return -1;
 
 	return 0;
lib/librte_pmd_ring/rte_eth_ring.h +2 -1
index ef29344..e6ae19e 100644
@@ -40,7 +40,8 @@ extern "C" {
 
 #include <rte_ring.h>
 
-int rte_eth_from_rings(struct rte_ring * const rx_queues[],
+int rte_eth_from_rings(const char *name,
+		struct rte_ring * const rx_queues[],
 		const unsigned nb_rx_queues,
 		struct rte_ring *const tx_queues[],
 		const unsigned nb_tx_queues,
lib/librte_pmd_xenvirt/rte_eth_xenvirt.c +1 -1
index 7c4d3fe..a0b4bdd 100644
@@ -647,7 +647,7 @@ eth_dev_xenvirt_create(const char *name, const char *params,
 		goto err;
 
 	/* reserve an ethdev entry */
-	eth_dev = rte_eth_dev_allocate();
+	eth_dev = rte_eth_dev_allocate(name);
 	if (eth_dev == NULL)
 		goto err;
 
Signature · 1 line
1.8.5.3

A message that is not in the archive (sent off-list or not yet received): 258914f35917ae07dddc991ac9726542964dce44.1402662300.git.declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#56 lore raw

Re: [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 40 lines · Declan Doherty

Updating functionality in EAL to support adding link bonding devices via –vdev option. Link bonding devices will be initialized after all physical devices have been probed and initialized.

---
 lib/librte_eal/common/eal_common_dev.c      | 66 +++++++++++++++++++++++++++--
 lib/librte_eal/common/eal_common_pci.c      |  6 +++
 lib/librte_eal/common/include/eal_private.h |  7 +++
 lib/librte_eal/common/include/rte_dev.h     |  1 +
 lib/librte_ether/rte_ethdev.c               | 34 +++++++++++++--
 lib/librte_ether/rte_ethdev.h               |  7 ++-
 lib/librte_pmd_pcap/rte_eth_pcap.c          | 22 +++++-----
 lib/librte_pmd_ring/rte_eth_ring.c          | 32 +++++++-------
 lib/librte_pmd_ring/rte_eth_ring.h          |  3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |  2 +-
 10 files changed, 144 insertions(+), 36 deletions(-)
lib/librte_eal/common/eal_common_dev.c +5 -1
index eae5656..b50c908 100644
@@ -75,14 +75,28 @@ rte_eal_dev_init(void)
 
 	/* call the init function for each virtual device */
 	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		uint8_t bdev = 0;
 
 		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
 			continue;
 
 		TAILQ_FOREACH(driver, &dev_driver_list, next) {
-			if (driver->type != PMD_VDEV)
+			/* RTE_DEVTYPE_VIRTUAL can only be a virtual or bonded device*/
+			if (driver->type != PMD_VDEV && driver->type != PMD_BDEV)
 				continue;
 
+			/*
+			 * Bonded devices are not initialize here, we do it later in

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 99

Quoted 10 lines
lib/librte_eal/common/eal_common_dev.c +10 -0
+			 * rte_eal_bonded_dev_init() after all physical devices have been
+			 * probed and initialized
+			 */
+			if (driver->type == PMD_BDEV &&
+					!strncmp(driver->name, devargs->virtual.drv_name,
+							strlen(driver->name))) {
+				bdev = 1;
+				break;
+			}
+

I really don't think you need to add a new device type for bonded devs. Its got no specific hardware that it drives, and you configure it with a --vdev command, so treat it as one here. I understand that you need to pass additional information about slaves to a bonded device, which is fine, but you can do that with kvargs pretty easily, at which point its just another vdev. The only other requirement is that you initilize the bonded vdev after the slave vdevs have been created, which you can do by any of several methods (a priority field to indicate that bonded drivers should be initilized last/later, a deferral return code from the init routine, or by dead reckoning via the careful construction of the application command line (placed the bonded --vdev option last on the command line argument list at run time).

Quoted 54 lines
lib/librte_eal/common/eal_common_dev.c +37 -3
 			/* search a driver prefix in virtual device name */
 			if (!strncmp(driver->name, devargs->virtual.drv_name,
 					strlen(driver->name))) {
@@ -92,9 +106,9 @@ rte_eal_dev_init(void)
 			}
 		}
 
-		if (driver == NULL) {
-			rte_panic("no driver found for %s\n",
-				  devargs->virtual.drv_name);
+		if (driver == NULL && !bdev) {
+			rte_panic("no driver found for %s and is not a bonded vdev %d\n",
+				  devargs->virtual.drv_name, bdev);
 		}
 	}
 
@@ -107,3 +121,47 @@ rte_eal_dev_init(void)
 	}
 	return 0;
 }
+
+#ifdef RTE_LIBRTE_PMD_BOND
+int
+rte_eal_bonded_dev_init(void)
+{
+	struct rte_devargs *devargs;
+	struct rte_driver *driver;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		int vdev = 0;
+
+		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
+			continue;
+
+		TAILQ_FOREACH(driver, &dev_driver_list, next) {
+			if (driver->type != PMD_VDEV && driver->type != PMD_BDEV)
+				continue;
+
+			/* Virtual devices have already been initialized so we skip them
+			 * here*/
+			if (driver->type == PMD_VDEV &&
+					!strncmp(driver->name, devargs->virtual.drv_name,
+							strlen(driver->name))) {
+				vdev = 1;
+				break;
+			}
+
+			/* search a driver prefix in bonded device name */
+			if (!strncmp(driver->name, devargs->virtual.drv_name,
+					strlen(driver->name))) {
+				driver->init(devargs->virtual.drv_name, devargs->args);
+				break;
+			}
+		}

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 167

Quoted 10 lines
lib/librte_eal/common/eal_common_dev.c +10 -0
+
+		if (driver == NULL && !vdev) {
+			rte_panic("no driver found for %s\n",
+					devargs->virtual.drv_name);
+		}
+	}
+	return 0;
+}
+#endif
+

If you treat bonded devices as vdevs, you can remove this function entirely.

lib/librte_eal/common/eal_common_pci.c rte_eal_pci_probe(void) · line 173

Quoted 13 lines
lib/librte_eal/common/eal_common_pci.c +5 -0
index 4d877ea..9b584f5 100644
@@ -166,7 +166,13 @@ rte_eal_pci_probe(void)
 				 dev->addr.devid, dev->addr.function);
 	}
 
+#ifdef RTE_LIBRTE_PMD_BOND
+	/* After all physical PCI devices have been probed and initialized then we
+	 * initialize the bonded devices */
+	return rte_eal_bonded_dev_init();
+#else

This is the wrong place for this, bonded devices are not pci devices, this doesn't belong in the pci device probe path. If you treat the bonded devices as vdevs and handle the ordering as described above, you won't need this anyway.

Quoted 26 lines
lib/librte_eal/common/eal_common_pci.c +1 -0
 	return 0;
+#endif
 }
 
 /* dump one device */
lib/librte_eal/common/include/eal_private.h +7 -0
index 232fcec..f6081bb 100644
@@ -203,4 +203,11 @@ int rte_eal_alarm_init(void);
  */
 int rte_eal_dev_init(void);
 
+#ifdef RTE_LIBRTE_PMD_BOND
+/**
+ * Initialize the bonded devices
+ */
+int rte_eal_bonded_dev_init(void);
+#endif
+
 #endif /* _EAL_PRIVATE_H_ */
lib/librte_eal/common/include/rte_dev.h +0 -0
index f7e3a10..f0a780a 100644

lib/librte_eal/common/include/rte_dev.h typedef int (rte_dev_init_t)(const char *name, const char *args); · line 66

Quoted 5 lines
lib/librte_eal/common/include/rte_dev.h +1 -0
@@ -62,6 +62,7 @@ typedef int (rte_dev_init_t)(const char *name, const char *args);
 enum pmd_type {
 	PMD_VDEV = 0,
 	PMD_PDEV = 1,
+	PMD_BDEV = 2,	/**< Poll Mode Driver Bonded Device*/
 };

Can drop this as noted above.

Quoted 38 lines
lib/librte_eal/common/include/rte_dev.h +0 -0
 /**
lib/librte_ether/rte_ethdev.c +15 -1
index 8011b8b..4c2f1d3 100644
@@ -64,6 +64,7 @@
 #include <rte_mbuf.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
+#include <rte_string_fns.h>
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"
@@ -152,8 +153,21 @@ rte_eth_dev_data_alloc(void)
 				RTE_MAX_ETHPORTS * sizeof(*rte_eth_dev_data));
 }
 
+static int
+rte_eth_dev_name_unique(const char* name)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_ports; i++) {
+		if (strcmp(rte_eth_devices[i].data->name, name) == 0)
+			return -1;
+	}
+
+	return 0;
+}
+
 struct rte_eth_dev *
-rte_eth_dev_allocate(void)
+rte_eth_dev_allocate(const char* name)
 {
 	struct rte_eth_dev *eth_dev;
 

lib/librte_ether/rte_ethdev.c rte_eth_dev_allocate(void) · line 186

Quoted 8 lines
lib/librte_ether/rte_ethdev.c +5 -0
@@ -165,23 +179,37 @@ rte_eth_dev_allocate(void)
 	if (rte_eth_dev_data == NULL)
 		rte_eth_dev_data_alloc();
 
+	if (rte_eth_dev_name_unique(name)) {
+		PMD_DEBUG_TRACE("Ethernet Device with name %s already allocated!\n");
+		return NULL;
+	}
+

This seems fairly racy if you allow dynamic device creation at run time from the application, if multiple threads attempt to create bonds in parallel.

lib/librte_pmd_pcap/rte_eth_pcap.c

Quoted 69 lines
lib/librte_ether/rte_ethdev.c +11 -2
 	eth_dev = &rte_eth_devices[nb_ports];
 	eth_dev->data = &rte_eth_dev_data[nb_ports];
+	rte_snprintf(eth_dev->data->name , sizeof(eth_dev->data->name ),
+			"%s", name);
 	eth_dev->data->port_id = nb_ports++;
 	return eth_dev;
 }
 
 static int
 rte_eth_dev_init(struct rte_pci_driver *pci_drv,
-		 struct rte_pci_device *pci_dev)
+		struct rte_pci_device *pci_dev)
 {
 	struct eth_driver    *eth_drv;
 	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
 	int diag;
 
 	eth_drv = (struct eth_driver *)pci_drv;
 
-	eth_dev = rte_eth_dev_allocate();
+	/* Create unique ethdev name by concatenating drive name and number of
+	 * ports */
+	rte_snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "%d:%d.%d",
+			pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
+
+	eth_dev = rte_eth_dev_allocate(ethdev_name);
 	if (eth_dev == NULL)
 		return -ENOMEM;
 
lib/librte_ether/rte_ethdev.h +6 -1
index 67eda50..27ed0ab 100644
@@ -1233,6 +1233,8 @@ struct rte_eth_dev_sriov {
 };
 #define RTE_ETH_DEV_SRIOV(dev)         ((dev)->data->sriov)
 
+#define RTE_ETH_NAME_MAX_LEN (32)
+
 /**
  * @internal
  * The data part, with no function pointers, associated with each ethernet device.
@@ -1241,6 +1243,8 @@ struct rte_eth_dev_sriov {
  * processes in a multi-process configuration.
  */
 struct rte_eth_dev_data {
+	char name[RTE_ETH_NAME_MAX_LEN]; /**< Unique identifier name */
+
 	void **rx_queues; /**< Array of pointers to RX queues. */
 	void **tx_queues; /**< Array of pointers to TX queues. */
 	uint16_t nb_rx_queues; /**< Number of RX queues. */
@@ -1293,10 +1297,11 @@ extern uint8_t rte_eth_dev_count(void);
  * Allocates a new ethdev slot for an ethernet device and returns the pointer
  * to that slot for the driver to use.
  *
+ * @param	name	Unique identifier name for each Ethernet device
  * @return
  *   - Slot in the rte_dev_devices array for a new device;
  */
-struct rte_eth_dev *rte_eth_dev_allocate(void);
+struct rte_eth_dev *rte_eth_dev_allocate(const char *name);
 
 struct eth_driver;
 

/**

lib/librte_pmd_pcap/rte_eth_pcap.c +0 -0

Hmm, we're modifying other pmds for the naming feature, I think it would be best split out into a separate patch. Something entitled "support unique interface naming for virtual pmds" or something.

A message that is not in the archive (sent off-list or not yet received): 20140613160807.GD22451-B26myB8xz7F8NnZeBjwnZQMhkBWG/[email protected]

#58 lore raw

Re: [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 68 lines

-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Friday, June 13, 2014 5:08 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 8 lines · Declan Doherty

Updating functionality in EAL to support adding link bonding devices via –vdev option. Link bonding devices will be initialized after all physical devices have been probed and initialized.

---
 lib/librte_eal/common/eal_common_dev.c      | 66

+++++++++++++++++++++++++++--

Quoted 11 lines
 lib/librte_eal/common/eal_common_pci.c      |  6 +++
 lib/librte_eal/common/include/eal_private.h |  7 +++
 lib/librte_eal/common/include/rte_dev.h     |  1 +
 lib/librte_ether/rte_ethdev.c               | 34 +++++++++++++--
 lib/librte_ether/rte_ethdev.h               |  7 ++-
 lib/librte_pmd_pcap/rte_eth_pcap.c          | 22 +++++-----
 lib/librte_pmd_ring/rte_eth_ring.c          | 32 +++++++-------
 lib/librte_pmd_ring/rte_eth_ring.h          |  3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |  2 +-
 10 files changed, 144 insertions(+), 36 deletions(-)

Review

Quoted 1 line
(quoted diff) +0 -0

b/lib/librte_eal/common/eal_common_dev.c

Quoted 5 lines

index eae5656..b50c908 100644

lib/librte_eal/common/eal_common_dev.c +0 -0
@@ -75,14 +75,28 @@ rte_eal_dev_init(void)
 

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 84

Quoted 10 lines
lib/librte_eal/common/eal_common_dev.c +2 -1
 	/* call the init function for each virtual device */
 	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		uint8_t bdev = 0;
 
 		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
 			continue;
 
 		TAILQ_FOREACH(driver, &dev_driver_list, next) {
-			if (driver->type != PMD_VDEV)
+			/* RTE_DEVTYPE_VIRTUAL can only be a virtual or bonded

device*/

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 85

Quoted 1 line
lib/librte_eal/common/eal_common_dev.c +1 -0
+			if (driver->type != PMD_VDEV && driver->type !=

PMD_BDEV)

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void)

Quoted 5 lines
lib/librte_eal/common/eal_common_dev.c +3 -0
 				continue;
 
+			/*
+			 * Bonded devices are not initialize here, we do it later in
+			 * rte_eal_bonded_dev_init() after all physical devices

have been

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 99

Quoted 10 lines
lib/librte_eal/common/eal_common_dev.c +9 -0
+			 * probed and initialized
+			 */
+			if (driver->type == PMD_BDEV &&
+					!strncmp(driver->name, devargs-
 virtual.drv_name,
+							strlen(driver->name))) {
+				bdev = 1;
+				break;
+			}
+

I really don't think you need to add a new device type for bonded devs. Its got no specific hardware that it drives, and you configure it with a --vdev command, so treat it as one here. I understand that you need to pass additional

Quoted 9 lines

information about slaves to a bonded device, which is fine, but you can do that with kvargs pretty easily, at which point its just another vdev. The only other requirement is that you initilize the bonded vdev after the slave vdevs have been created, which you can do by any of several methods (a priority field to indicate that bonded drivers should be initilized last/later, a deferral return code from the init routine, or by dead reckoning via the careful construction of the application command line (placed the bonded --vdev option last on the command line argument list at run time).

It was my initial intent to do as you have describe above, but the physical devices cause a real issue here, physical devices don't call through to rte_eth_dev_allocate until during rte_eal_pci_probe call, so it's not possible to initialize the bonded device from within rte_eal_dev_init as the physical devices have not been fully initialized at this point, as a port_id has not been allocated and can't be added as bonding slaves. I don't see away around this without changing the EAL API, which I've tried to avoid with this solution.

Ordering isn't an issue, and can easily be solved if the above problem didn't exist, and although a new device type isn't technically required, I think it's a cleaner solution than doing string comparisons.

Quoted 63 lines

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 110

Quoted 13 lines
lib/librte_eal/common/eal_common_dev.c +0 -0
 			/* search a driver prefix in virtual device name */
 			if (!strncmp(driver->name, devargs->virtual.drv_name,
lib/librte_eal/common/eal_common_dev.c +2 -3
 					strlen(driver->name))) {
@@ -92,9 +106,9 @@ rte_eal_dev_init(void)
 			}
 		}
 
-		if (driver == NULL) {
-			rte_panic("no driver found for %s\n",
-				  devargs->virtual.drv_name);
+		if (driver == NULL && !bdev) {
+			rte_panic("no driver found for %s and is not a bonded

vdev %d\n",

Quoted 14 lines
lib/librte_eal/common/eal_common_dev.c +7 -0
+				  devargs->virtual.drv_name, bdev);
 		}
 	}
 
@@ -107,3 +121,47 @@ rte_eal_dev_init(void)
 	}
 	return 0;
 }
+
+#ifdef RTE_LIBRTE_PMD_BOND
+int
+rte_eal_bonded_dev_init(void)
+{
+	struct rte_devargs *devargs;

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 139

Quoted 10 lines
lib/librte_eal/common/eal_common_dev.c +10 -0
+	struct rte_driver *driver;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		int vdev = 0;
+
+		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
+			continue;
+
+		TAILQ_FOREACH(driver, &dev_driver_list, next) {
+			if (driver->type != PMD_VDEV && driver->type !=

PMD_BDEV)

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void)

Quoted 3 lines
lib/librte_eal/common/eal_common_dev.c +3 -0
+				continue;
+
+			/* Virtual devices have already been initialized so we skip

them

Quoted 20 lines
lib/librte_eal/common/eal_common_dev.c +3 -0
+			 * here*/
+			if (driver->type == PMD_VDEV &&
+					!strncmp(driver->name, devargs-

virtual.drv_name,

lib/librte_eal/common/eal_common_dev.c +9 -0
+							strlen(driver->name))) {
+				vdev = 1;
+				break;
+			}
+
+			/* search a driver prefix in bonded device name */
+			if (!strncmp(driver->name, devargs->virtual.drv_name,
+					strlen(driver->name))) {
+				driver->init(devargs->virtual.drv_name, devargs-

args);

lib/librte_eal/common/eal_common_dev.c +6 -0
+				break;
+			}
+		}
+
+		if (driver == NULL && !vdev) {
+			rte_panic("no driver found for %s\n",
Quoted 8 lines

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 167

Quoted 7 lines
lib/librte_eal/common/eal_common_dev.c +7 -0
+					devargs->virtual.drv_name);
+		}
+	}
+	return 0;
+}
+#endif
+

If you treat bonded devices as vdevs, you can remove this function entirely.

Agreed but only if there is a solution to the issues described above.

Quoted 10 lines

Review

Quoted 2 lines
(quoted diff) +0 -0

b/lib/librte_eal/common/eal_common_pci.c

Quoted 7 lines

index 4d877ea..9b584f5 100644

lib/librte_eal/common/eal_common_pci.c +0 -0
@@ -166,7 +166,13 @@ rte_eal_pci_probe(void)
 				 dev->addr.devid, dev->addr.function);
 	}
 
Quoted 8 lines

lib/librte_eal/common/eal_common_pci.c rte_eal_pci_probe(void) · line 173

Quoted 5 lines
lib/librte_eal/common/eal_common_pci.c +5 -0
+#ifdef RTE_LIBRTE_PMD_BOND
+	/* After all physical PCI devices have been probed and initialized then we
+	 * initialize the bonded devices */
+	return rte_eal_bonded_dev_init();
+#else

This is the wrong place for this, bonded devices are not pci devices, this doesn't belong in the pci device probe path. If you treat the bonded devices as vdevs and handle the ordering as described above, you won't need this anyway.

See first comment, but unless a new API is added for initialization of the bonded devices, then some sort signal/callback is required here to notify that it is now safe to initialize the bonded devices.

Quoted 79 lines

Review

Quoted 7 lines
lib/librte_eal/common/eal_common_pci.c +1 -0
 	return 0;
+#endif
 }
 
 /* dump one device */
(quoted diff) +0 -0

b/lib/librte_eal/common/include/eal_private.h

Review

Quoted 16 lines

index 232fcec..f6081bb 100644

lib/librte_eal/common/include/eal_private.h +7 -0
@@ -203,4 +203,11 @@ int rte_eal_alarm_init(void);
  */
 int rte_eal_dev_init(void);
 
+#ifdef RTE_LIBRTE_PMD_BOND
+/**
+ * Initialize the bonded devices
+ */
+int rte_eal_bonded_dev_init(void);
+#endif
+
 #endif /* _EAL_PRIVATE_H_ */
(quoted diff) +0 -0

b/lib/librte_eal/common/include/rte_dev.h

lib/librte_eal/common/include/rte_dev.h typedef int (rte_dev_init_t)(const char *name, const char

Quoted 4 lines

index f7e3a10..f0a780a 100644

lib/librte_eal/common/include/rte_dev.h +0 -0
@@ -62,6 +62,7 @@ typedef int (rte_dev_init_t)(const char *name, const char

*args);

lib/librte_eal/common/include/rte_dev.h typedef int (rte_dev_init_t)(const char *name, const char *args); · line 66

Quoted 5 lines
lib/librte_eal/common/include/rte_dev.h +1 -0
 enum pmd_type {
 	PMD_VDEV = 0,
 	PMD_PDEV = 1,
+	PMD_BDEV = 2,	/**< Poll Mode Driver Bonded Device*/
 };

Can drop this as noted above.

Quoted 15 lines
lib/librte_eal/common/include/rte_dev.h +0 -0
 /**
lib/librte_ether/rte_ethdev.c +1 -0
index 8011b8b..4c2f1d3 100644
@@ -64,6 +64,7 @@
 #include <rte_mbuf.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
+#include <rte_string_fns.h>
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"

lib/librte_ether/rte_ethdev.c rte_eth_dev_data_alloc(void) · line 153

Quoted 1 line
lib/librte_ether/rte_ethdev.c +0 -0
@@ -152,8 +153,21 @@ rte_eth_dev_data_alloc(void)
 				RTE_MAX_ETHPORTS *

sizeof(*rte_eth_dev_data));

Quoted 25 lines
lib/librte_ether/rte_ethdev.c +14 -1
 }
 
+static int
+rte_eth_dev_name_unique(const char* name)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_ports; i++) {
+		if (strcmp(rte_eth_devices[i].data->name, name) == 0)
+			return -1;
+	}
+
+	return 0;
+}
+
 struct rte_eth_dev *
-rte_eth_dev_allocate(void)
+rte_eth_dev_allocate(const char* name)
 {
 	struct rte_eth_dev *eth_dev;
 
@@ -165,23 +179,37 @@ rte_eth_dev_allocate(void)
 	if (rte_eth_dev_data == NULL)
 		rte_eth_dev_data_alloc();
 
Quoted 8 lines

lib/librte_ether/rte_ethdev.c rte_eth_dev_allocate(void) · line 183

Quoted 2 lines
lib/librte_ether/rte_ethdev.c +2 -0
+	if (rte_eth_dev_name_unique(name)) {
+		PMD_DEBUG_TRACE("Ethernet Device with name %s already

allocated!\n");

lib/librte_ether/rte_ethdev.c rte_eth_dev_allocate(void) · line 186

Quoted 3 lines
lib/librte_ether/rte_ethdev.c +3 -0
+		return NULL;
+	}
+

This seems fairly racy if you allow dynamic device creation at run time from the application, if multiple threads attempt to create bonds in parallel.

True but if this is an issue then there probably should be some locking around this allocation anyway.

Quoted 72 lines
Quoted 15 lines
lib/librte_ether/rte_ethdev.c +3 -1
 	eth_dev = &rte_eth_devices[nb_ports];
 	eth_dev->data = &rte_eth_dev_data[nb_ports];
+	rte_snprintf(eth_dev->data->name , sizeof(eth_dev->data->name ),
+			"%s", name);
 	eth_dev->data->port_id = nb_ports++;
 	return eth_dev;
 }
 
 static int
 rte_eth_dev_init(struct rte_pci_driver *pci_drv,
-		 struct rte_pci_device *pci_dev)
+		struct rte_pci_device *pci_dev)
 {

lib/librte_ether/rte_ethdev.c rte_eth_dev_allocate(void)

Quoted 10 lines
lib/librte_ether/rte_ethdev.c +3 -1
 	struct eth_driver    *eth_drv;
 	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
 	int diag;
 
 	eth_drv = (struct eth_driver *)pci_drv;
 
-	eth_dev = rte_eth_dev_allocate();
+	/* Create unique ethdev name by concatenating drive name and number

of

Quoted 14 lines
lib/librte_ether/rte_ethdev.c +5 -0
+	 * ports */
+	rte_snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "%d:%d.%d",
+			pci_dev->addr.bus, pci_dev->addr.devid, pci_dev-
 addr.function);
+
+	eth_dev = rte_eth_dev_allocate(ethdev_name);
 	if (eth_dev == NULL)
 		return -ENOMEM;
lib/librte_ether/rte_ethdev.h +0 -0
index 67eda50..27ed0ab 100644

lib/librte_ether/rte_ethdev.h struct rte_eth_dev_sriov { · line 1240

Quoted 8 lines
lib/librte_ether/rte_ethdev.h +2 -0
@@ -1233,6 +1233,8 @@ struct rte_eth_dev_sriov {
 };
 #define RTE_ETH_DEV_SRIOV(dev)         ((dev)->data->sriov)
 
+#define RTE_ETH_NAME_MAX_LEN (32)
+
 /**
  * @internal
  * The data part, with no function pointers, associated with each ethernet

device.

Quoted 21 lines
lib/librte_ether/rte_ethdev.h +4 -1
@@ -1241,6 +1243,8 @@ struct rte_eth_dev_sriov {
  * processes in a multi-process configuration.
  */
 struct rte_eth_dev_data {
+	char name[RTE_ETH_NAME_MAX_LEN]; /**< Unique identifier name */
+
 	void **rx_queues; /**< Array of pointers to RX queues. */
 	void **tx_queues; /**< Array of pointers to TX queues. */
 	uint16_t nb_rx_queues; /**< Number of RX queues. */
@@ -1293,10 +1297,11 @@ extern uint8_t rte_eth_dev_count(void);
  * Allocates a new ethdev slot for an ethernet device and returns the pointer
  * to that slot for the driver to use.
  *
+ * @param	name	Unique identifier name for each Ethernet device
  * @return
  *   - Slot in the rte_dev_devices array for a new device;
  */
-struct rte_eth_dev *rte_eth_dev_allocate(void);
+struct rte_eth_dev *rte_eth_dev_allocate(const char *name);
 
 struct eth_driver;
Quoted 6 lines

Review

Quoted 2 lines
lib/librte_ether/rte_ethdev.h +0 -0
 /**
(quoted diff) +0 -0

b/lib/librte_pmd_pcap/rte_eth_pcap.c
Hmm, we're modifying other pmds for the naming feature, I think it would be best split out into a separate patch. Something entitled "support unique interface naming for virtual pmds" or something.

True, but if I do that, I will need to break support for virtual devices in this patch set, and I would prefer to keep this functionality working initial release of link bonding. Also another patchset will be required at some point in the near future to tidy up/rationalize the current handling of virtual devices identification and these changes do not change functionally how these devices work.

A message that is not in the archive (sent off-list or not yet received): 345C63BAECC1AD42A2EC8C63AFFC3ADC13D38EE9-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org

#60 lore raw

Re: [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 84 lines · Declan
Quoted 68 lines

-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Friday, June 13, 2014 5:08 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 8 lines · Declan Doherty

Updating functionality in EAL to support adding link bonding devices via –vdev option. Link bonding devices will be initialized after all physical devices have been probed and initialized.

---
 lib/librte_eal/common/eal_common_dev.c      | 66

+++++++++++++++++++++++++++--

Quoted 11 lines
 lib/librte_eal/common/eal_common_pci.c      |  6 +++
 lib/librte_eal/common/include/eal_private.h |  7 +++
 lib/librte_eal/common/include/rte_dev.h     |  1 +
 lib/librte_ether/rte_ethdev.c               | 34 +++++++++++++--
 lib/librte_ether/rte_ethdev.h               |  7 ++-
 lib/librte_pmd_pcap/rte_eth_pcap.c          | 22 +++++-----
 lib/librte_pmd_ring/rte_eth_ring.c          | 32 +++++++-------
 lib/librte_pmd_ring/rte_eth_ring.h          |  3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |  2 +-
 10 files changed, 144 insertions(+), 36 deletions(-)

Review

Quoted 1 line
(quoted diff) +0 -0

b/lib/librte_eal/common/eal_common_dev.c

Quoted 5 lines

index eae5656..b50c908 100644

lib/librte_eal/common/eal_common_dev.c +0 -0
@@ -75,14 +75,28 @@ rte_eal_dev_init(void)
 

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 84

Quoted 10 lines
lib/librte_eal/common/eal_common_dev.c +2 -1
 	/* call the init function for each virtual device */
 	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		uint8_t bdev = 0;
 
 		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
 			continue;
 
 		TAILQ_FOREACH(driver, &dev_driver_list, next) {
-			if (driver->type != PMD_VDEV)
+			/* RTE_DEVTYPE_VIRTUAL can only be a virtual or bonded

device*/

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 85

Quoted 1 line
lib/librte_eal/common/eal_common_dev.c +1 -0
+			if (driver->type != PMD_VDEV && driver->type !=

PMD_BDEV)

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void)

Quoted 5 lines
lib/librte_eal/common/eal_common_dev.c +3 -0
 				continue;
 
+			/*
+			 * Bonded devices are not initialize here, we do it later in
+			 * rte_eal_bonded_dev_init() after all physical devices

have been

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 99

Quoted 10 lines
lib/librte_eal/common/eal_common_dev.c +9 -0
+			 * probed and initialized
+			 */
+			if (driver->type == PMD_BDEV &&
+					!strncmp(driver->name, devargs-
 virtual.drv_name,
+							strlen(driver->name))) {
+				bdev = 1;
+				break;
+			}
+

I really don't think you need to add a new device type for bonded devs. Its got no specific hardware that it drives, and you configure it with a --vdev command, so treat it as one here. I understand that you need to pass additional

Quoted 9 lines

information about slaves to a bonded device, which is fine, but you can do that with kvargs pretty easily, at which point its just another vdev. The only other requirement is that you initilize the bonded vdev after the slave vdevs have been created, which you can do by any of several methods (a priority field to indicate that bonded drivers should be initilized last/later, a deferral return code from the init routine, or by dead reckoning via the careful construction of the application command line (placed the bonded --vdev option last on the command line argument list at run time).

It was my initial intent to do as you have describe above, but the physical devices cause a real issue here, physical devices don't call through to rte_eth_dev_allocate until during rte_eal_pci_probe call, so it's not possible to initialize the bonded device from within rte_eal_dev_init as the physical devices have not been fully initialized at this point, as a port_id has not been allocated and can't be added as bonding slaves. I don't see away around this without changing the EAL API, which I've tried to avoid with this solution.

Quoted 4 lines

Ordering isn't an issue, and can easily be solved if the above problem didn't exist, and although a new device type isn't technically required, I think it's a cleaner solution than doing string comparisons.

Ugh, you're right. That stinks. We still shouldn't just drop the init code in with the pci probe code though, especially if dpdk starts supporting more stacked network devices. A notification system for interface creation that you could monitor for pci_device addresses (B:D:F tupples) would be nice, but might be overkill since dpdk doesn't really support device freeing yet. what might be useful is a generic ordering mechanism for rte_eal_dev_init. If you added a priority field to the rte_driver structure, you could create an enumeration for the field to define when the init routine for that driver was called something like:

typdef enum {
	PMD_INIT_FIRST = 0,
	PMD_INIT_POST_PROBE = 1,
}

Then you could make multiple calls to rte_eal_dev_init from rte_eal_init at the appropriate places in the initalization process, each time passing one of the above values. rte_eal_dev_init would only initalize those drivers whos priority matched the passed in priority. That would be helpful for interfaces like vlans, vxlans, tunnels, etc.

Quoted 27 lines
Quoted 27 lines
Quoted 21 lines
lib/librte_eal/common/eal_common_dev.c +14 -1
+static int
+rte_eth_dev_name_unique(const char* name)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_ports; i++) {
+		if (strcmp(rte_eth_devices[i].data->name, name) == 0)
+			return -1;
+	}
+
+	return 0;
+}
+
 struct rte_eth_dev *
-rte_eth_dev_allocate(void)
+rte_eth_dev_allocate(const char* name)
 {
 	struct rte_eth_dev *eth_dev;

lib/librte_eal/common/eal_common_dev.c rte_eth_dev_allocate(void) · line 183

Quoted 5 lines
lib/librte_eal/common/eal_common_dev.c +2 -0
@@ -165,23 +179,37 @@ rte_eth_dev_allocate(void)
 	if (rte_eth_dev_data == NULL)
 		rte_eth_dev_data_alloc();
 
+	if (rte_eth_dev_name_unique(name)) {
+		PMD_DEBUG_TRACE("Ethernet Device with name %s already

allocated!\n");

Quoted 7 lines
Quoted 5 lines

lib/librte_eal/common/eal_common_dev.c rte_eth_dev_allocate(void) · line 186

Quoted 3 lines
lib/librte_eal/common/eal_common_dev.c +3 -0
+		return NULL;
+	}
+

This seems fairly racy if you allow dynamic device creation at run time from the application, if multiple threads attempt to create bonds in parallel.

True but if this is an issue then there probably should be some locking around this allocation anyway.

Agreed the allocation of the port id is also racy.

Quoted 8 lines
Quoted 7 lines

Review

Quoted 3 lines
lib/librte_eal/common/eal_common_dev.c +0 -0
 /**
(quoted diff) +0 -0

b/lib/librte_pmd_pcap/rte_eth_pcap.c
Hmm, we're modifying other pmds for the naming feature, I think it would be best split out into a separate patch. Something entitled "support unique interface naming for virtual pmds" or something.

Quoted 5 lines

True, but if I do that, I will need to break support for virtual devices in this patch set, and I would prefer to keep this functionality working initial release of link bonding. Also another patchset will be required at some point in the near future to tidy up/rationalize the current handling of virtual devices identification and these changes do not change functionally how these devices work.

I'm not sure I'm following what you're saying here. If you split this into another patch set, and order earlier in this series, then you won't break anything. I'm not suggesting a functional change here, just a organizational one, so that this change doesn't do more than the changelog indicates.

Neil

A message that is not in the archive (sent off-list or not yet received): 20140613193815.GE22451-B26myB8xz7F8NnZeBjwnZQMhkBWG/[email protected]

#62 lore raw

Re: [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 122 lines

-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Friday, June 13, 2014 8:38 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 55 lines · Declan
Quoted 55 lines

-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Friday, June 13, 2014 5:08 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 8 lines · Declan Doherty

Updating functionality in EAL to support adding link bonding devices via –vdev option. Link bonding devices will be initialized after all physical devices have been probed and initialized.

---
 lib/librte_eal/common/eal_common_dev.c      | 66

+++++++++++++++++++++++++++--

Quoted 11 lines
 lib/librte_eal/common/eal_common_pci.c      |  6 +++
 lib/librte_eal/common/include/eal_private.h |  7 +++
 lib/librte_eal/common/include/rte_dev.h     |  1 +
 lib/librte_ether/rte_ethdev.c               | 34 +++++++++++++--
 lib/librte_ether/rte_ethdev.h               |  7 ++-
 lib/librte_pmd_pcap/rte_eth_pcap.c          | 22 +++++-----
 lib/librte_pmd_ring/rte_eth_ring.c          | 32 +++++++-------
 lib/librte_pmd_ring/rte_eth_ring.h          |  3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |  2 +-
 10 files changed, 144 insertions(+), 36 deletions(-)

Review

Quoted 1 line
(quoted diff) +0 -0

b/lib/librte_eal/common/eal_common_dev.c

Quoted 5 lines

index eae5656..b50c908 100644

lib/librte_eal/common/eal_common_dev.c +0 -0
@@ -75,14 +75,28 @@ rte_eal_dev_init(void)
 

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 84

Quoted 10 lines
lib/librte_eal/common/eal_common_dev.c +2 -1
 	/* call the init function for each virtual device */
 	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		uint8_t bdev = 0;
 
 		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
 			continue;
 
 		TAILQ_FOREACH(driver, &dev_driver_list, next) {
-			if (driver->type != PMD_VDEV)
+			/* RTE_DEVTYPE_VIRTUAL can only be a virtual or bonded

device*/

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 85

Quoted 1 line
lib/librte_eal/common/eal_common_dev.c +1 -0
+			if (driver->type != PMD_VDEV && driver->type !=

PMD_BDEV)

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 90

Quoted 5 lines
lib/librte_eal/common/eal_common_dev.c +3 -0
 				continue;
 
+			/*
+			 * Bonded devices are not initialize here, we do it later in
+			 * rte_eal_bonded_dev_init() after all physical devices

have been

Quoted 12 lines
Quoted 4 lines
Quoted 4 lines
lib/librte_eal/common/eal_common_dev.c +4 -0
+			 * probed and initialized
+			 */
+			if (driver->type == PMD_BDEV &&
+					!strncmp(driver->name, devargs-
Quoted 8 lines

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 100

Quoted 6 lines
lib/librte_eal/common/eal_common_dev.c +5 -0
 virtual.drv_name,
+							strlen(driver->name))) {
+				bdev = 1;
+				break;
+			}
+

I really don't think you need to add a new device type for bonded devs. Its got no specific hardware that it drives, and you configure it with a --vdev

command,

Quoted 7 lines
Quoted 7 lines

so treat it as one here. I understand that you need to pass additional information about slaves to a bonded device, which is fine, but you can do that with kvargs pretty easily, at which point its just another vdev. The only other requirement is that you initilize the bonded vdev after the slave vdevs have been created, which you can do by any of several methods (a priority field to indicate that bonded drivers should be initilized last/later, a deferral return code from the init routine, or by dead reckoning via the careful construction

of

Quoted 5 lines
Quoted 3 lines

the application command line (placed the bonded --vdev option last on the command line argument list at run time).

It was my initial intent to do as you have describe above, but the physical devices cause a real issue here, physical devices don't call through to

rte_eth_dev_allocate until

Quoted 1 line

during rte_eal_pci_probe call, so it's not possible to initialize the bonded device

from

Quoted 1 line

within rte_eal_dev_init as the physical devices have not been fully initialized at

this

Quoted 1 line

point, as a port_id has not been allocated and can't be added as bonding slaves. I

don't

Quoted 1 line

see away around this without changing the EAL API, which I've tried to avoid with

this solution.

Quoted 2 lines

Ordering isn't an issue, and can easily be solved if the above problem didn't

exist, and although

Quoted 1 line

a new device type isn't technically required, I think it's a cleaner solution than

doing

Quoted 2 lines

string comparisons.

Ugh, you're right. That stinks. We still shouldn't just drop the init code in with the pci probe code though, especially if dpdk starts supporting more stacked network devices. A notification system for interface creation that you could monitor for pci_device addresses (B:D:F tupples) would be nice, but might be overkill since dpdk doesn't really support device freeing yet. what might be useful is a generic ordering mechanism for rte_eal_dev_init. If you added a priority field to the rte_driver structure, you could create an enumeration for the field to define when the init routine for that driver was called something like:

typdef enum {
	PMD_INIT_FIRST = 0,
	PMD_INIT_POST_PROBE = 1,
}
Quoted 6 lines

Then you could make multiple calls to rte_eal_dev_init from rte_eal_init at the appropriate places in the initalization process, each time passing one of the above values. rte_eal_dev_init would only initalize those drivers whos priority matched the passed in priority. That would be helpful for interfaces like vlans, vxlans, tunnels, etc.

I'm not sure I understand how you intend this to work, are you proposing that rte_eal_dev_init is call multiple times by the user pre and post rte_eal_pci_probe this doesn't seem like an idea solution either. I'm not 100% clear why rte_eal_pci_probe is currently called by the application code and not initiated
from within rte_eal_dev_init, if this was the case we would be able to figure out
a dependency tree for initialization of devices, based on the parsed input arguments without having extra user input to or multiple calls of rte_eal_dev_init.

Either way I don't think that any of these solution are trivial and they would need to be thoroughly tested, which I don't think will be possible in the time frame for 1.7. If my current implementation calling rte_eal_bonded_dev_init from within rte_eal_pci_probe is unacceptable, then I propose that I remove the EAL changes for --vdev initialization of bonding devices from this release and only support the C API, and that an overall strategy is discussed for static device
initialization that is developed for 1.7.1 or 1.8.

Quoted 53 lines
Quoted 24 lines
Quoted 24 lines
Quoted 24 lines
lib/librte_eal/common/eal_common_dev.c +14 -1
+static int
+rte_eth_dev_name_unique(const char* name)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_ports; i++) {
+		if (strcmp(rte_eth_devices[i].data->name, name) == 0)
+			return -1;
+	}
+
+	return 0;
+}
+
 struct rte_eth_dev *
-rte_eth_dev_allocate(void)
+rte_eth_dev_allocate(const char* name)
 {
 	struct rte_eth_dev *eth_dev;
@@ -165,23 +179,37 @@ rte_eth_dev_allocate(void)
 	if (rte_eth_dev_data == NULL)
 		rte_eth_dev_data_alloc();
 
Quoted 7 lines
Quoted 7 lines

lib/librte_eal/common/eal_common_dev.c rte_eth_dev_allocate(void) · line 183

Quoted 2 lines
lib/librte_eal/common/eal_common_dev.c +2 -0
+	if (rte_eth_dev_name_unique(name)) {
+		PMD_DEBUG_TRACE("Ethernet Device with name %s already

allocated!\n");

lib/librte_eal/common/eal_common_dev.c rte_eth_dev_allocate(void) · line 186

Quoted 3 lines
lib/librte_eal/common/eal_common_dev.c +3 -0
+		return NULL;
+	}
+

This seems fairly racy if you allow dynamic device creation at run time from

the

Quoted 3 lines
Quoted 1 line

application, if multiple threads attempt to create bonds in parallel.

True but if this is an issue then there probably should be some locking around

this allocation anyway.
Agreed the allocation of the port id is also racy.

Quoted 5 lines
Quoted 5 lines

Review

Quoted 3 lines
lib/librte_eal/common/eal_common_dev.c +0 -0
 /**
(quoted diff) +0 -0

b/lib/librte_pmd_pcap/rte_eth_pcap.c
Hmm, we're modifying other pmds for the naming feature, I think it would be

best

Quoted 4 lines
Quoted 2 lines

split out into a separate patch. Something entitled "support unique interface naming for virtual pmds" or something.

True, but if I do that, I will need to break support for virtual devices in this patch

set, and

Quoted 1 line

I would prefer to keep this functionality working initial release of link bonding.

Also another

Quoted 1 line

patchset will be required at some point in the near future to tidy up/rationalize

the current

Quoted 9 lines
Quoted 1 line

handling of virtual devices identification and these changes do not change

functionally how

Quoted 1 line

these devices work.

I'm not sure I'm following what you're saying here. If you split this into another patch set, and order earlier in this series, then you won't break anything. I'm not suggesting a functional change here, just a organizational one, so that this change doesn't do more than the changelog indicates.

Sorry I misunderstood, I thought that you where proposing that I create a completely new patchset separate to the link bonding release set for these changes.

Quoted 1 line

Neil

Declan

A message that is not in the archive (sent off-list or not yet received): 345C63BAECC1AD42A2EC8C63AFFC3ADC13D39383-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org

#64 lore raw

Re: [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 122 lines · Declan
Quoted 122 lines

-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Friday, June 13, 2014 8:38 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 55 lines · Declan
Quoted 55 lines

-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Friday, June 13, 2014 5:08 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 8 lines · Declan Doherty

Updating functionality in EAL to support adding link bonding devices via –vdev option. Link bonding devices will be initialized after all physical devices have been probed and initialized.

---
 lib/librte_eal/common/eal_common_dev.c      | 66

+++++++++++++++++++++++++++--

Quoted 11 lines
 lib/librte_eal/common/eal_common_pci.c      |  6 +++
 lib/librte_eal/common/include/eal_private.h |  7 +++
 lib/librte_eal/common/include/rte_dev.h     |  1 +
 lib/librte_ether/rte_ethdev.c               | 34 +++++++++++++--
 lib/librte_ether/rte_ethdev.h               |  7 ++-
 lib/librte_pmd_pcap/rte_eth_pcap.c          | 22 +++++-----
 lib/librte_pmd_ring/rte_eth_ring.c          | 32 +++++++-------
 lib/librte_pmd_ring/rte_eth_ring.h          |  3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |  2 +-
 10 files changed, 144 insertions(+), 36 deletions(-)

Review

Quoted 1 line
(quoted diff) +0 -0

b/lib/librte_eal/common/eal_common_dev.c

Quoted 5 lines

index eae5656..b50c908 100644

lib/librte_eal/common/eal_common_dev.c +0 -0
@@ -75,14 +75,28 @@ rte_eal_dev_init(void)
 

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 84

Quoted 10 lines
lib/librte_eal/common/eal_common_dev.c +2 -1
 	/* call the init function for each virtual device */
 	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		uint8_t bdev = 0;
 
 		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
 			continue;
 
 		TAILQ_FOREACH(driver, &dev_driver_list, next) {
-			if (driver->type != PMD_VDEV)
+			/* RTE_DEVTYPE_VIRTUAL can only be a virtual or bonded

device*/

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 85

Quoted 1 line
lib/librte_eal/common/eal_common_dev.c +1 -0
+			if (driver->type != PMD_VDEV && driver->type !=

PMD_BDEV)

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 90

Quoted 5 lines
lib/librte_eal/common/eal_common_dev.c +3 -0
 				continue;
 
+			/*
+			 * Bonded devices are not initialize here, we do it later in
+			 * rte_eal_bonded_dev_init() after all physical devices

have been

Quoted 12 lines
Quoted 4 lines
Quoted 4 lines
lib/librte_eal/common/eal_common_dev.c +4 -0
+			 * probed and initialized
+			 */
+			if (driver->type == PMD_BDEV &&
+					!strncmp(driver->name, devargs-
Quoted 8 lines

lib/librte_eal/common/eal_common_dev.c rte_eal_dev_init(void) · line 100

Quoted 6 lines
lib/librte_eal/common/eal_common_dev.c +5 -0
 virtual.drv_name,
+							strlen(driver->name))) {
+				bdev = 1;
+				break;
+			}
+

I really don't think you need to add a new device type for bonded devs. Its got no specific hardware that it drives, and you configure it with a --vdev

command,

Quoted 7 lines
Quoted 7 lines

so treat it as one here. I understand that you need to pass additional information about slaves to a bonded device, which is fine, but you can do that with kvargs pretty easily, at which point its just another vdev. The only other requirement is that you initilize the bonded vdev after the slave vdevs have been created, which you can do by any of several methods (a priority field to indicate that bonded drivers should be initilized last/later, a deferral return code from the init routine, or by dead reckoning via the careful construction

of

Quoted 5 lines
Quoted 3 lines

the application command line (placed the bonded --vdev option last on the command line argument list at run time).

It was my initial intent to do as you have describe above, but the physical devices cause a real issue here, physical devices don't call through to

rte_eth_dev_allocate until

Quoted 1 line

during rte_eal_pci_probe call, so it's not possible to initialize the bonded device

from

Quoted 1 line

within rte_eal_dev_init as the physical devices have not been fully initialized at

this

Quoted 1 line

point, as a port_id has not been allocated and can't be added as bonding slaves. I

don't

Quoted 1 line

see away around this without changing the EAL API, which I've tried to avoid with

this solution.

Quoted 2 lines

Ordering isn't an issue, and can easily be solved if the above problem didn't

exist, and although

Quoted 1 line

a new device type isn't technically required, I think it's a cleaner solution than

doing

Quoted 2 lines

string comparisons.

Ugh, you're right. That stinks. We still shouldn't just drop the init code in with the pci probe code though, especially if dpdk starts supporting more stacked network devices. A notification system for interface creation that you could monitor for pci_device addresses (B:D:F tupples) would be nice, but might be overkill since dpdk doesn't really support device freeing yet. what might be useful is a generic ordering mechanism for rte_eal_dev_init. If you added a priority field to the rte_driver structure, you could create an enumeration for the field to define when the init routine for that driver was called something like:

typdef enum {
	PMD_INIT_FIRST = 0,
	PMD_INIT_POST_PROBE = 1,
}
Quoted 8 lines
Quoted 6 lines

Then you could make multiple calls to rte_eal_dev_init from rte_eal_init at the appropriate places in the initalization process, each time passing one of the above values. rte_eal_dev_init would only initalize those drivers whos priority matched the passed in priority. That would be helpful for interfaces like vlans, vxlans, tunnels, etc.

I'm not sure I understand how you intend this to work, are you proposing that rte_eal_dev_init is call multiple times by the user pre and post rte_eal_pci_probe

Mostly, I'm proposing that rte_eal_pci_probe be called by rte_eal_init, and that we then call rte_eal_dev_init multiple times from within rte_eal_dev_init, passing a parameter to indicate the priority level of device that should be initalized within that call.

Quoted 6 lines

this doesn't seem like an idea solution either. I'm not 100% clear why rte_eal_pci_probe is currently called by the application code and not initiated
from within rte_eal_dev_init, if this was the case we would be able to figure out
a dependency tree for initialization of devices, based on the parsed input arguments without having extra user input to or multiple calls of rte_eal_dev_init.

I agree, I think you should move it into its proper place within rte_eal_init, though I think multiple calls to rte_eal_dev_init is perfectly acceptible in this scenario. You certainly could parse the command line to build a dependency tree if you wish, though I don't think thats crruently overly complex. The current dependency tree is static at (physical devices, virtual devices, probe, stacked devices). If you need something more complex later, you can re-write it freely as it will be an internal library mechanism with no external visibility.

Quoted 8 lines

Either way I don't think that any of these solution are trivial and they would need to be thoroughly tested, which I don't think will be possible in the time frame for 1.7. If my current implementation calling rte_eal_bonded_dev_init from within rte_eal_pci_probe is unacceptable, then I propose that I remove the EAL changes for --vdev initialization of bonding devices from this release and only support the C API, and that an overall strategy is discussed for static device
initialization that is developed for 1.7.1 or 1.8.

I would assert that if you can't write the pmd to support the existing pmd interfaces, then this probably needs to wait until 1.8. I'll bow to consensus on that, but I would think that, if it gets in now, the additional work won't happen.

Neil

Quoted 69 lines
Quoted 53 lines
Quoted 24 lines
Quoted 24 lines
Quoted 24 lines
lib/librte_eal/common/eal_common_dev.c +14 -1
+static int
+rte_eth_dev_name_unique(const char* name)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_ports; i++) {
+		if (strcmp(rte_eth_devices[i].data->name, name) == 0)
+			return -1;
+	}
+
+	return 0;
+}
+
 struct rte_eth_dev *
-rte_eth_dev_allocate(void)
+rte_eth_dev_allocate(const char* name)
 {
 	struct rte_eth_dev *eth_dev;
@@ -165,23 +179,37 @@ rte_eth_dev_allocate(void)
 	if (rte_eth_dev_data == NULL)
 		rte_eth_dev_data_alloc();
 
Quoted 7 lines
Quoted 7 lines

lib/librte_eal/common/eal_common_dev.c rte_eth_dev_allocate(void) · line 183

Quoted 2 lines
lib/librte_eal/common/eal_common_dev.c +2 -0
+	if (rte_eth_dev_name_unique(name)) {
+		PMD_DEBUG_TRACE("Ethernet Device with name %s already

allocated!\n");

lib/librte_eal/common/eal_common_dev.c rte_eth_dev_allocate(void) · line 186

Quoted 3 lines
lib/librte_eal/common/eal_common_dev.c +3 -0
+		return NULL;
+	}
+

This seems fairly racy if you allow dynamic device creation at run time from

the

Quoted 3 lines
Quoted 1 line

application, if multiple threads attempt to create bonds in parallel.

True but if this is an issue then there probably should be some locking around

this allocation anyway.
Agreed the allocation of the port id is also racy.

Quoted 5 lines
Quoted 5 lines

Review

Quoted 3 lines
lib/librte_eal/common/eal_common_dev.c +0 -0
 /**
(quoted diff) +0 -0

b/lib/librte_pmd_pcap/rte_eth_pcap.c
Hmm, we're modifying other pmds for the naming feature, I think it would be

best

Quoted 4 lines
Quoted 2 lines

split out into a separate patch. Something entitled "support unique interface naming for virtual pmds" or something.

True, but if I do that, I will need to break support for virtual devices in this patch

set, and

Quoted 1 line

I would prefer to keep this functionality working initial release of link bonding.

Also another

Quoted 1 line

patchset will be required at some point in the near future to tidy up/rationalize

the current

Quoted 9 lines
Quoted 1 line

handling of virtual devices identification and these changes do not change

functionally how

Quoted 1 line

these devices work.

I'm not sure I'm following what you're saying here. If you split this into another patch set, and order earlier in this series, then you won't break anything. I'm not suggesting a functional change here, just a organizational one, so that this change doesn't do more than the changelog indicates.

Sorry I misunderstood, I thought that you where proposing that I create a completely new patchset separate to the link bonding release set for these changes.

Quoted 1 line

Neil

Declan

A message that is not in the archive (sent off-list or not yet received): 20140616110758.GA15165-B26myB8xz7F8NnZeBjwnZQMhkBWG/[email protected]

#66 lore raw

Re: [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 3 lines

-----Original Message-----

<...snip...>

Quoted 8 lines
Quoted 3 lines

this doesn't seem like an idea solution either. I'm not 100% clear why rte_eal_pci_probe is currently called by the application code and not initiated
from within rte_eal_dev_init, if this was the case we would be able to figure

out

Quoted 2 lines

a dependency tree for initialization of devices, based on the parsed input arguments without having extra user input to or multiple calls of

rte_eal_dev_init.

Quoted 1 line
Quoted 8 lines

I agree, I think you should move it into its proper place within rte_eal_init, though I think multiple calls to rte_eal_dev_init is perfectly acceptible in this scenario. You certainly could parse the command line to build a dependency tree if you wish, though I don't think thats crruently overly complex. The current dependency tree is static at (physical devices, virtual devices, probe, stacked devices). If you need something more complex later, you can re-write it freely as it will be an internal library mechanism with no external visibility.

How useful is this going to be? The more complicated the ethdev stacking being done, the better suited it is to being done via the C APIs, via code which can do analysis of the hardware and cores at runtime and make logical decisions? After all, even if we do have applications being run to use bonded devices at runtime in place of physical ones, the bonded devices don't actually replace the physical ones, so some other application logic is needed to ensure that the application knows to only use the bonded devices. In most cases simply having a port-mask suffices, but not all apps will have a port-mask parameter, and for those that do, it introduces complexity for the user counting out interfaces and trying to work out what ports will have what numbers to set the appropriate bits in the portmask.

A message that is not in the archive (sent off-list or not yet received): 59AF69C657FD0841A61C55336867B5B01AA368CE-kPTMFJFq+rELt2AQoY/[email protected]

#68 lore raw

Re: [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 21 lines · Bruce
Quoted 3 lines

-----Original Message-----

<...snip...>

Quoted 8 lines
Quoted 3 lines

this doesn't seem like an idea solution either. I'm not 100% clear why rte_eal_pci_probe is currently called by the application code and not initiated
from within rte_eal_dev_init, if this was the case we would be able to figure

out

Quoted 2 lines

a dependency tree for initialization of devices, based on the parsed input arguments without having extra user input to or multiple calls of

rte_eal_dev_init.

Quoted 1 line
Quoted 8 lines

I agree, I think you should move it into its proper place within rte_eal_init, though I think multiple calls to rte_eal_dev_init is perfectly acceptible in this scenario. You certainly could parse the command line to build a dependency tree if you wish, though I don't think thats crruently overly complex. The current dependency tree is static at (physical devices, virtual devices, probe, stacked devices). If you need something more complex later, you can re-write it freely as it will be an internal library mechanism with no external visibility.

Quoted 1 line

How useful is this going to be? The more complicated the ethdev stacking being done, the better suited it is to being done via the C APIs, via code which can do analysis of the hardware and cores at runtime and make logical decisions? After all, even if we do have applications being run to use bonded devices at runtime in place of physical ones, the bonded devices don't actually replace the physical ones, so some other application logic is needed to ensure that the application knows to only use the bonded devices. In most cases simply having a port-mask suffices, but not all apps will have a port-mask parameter, and for those that do, it introduces complexity for the user counting out interfaces and trying to work out what ports will have what numbers to set the appropriate bits in the p

ortmask.

Honestly? I don't know. As Stephen indicates the command line options might not be overly used, as its not always the best interface to select when building an application. But by the same token, not everyone is building an application that needs dynamic configuration with DPDK. My main concern here is one of consistency, which is really what people look for in a package within a distribution (i.e. Fedora, what I'm doing with the dpdk right now). You're probably correct in that lots of people will use the C api to build bonded interfaces since its a new api and they won't have been using bonds yet. But I'm concerned that, with a distributed package, lots of people might also be porting legacy applications to use the DPDK, in which case they may very well want to create static configurations within the dpdk to lower their porting efforts. Those people may well be very turned off by the fact that some, but not all interfaces can use the command line to be configured.

In the end, its all about consistency in my mind. I get that the --vdev command line parameter perhaps isn't the most useful interface available, but its whats there. And if you start creating PMD's that use separate configuration interfaces and abandon the ones before it, you'll wind up with a hodgepodge of apis, all of which an application will have to be aware of to provide a full robust feature set.

If --vdev stays, we should make it work for all the PMD's. Most might not use it, but some will, and those that do will appreciate the consistency you provide. If it just doesn't make sense to keep it around anymore, lets drop it and replace it with something better. Perhaps a configuration file interface would be good, so that the initialization of the pmds and the creation of interfaces is separated from the acutal application (thats actually a good idea I think, as it implies that all an application needs to know about is interfaces, not how they are constructed or stacked). But lets not just quietly start abandoning stuff because its inconvienient.

Neil

A message that is not in the archive (sent off-list or not yet received): 20140616174746.GC15165-B26myB8xz7F8NnZeBjwnZQMhkBWG/[email protected]

#70 lore raw

Re: [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 68 lines

-----Original Message-----
From: Neil Horman [mailto:[email protected]]
Sent: Monday, June 16, 2014 10:48 AM
To: Richardson, Bruce
Cc: Doherty, Declan; [email protected]
Subject: Re: [dpdk-dev] [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 6 lines · Bruce
Quoted 3 lines

-----Original Message-----

<...snip...>

Quoted 2 lines
Quoted 2 lines

this doesn't seem like an idea solution either. I'm not 100% clear why rte_eal_pci_probe is currently called by the application code and not

initiated

Quoted 1 line
Quoted 1 line
Quoted 1 line

from within rte_eal_dev_init, if this was the case we would be able to

figure

Quoted 8 lines
Quoted 8 lines

out

Quoted 2 lines

a dependency tree for initialization of devices, based on the parsed input arguments without having extra user input to or multiple calls of

rte_eal_dev_init.

Quoted 1 line

I agree, I think you should move it into its proper place within rte_eal_init, though I think multiple calls to rte_eal_dev_init is perfectly acceptible in this scenario. You certainly could parse the command line to build a

dependency

Quoted 1 line
Quoted 1 line

tree if you wish, though I don't think thats crruently overly complex. The

current

Quoted 2 lines
Quoted 2 lines

dependency tree is static at (physical devices, virtual devices, probe, stacked devices). If you need something more complex later, you can re-write it

freely

Quoted 4 lines
Quoted 2 lines

as it will be an internal library mechanism with no external visibility.

How useful is this going to be? The more complicated the ethdev stacking

being done, the better suited it is to being done via the C APIs, via code which can do analysis of the hardware and cores at runtime and make logical decisions? After all, even if we do have applications being run to use bonded devices at runtime in place of physical ones, the bonded devices don't actually replace the physical ones, so some other application logic is needed to ensure that the application knows to only use the bonded devices. In most cases simply having a port-mask suffices, but not all apps will have a port-mask parameter, and for those that do, it introduces complexity for the user counting out interfaces and trying to work out what ports will have what numbers to set the appropriate bits in the portmask.

Honestly? I don't know. As Stephen indicates the command line options might not be overly used, as its not always the best interface to select when building an application. But by the same token, not everyone is building an application that needs dynamic configuration with DPDK. My main concern here is one of consistency, which is really what people look for in a package within a distribution (i.e. Fedora, what I'm doing with the dpdk right now). You're probably correct in that lots of people will use the C api to build bonded interfaces since its a new api and they won't have been using bonds yet. But I'm concerned that, with a distributed package, lots of people might also be porting legacy applications to use the DPDK, in which case they may very well want to create static configurations within the dpdk to lower their porting efforts. Those people may well be very turned off by the fact that some, but not all interfaces can use the command line to be configured.

In the end, its all about consistency in my mind. I get that the --vdev command line parameter perhaps isn't the most useful interface available, but its whats there. And if you start creating PMD's that use separate configuration interfaces and abandon the ones before it, you'll wind up with a hodgepodge of apis, all of which an application will have to be aware of to provide a full robust feature set.

Quoted 10 lines

If --vdev stays, we should make it work for all the PMD's. Most might not use it, but some will, and those that do will appreciate the consistency you provide. If it just doesn't make sense to keep it around anymore, lets drop it and replace it with something better. Perhaps a configuration file interface would be good, so that the initialization of the pmds and the creation of interfaces is separated from the acutal application (thats actually a good idea I think, as it implies that all an application needs to know about is interfaces, not how they are constructed or stacked). But lets not just quietly start abandoning stuff because its inconvienient.

The config file idea is one that's probably worth considering for the future.

The thing about the vpmd option the assumption that all PMDs are equal. It works well for creating pseudo-physical ethdevs, such as pcap, raw-socket or ring or other similar ethdevs, but I'm not sure it's a good abstraction for higher level functionality that we want to expose via an ethdev interface. However, what to do for all these is not a decision we need to make for 1.7 :-)

#71 lore raw

Re: [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

In reply to a message not in the archive

2014-06-16 13:47, Neil Horman:

Quoted 1 line

But lets not just quietly start abandoning stuff because its inconvienient.

Fully agree. The minimum is to have "TODO" comments.
And please, don't consider existing API as a reference.
We must build a convenient and robust API, and probably break the existing one in many areas. The command line could be also reworked.

Thanks for your efforts

Signature · 1 line
Thomas
#72 lore raw

Re: [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

In reply to a message not in the archive
Quoted 6 lines · On Fri, 13 Jun 2014 15:41:59 +0100 Declan Doherty…

Updating functionality in EAL to support adding link bonding devices via –vdev option. Link bonding devices will be initialized after all physical devices have been probed and initialized.

The DPDK is used by both static (demo style) applications and dynamic applications that need to be able to modify parameters while running. The tendency of the code has been to have values that can only be set at initialization, and this kind of inflexibility is hard to fix.

The whole dev args style of configuration is a poor design for those reasons. How do you support creating additional bond devices at runtime?

Remember what works for a demo doesn't make a good API for real world.

A message that is not in the archive (sent off-list or not yet received): 20140613145918.5faebfde-We1ePj4FEcvRI77zikRAJc56i+j3xesD0e7PPNI6Mm0@public.gmane.org

#74 lore raw

Re: [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 23 lines

-----Original Message-----
From: Stephen Hemminger [mailto:[email protected]]
Sent: Friday, June 13, 2014 10:59 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v3 2/5] Link Bonding PMD Library (librte_eal/librte_ether link bonding support changes)

Quoted 6 lines · On Fri, 13 Jun 2014 15:41:59 +0100 Declan Doherty <[email protected]>…

Updating functionality in EAL to support adding link bonding devices via –vdev option. Link bonding devices will be initialized after all physical devices have been probed and initialized.

The DPDK is used by both static (demo style) applications and dynamic applications that need to be able to modify parameters while running. The tendency of the code has been to have values that can only be set at initialization, and this kind of inflexibility is hard to fix.

Quoted 6 lines

The whole dev args style of configuration is a poor design for those reasons. How do you support creating additional bond devices at runtime?

Remember what works for a demo doesn't make a good API for real world.

Hi Stephen,

I totally agree but all of the dev argument parsing / static initialization here is based on the rte_eth_bond.h public API. Actually testpmd has full support for dynamic initialization and management of bonding devices in run-time through the interactive command line options which pretty much have options corresponding to all of the public link bonding APIs.

It is my intent that this would main interface that this API would be used by user applications and that the static configuration options using --vdev interface would only be used if a user wanted to use a bonded device in a existing application without having to make any changes to their code or add any explicit reference to the link bonding library.

#75 lore raw

PATCH v3 3/5 Link Bonding PMD Library (Unit Test Suite)

In reply to a message not in the archive

Link bonding unit tests, including:
- code to generate packet bursts for testing rx and tx functionality of bonded device
- virtual/stubbed out ethdev for use as slave ethdev in testing

---
 app/test/Makefile                 |    4 +-
 app/test/commands.c               |    7 +
 app/test/packet_burst_generator.c |  288 +++
 app/test/packet_burst_generator.h |   78 +
 app/test/test.h                   |    1 +
 app/test/test_link_bonding.c      | 3958 +++++++++++++++++++++++++++++++++++++
 app/test/virtual_pmd.c            |  574 ++++++
 app/test/virtual_pmd.h            |   74 +
 8 files changed, 4983 insertions(+), 1 deletion(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
app/test/Makefile +3 -1
index 3b050c3..02eff0f 100644
@@ -96,7 +96,9 @@ SRCS-$(CONFIG_RTE_APP_TEST) += test_ivshmem.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_distributor.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_distributor_perf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_devargs.c
-
+SRCS-$(CONFIG_RTE_APP_TEST) += virtual_pmd.c
+SRCS-$(CONFIG_RTE_APP_TEST) += packet_burst_generator.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_link_bonding.c
 ifeq ($(CONFIG_RTE_APP_TEST),y)
 SRCS-$(CONFIG_RTE_LIBRTE_ACL) += test_acl.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring.c
app/test/commands.c +7 -0
index 016410d..c31389d 100644
@@ -157,6 +157,10 @@ static void cmd_autotest_parsed(void *parsed_result,
 		ret = test_timer();
 	if (!strcmp(res->autotest, "timer_perf_autotest"))
 		ret = test_timer_perf();
+#ifdef RTE_LIBRTE_PMD_BOND
+	if (!strcmp(res->autotest, "link_bonding_autotest"))
+		ret = test_link_bonding();
+#endif
 	if (!strcmp(res->autotest, "mempool_autotest"))
 		ret = test_mempool();
 	if (!strcmp(res->autotest, "mempool_perf_autotest"))
@@ -225,6 +229,9 @@ cmdline_parse_token_string_t cmd_autotest_autotest =
 			"alarm_autotest#interrupt_autotest#"
 			"version_autotest#eal_fs_autotest#"
 			"cmdline_autotest#func_reentrancy_autotest#"
+#ifdef RTE_LIBRTE_PMD_BOND
+			"link_bonding_autotest#"
+#endif
 			"mempool_perf_autotest#hash_perf_autotest#"
 			"memcpy_perf_autotest#ring_perf_autotest#"
 			"red_autotest#meter_autotest#sched_autotest#"
app/test/packet_burst_generator.c new file +288 -0

288 lines not on this page · raw message

app/test/packet_burst_generator.h new file +78 -0

78 lines not on this page · raw message

app/test/test.h +1 -0
index f992ceb..574841b 100644
@@ -96,6 +96,7 @@ int test_distributor(void);
 int test_distributor_perf(void);
 int test_kvargs(void);
 int test_devargs(void);
+int test_link_bonding(void);
 
 int test_pci_run;
 
app/test/test_link_bonding.c new file +3958 -0

2,598 lines not on this page · raw message

app/test/virtual_pmd.c new file +574 -0

574 lines not on this page · raw message

app/test/virtual_pmd.h new file +74 -0

74 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.8.5.3

Part of the diff is not shown here. View the raw message.

#76 lore raw

PATCH v3 4/5 Link Bonding PMD Library (testpmd link bonding API support)

In reply to a message not in the archive

Adding link bonding support to testpmd.
- Includes the ability to create new bonded devices.
- Add /remove bonding slave devices.
- Interogate bonded device stats/configuration
- Change bonding modes and select balance transmit polices

---
 app/test-pmd/cmdline.c    | 571 ++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/config.c     |   4 +-
 app/test-pmd/parameters.c |   3 +
 app/test-pmd/testpmd.c    |  37 ++-
 app/test-pmd/testpmd.h    |   2 +
 5 files changed, 611 insertions(+), 6 deletions(-)
app/test-pmd/cmdline.c +571 -0
index 4678977..fd220e7 100644
@@ -84,6 +84,9 @@
 #include <cmdline_socket.h>
 #include <cmdline.h>
 #include <rte_pci_dev_ids.h>
+#ifdef RTE_LIBRTE_PMD_BOND
+#include <rte_eth_bond.h>
+#endif
 
 #include "testpmd.h"
 
@@ -400,6 +403,31 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"   Show the bypass configuration for a bypass enabled NIC"
 			" using the lowest port on the NIC.\n\n"
 #endif
+#ifdef RTE_LIBRTE_PMD_BOND
+			"create bonded device (mode) (socket)\n"
+			"	Create a new bonded device with specific bonding mode and socket.\n\n"
+
+			"add bonding slave (slave_id) (port_id)\n"
+			"	Add a slave device to a bonded device.\n\n"
+
+			"remove bonding slave (slave_id) (port_id)\n"
+			"	Remove a slave device from a bonded device.\n\n"
+
+			"set bonding mode (value) (port_id)\n"
+			"	Set the bonding mode on a bonded device.\n\n"
+
+			"set bonding primary (slave_id) (port_id)\n"
+			"	Set the primary slave for a bonded device.\n\n"
+
+			"show bonding config (port_id)\n"
+			"	Show the bonding config for port_id.\n\n"
+
+			"set bonding mac_addr (port_id) (address)\n"
+			"	Set the MAC address of a bonded device.\n\n"
+
+			"set bonding xmit_balance_policy (port_id) (l2|l23|l34)\n"
+			"	Set the transmit balance policy for bonded device running in balance mode.\n\n"
+#endif
 
 			, list_pkt_forwarding_modes()
 		);
@@ -2856,6 +2884,539 @@ cmdline_parse_inst_t cmd_show_bypass_config = {
 };
 #endif
 
+#ifdef RTE_LIBRTE_PMD_BOND
+/* *** SET BONDING MODE *** */
+struct cmd_set_bonding_mode_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t mode;
+	uint8_t value;
+	uint8_t port_id;
+};
+
+static void cmd_set_bonding_mode_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_mode_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+
+	/* Set the bonding mode for the relevant port. */
+	if (0 != rte_eth_bond_mode_set(port_id, res->value))
+		printf("\t Failed to set bonding mode for port = %d.\n", port_id);
+}
+
+cmdline_parse_token_string_t cmd_setbonding_mode_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_mode_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_mode_mode =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		mode, "mode");
+cmdline_parse_token_num_t cmd_setbonding_mode_value =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+		value, UINT8);
+cmdline_parse_token_num_t cmd_setbonding_mode_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bonding_mode = {
+		.f = cmd_set_bonding_mode_parsed,
+		.help_str = "set bonding mode (mode_value) (port_id): Set the bonding mode for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *) &cmd_setbonding_mode_set,
+				(void *) &cmd_setbonding_mode_bonding,
+				(void *) &cmd_setbonding_mode_mode,
+				(void *) &cmd_setbonding_mode_value,
+				(void *) &cmd_setbonding_mode_port,
+				NULL
+		}
+};
+
+/* *** SET BALANCE XMIT POLICY *** */
+struct cmd_set_bonding_balance_xmit_policy_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t balance_xmit_policy;
+	uint8_t port_id;
+	cmdline_fixed_string_t policy;
+};
+
+static void cmd_set_bonding_balance_xmit_policy_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_balance_xmit_policy_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+	uint8_t policy;
+
+	if (!strcmp(res->policy, "l2")) {
+		policy = BALANCE_XMIT_POLICY_LAYER2;
+	} else if (!strcmp(res->policy, "l23")) {
+		policy = BALANCE_XMIT_POLICY_LAYER23;
+	} else if (!strcmp(res->policy, "l34")) {
+		policy = BALANCE_XMIT_POLICY_LAYER34;
+	} else {
+		printf("\t Invalid xmit policy selection");
+		return;
+	}
+
+	/* Set the bonding mode for the relevant port. */
+	if (0 != rte_eth_bond_xmit_policy_set(port_id, policy)) {
+		printf("\t Failed to set bonding balance xmit policy for port = %d.\n",
+				port_id);
+	}
+}
+
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_balance_xmit_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		balance_xmit_policy, "balance_xmit_policy");
+cmdline_parse_token_num_t cmd_setbonding_balance_xmit_policy_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		port_id, UINT8);
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		policy, "l2#l23#l34");
+
+cmdline_parse_inst_t cmd_set_balance_xmit_policy = {
+		.f = cmd_set_bonding_balance_xmit_policy_parsed,
+		.help_str = "set bonding balance_xmit_policy (port_id) (policy_value): Set the bonding balance_xmit_policy for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_setbonding_balance_xmit_policy_set,
+				(void *)&cmd_setbonding_balance_xmit_policy_bonding,
+				(void *)&cmd_setbonding_balance_xmit_policy_balance_xmit_policy,
+				(void *)&cmd_setbonding_balance_xmit_policy_port,
+				(void *)&cmd_setbonding_balance_xmit_policy_policy,
+				NULL
+		}
+};
+
+/* *** SHOW NIC BONDING CONFIGURATION *** */
+struct cmd_show_bonding_config_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+};
+
+static void cmd_show_bonding_config_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_show_bonding_config_result *res = parsed_result;
+	int bonding_mode;
+	uint8_t slaves[RTE_MAX_ETHPORTS];
+	int num_slaves, num_active_slaves;
+	int primary_id;
+	int i;
+	portid_t port_id = res->port_id;
+
+	/* Display the bonding mode.*/
+	bonding_mode = rte_eth_bond_mode_get(port_id);
+	if (bonding_mode < 0) {
+		printf("\tFailed to get bonding mode for port = %d\n", port_id);
+		return;
+	} else
+		printf("\tBonding mode: %d\n", bonding_mode);
+
+	if (bonding_mode == BONDING_MODE_BALANCE) {
+		int balance_xmit_policy;
+
+		balance_xmit_policy = rte_eth_bond_xmit_policy_get(port_id);
+		if (balance_xmit_policy < 0) {
+			printf("\tFailed to get balance xmit policy for port = %d\n",
+					port_id);
+			return;
+		} else {
+			printf("\tBalance Xmit Policy: ");
+
+			switch (balance_xmit_policy) {
+			case BALANCE_XMIT_POLICY_LAYER2:
+				printf("BALANCE_XMIT_POLICY_LAYER2");
+				break;
+			case BALANCE_XMIT_POLICY_LAYER23:
+				printf("BALANCE_XMIT_POLICY_LAYER23");
+				break;
+			case BALANCE_XMIT_POLICY_LAYER34:
+				printf("BALANCE_XMIT_POLICY_LAYER34");
+				break;
+			}
+			printf("\n");
+		}
+	}
+
+	num_slaves = rte_eth_bond_slaves_get(port_id, slaves, RTE_MAX_ETHPORTS);
+
+	if (num_slaves < 0) {
+		printf("\tFailed to get slave list for port = %d\n", port_id);
+		return;
+	}
+	if (num_slaves > 0) {
+		printf("\tSlaves (%d): [", num_slaves);
+		for (i = 0; i < num_slaves - 1; i++)
+			printf("%d ", slaves[i]);
+
+		printf("%d]\n", slaves[num_slaves - 1]);
+	} else {
+		printf("\tSlaves: []\n");
+
+	}
+
+	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
+			RTE_MAX_ETHPORTS);
+
+	if (num_active_slaves < 0) {
+		printf("\tFailed to get active slave list for port = %d\n", port_id);
+		return;
+	}
+	if (num_active_slaves > 0) {
+		printf("\tActive Slaves (%d): [", num_active_slaves);
+		for (i = 0; i < num_active_slaves - 1; i++)
+			printf("%d ", slaves[i]);
+
+		printf("%d]\n", slaves[num_active_slaves - 1]);
+
+	} else {
+		printf("\tActive Slaves: []\n");
+
+	}
+
+	primary_id = rte_eth_bond_primary_get(port_id);
+	if (primary_id < 0) {
+		printf("\tFailed to get primary slave for port = %d\n", port_id);
+		return;
+	} else
+		printf("\tPrimary: [%d]\n", primary_id);
+
+}
+
+cmdline_parse_token_string_t cmd_showbonding_config_show =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		show, "show");
+cmdline_parse_token_string_t cmd_showbonding_config_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_showbonding_config_config =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		config, "config");
+cmdline_parse_token_num_t cmd_showbonding_config_port =
+TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_config_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_show_bonding_config = {
+		.f = cmd_show_bonding_config_parsed,
+		.help_str =	"show bonding config (port_id): Show the bonding config for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_showbonding_config_show,
+				(void *)&cmd_showbonding_config_bonding,
+				(void *)&cmd_showbonding_config_config,
+				(void *)&cmd_showbonding_config_port,
+				NULL
+		}
+};
+
+/* *** SET BONDING PRIMARY *** */
+struct cmd_set_bonding_primary_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t primary;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_set_bonding_primary_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_primary_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_primary_set(master_port_id, slave_port_id)) {
+		printf("\t Failed to set primary slave for port = %d.\n",
+				master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_setbonding_primary_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_primary_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_primary_primary =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		primary, "primary");
+cmdline_parse_token_num_t cmd_setbonding_primary_slave =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+		slave_id, UINT8);
+cmdline_parse_token_num_t cmd_setbonding_primary_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bonding_primary = {
+		.f = cmd_set_bonding_primary_parsed,
+		.help_str = "set bonding primary (slave_id) (port_id): Set the primary slave for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_setbonding_primary_set,
+				(void *)&cmd_setbonding_primary_bonding,
+				(void *)&cmd_setbonding_primary_primary,
+				(void *)&cmd_setbonding_primary_slave,
+				(void *)&cmd_setbonding_primary_port,
+				NULL
+		}
+};
+
+/* *** ADD SLAVE *** */
+struct cmd_add_bonding_slave_result {
+	cmdline_fixed_string_t add;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t slave;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_add_bonding_slave_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_add_bonding_slave_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_slave_add(master_port_id, slave_port_id)) {
+		printf("\t Failed to add slave %d to master port = %d.\n",
+				slave_port_id, master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_addbonding_slave_add =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		add, "add");
+cmdline_parse_token_string_t cmd_addbonding_slave_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_addbonding_slave_slave =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		slave, "slave");
+cmdline_parse_token_num_t cmd_addbonding_slave_slaveid =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+		slave_id, UINT8);
+cmdline_parse_token_num_t cmd_addbonding_slave_port =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_add_bonding_slave = {
+		.f = cmd_add_bonding_slave_parsed,
+		.help_str = "add bonding slave (slave_id) (port_id): Add a slave device to a bonded device",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_addbonding_slave_add,
+				(void *)&cmd_addbonding_slave_bonding,
+				(void *)&cmd_addbonding_slave_slave,
+				(void *)&cmd_addbonding_slave_slaveid,
+				(void *)&cmd_addbonding_slave_port,
+				NULL
+		}
+};
+
+/* *** REMOVE SLAVE *** */
+struct cmd_remove_bonding_slave_result {
+	cmdline_fixed_string_t remove;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t slave;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_remove_bonding_slave_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_remove_bonding_slave_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_slave_remove(master_port_id, slave_port_id)) {
+		printf("\t Failed to remove slave %d from master port = %d.\n",
+				slave_port_id, master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_removebonding_slave_remove =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				remove, "remove");
+cmdline_parse_token_string_t cmd_removebonding_slave_bonding =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				bonding, "bonding");
+cmdline_parse_token_string_t cmd_removebonding_slave_slave =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				slave, "slave");
+cmdline_parse_token_num_t cmd_removebonding_slave_slaveid =
+		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				slave_id, UINT8);
+cmdline_parse_token_num_t cmd_removebonding_slave_port =
+		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				port_id, UINT8);
+
+cmdline_parse_inst_t cmd_remove_bonding_slave = {
+		.f = cmd_remove_bonding_slave_parsed,
+		.help_str = "remove bonding slave (slave_id) (port_id): Remove a slave device from a bonded device",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_removebonding_slave_remove,
+				(void *)&cmd_removebonding_slave_bonding,
+				(void *)&cmd_removebonding_slave_slave,
+				(void *)&cmd_removebonding_slave_slaveid,
+				(void *)&cmd_removebonding_slave_port,
+				NULL
+		}
+};
+
+/* *** CREATE BONDED DEVICE *** */
+struct cmd_create_bonded_device_result {
+	cmdline_fixed_string_t create;
+	cmdline_fixed_string_t bonded;
+	cmdline_fixed_string_t device;
+	uint8_t mode;
+	uint8_t socket;
+};
+
+static void cmd_create_bonded_device_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_create_bonded_device_result *res = parsed_result;
+
+	int port_id;
+	if (test_done == 0) {
+		printf("Please stop forwarding first\n");
+		return;
+	}
+
+	port_id = rte_eth_bond_create("testpmd-bonded-dev", res->mode, res->socket);
+	/* Create a new bonded device. */
+	if (port_id < 0) {
+		printf("\t Failed to create bonded device.\n");
+		return;
+	} else {
+		printf("\t Created new bonded device (port %d).\n", port_id);
+		/* Update number of ports */
+		nb_ports = rte_eth_dev_count();
+		reconfig(port_id);
+		rte_eth_promiscuous_enable(port_id);
+	}
+
+}
+
+cmdline_parse_token_string_t cmd_createbonded_device_create =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				create, "create");
+cmdline_parse_token_string_t cmd_createbonded_device_bonded =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				bonded, "bonded");
+cmdline_parse_token_string_t cmd_createbonded_device_device =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				device, "device");
+cmdline_parse_token_num_t cmd_createbonded_device_mode =
+		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+				mode, UINT8);
+cmdline_parse_token_num_t cmd_createbonded_device_socket =
+		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+				socket, UINT8);
+
+cmdline_parse_inst_t cmd_create_bonded_device = {
+		.f = cmd_create_bonded_device_parsed,
+		.help_str = "create bonded device (mode) (socket): Create a new bonded device with specific bonding mode and socket",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_createbonded_device_create,
+				(void *)&cmd_createbonded_device_bonded,
+				(void *)&cmd_createbonded_device_device,
+				(void *)&cmd_createbonded_device_mode,
+				(void *)&cmd_createbonded_device_socket,
+				NULL
+		}
+};
+
+/* *** SET MAC ADDRESS IN BONDED DEVICE *** */
+struct cmd_set_bond_mac_addr_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t mac_addr;
+	uint8_t port_num;
+	struct ether_addr address;
+};
+
+static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bond_mac_addr_result *res = parsed_result;
+	int ret;
+
+	if (res->port_num >= nb_ports) {
+		printf("Port id %d must be less than %d\n", res->port_num, nb_ports);
+		return;
+	}
+
+	ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
+
+	/* check the return value and print it if is < 0 */
+	if (ret < 0)
+		printf("set_bond_mac_addr error: (%s)\n", strerror(-ret));
+}
+
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_set =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, set, "set");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, bonding,
+				"bonding");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, mac_addr,
+				"mac_addr");
+cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum =
+		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result, port_num, UINT8);
+cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr =
+		TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result, address);
+
+cmdline_parse_inst_t cmd_set_bond_mac_addr = {
+		.f = cmd_set_bond_mac_addr_parsed,
+		.data = (void *) 0,
+		.help_str = "set bonding mac_addr (port_id) (address): ",
+		.tokens = {
+				(void *)&cmd_set_bond_mac_addr_set,
+				(void *)&cmd_set_bond_mac_addr_bonding,
+				(void *)&cmd_set_bond_mac_addr_mac,
+				(void *)&cmd_set_bond_mac_addr_portnum,
+				(void *)&cmd_set_bond_mac_addr_addr,
+				NULL
+		}
+};
+
+#endif /* RTE_LIBRTE_PMD_BOND */
+
 /* *** SET FORWARDING MODE *** */
 struct cmd_set_fwd_mode_result {
 	cmdline_fixed_string_t set;
@@ -5567,6 +6128,16 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_bypass_timeout,
 	(cmdline_parse_inst_t *)&cmd_show_bypass_config,
 #endif
+#ifdef RTE_LIBRTE_PMD_BOND
+	(cmdline_parse_inst_t *) &cmd_set_bonding_mode,
+	(cmdline_parse_inst_t *) &cmd_show_bonding_config,
+	(cmdline_parse_inst_t *) &cmd_set_bonding_primary,
+	(cmdline_parse_inst_t *) &cmd_add_bonding_slave,
+	(cmdline_parse_inst_t *) &cmd_remove_bonding_slave,
+	(cmdline_parse_inst_t *) &cmd_create_bonded_device,
+	(cmdline_parse_inst_t *) &cmd_set_bond_mac_addr,
+	(cmdline_parse_inst_t *) &cmd_set_balance_xmit_policy,
+#endif
 	(cmdline_parse_inst_t *)&cmd_vlan_offload,
 	(cmdline_parse_inst_t *)&cmd_vlan_tpid,
 	(cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all,
app/test-pmd/config.c +3 -1
index 52ad01a..d1ec1e5 100644
@@ -242,6 +242,7 @@ void
 port_infos_display(portid_t port_id)
 {
 	struct rte_port *port;
+	struct ether_addr mac_addr;
 	struct rte_eth_link link;
 	int vlan_offload;
 	struct rte_mempool * mp;
@@ -255,7 +256,8 @@ port_infos_display(portid_t port_id)
 	rte_eth_link_get_nowait(port_id, &link);
 	printf("\n%s Infos for port %-2d %s\n",
 	       info_border, port_id, info_border);
-	print_ethaddr("MAC address: ", &port->eth_addr);
+	rte_eth_macaddr_get(port_id, &mac_addr);
+	print_ethaddr("MAC address: ", &mac_addr);
 	printf("\nConnect to socket: %u", port->socket_id);
 
 	if (port_numa[port_id] != NUMA_NO_CONFIG) {
app/test-pmd/parameters.c +3 -0
index eb14cd3..63669f5 100644
@@ -75,6 +75,9 @@
 #include <cmdline_parse.h>
 #include <cmdline_parse_etheraddr.h>
 #endif
+#ifdef RTE_LIBRTE_PMD_BOND
+#include <rte_eth_bond.h>
+#endif
 
 #include "testpmd.h"
 
app/test-pmd/testpmd.c +32 -5
index 2529dc3..e3de4ad 100644
@@ -300,7 +300,7 @@ struct rte_fdir_conf fdir_conf = {
 	.drop_queue = 127,
 };
 
-static volatile int test_done = 1; /* stop packet forwarding when set to 1. */
+volatile int test_done = 1; /* stop packet forwarding when set to 1. */
 
 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
@@ -625,6 +625,32 @@ init_config(void)
 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
 }
 
+
+void
+reconfig(portid_t new_port_id)
+{
+	struct rte_port *port;
+
+	/* Reconfiguration of Ethernet ports. */
+	ports = rte_realloc(ports,
+			    sizeof(struct rte_port) * nb_ports,
+			    CACHE_LINE_SIZE);
+	if (ports == NULL) {
+		rte_exit(EXIT_FAILURE, "rte_realloc(%d struct rte_port) failed\n",
+				nb_ports);
+	}
+
+	port = &ports[new_port_id];
+	rte_eth_dev_info_get(new_port_id, &port->dev_info);
+
+	/* set flag to initialize port/queue */
+	port->need_reconfig = 1;
+	port->need_reconfig_queues = 1;
+
+	init_port_config();
+}
+
+
 int
 init_fwd_streams(void)
 {
@@ -1246,7 +1272,7 @@ start_port(portid_t pid)
 	portid_t pi;
 	queueid_t qi;
 	struct rte_port *port;
-	uint8_t *mac_addr;
+	struct ether_addr mac_addr;
 
 	if (test_done == 0) {
 		printf("Please stop forwarding first\n");
@@ -1374,10 +1400,11 @@ start_port(portid_t pid)
 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
 			printf("Port %d can not be set into started\n", pi);
 
-		mac_addr = port->eth_addr.addr_bytes;
+		rte_eth_macaddr_get(pi, &mac_addr);
 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
-		       mac_addr[0], mac_addr[1], mac_addr[2],
-		       mac_addr[3], mac_addr[4], mac_addr[5]);
+				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
+				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
+				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
 
 		/* at least one port started, need checking link status */
 		need_check_link_status = 1;
app/test-pmd/testpmd.h +2 -0
index 4fabf1c..892d39f 100644
@@ -279,6 +279,7 @@ extern uint16_t port_topology; /**< set by "--port-topology" parameter */
 extern uint8_t no_flush_rx; /**<set by "--no-flush-rx" parameter */
 extern uint8_t  mp_anon; /**< set by "--mp-anon" parameter */
 extern uint8_t no_link_check; /**<set by "--disable-link-check" parameter */
+extern volatile int test_done; /* stop packet forwarding when set to 1. */
 
 #ifdef RTE_NIC_BYPASS
 extern uint32_t bypass_timeout; /**< Store the NIC bypass watchdog timeout */
@@ -452,6 +453,7 @@ void fwd_config_display(void);
 void rxtx_config_display(void);
 void fwd_config_setup(void);
 void set_def_fwd_config(void);
+void reconfig(portid_t new_port_id);
 int init_fwd_streams(void);
 
 
Signature · 1 line
1.8.5.3
#77 lore raw

PATCH v3 5/5 Link Bonding PMD Library (Doxygen Additions)

In reply to a message not in the archive
---
 doc/doxy-api-index.md | 1 +
 doc/doxy-api.conf     | 1 +
 2 files changed, 2 insertions(+)
doc/doxy-api-index.md +1 -0
index 6e75a6e..a4d2e57 100644
@@ -36,6 +36,7 @@ API {#index}
 There are many libraries, so their headers may be grouped by topics:
 
 - **device**:
+  [bond]               (@ref rte_eth_bond.h),
   [ethdev]             (@ref rte_ethdev.h),
   [devargs]            (@ref rte_devargs.h),
   [KNI]                (@ref rte_kni.h),
doc/doxy-api.conf +1 -0
index 9df7356..92f8c59 100644
@@ -30,6 +30,7 @@
 
 PROJECT_NAME            = DPDK
 INPUT                   = doc/doxy-api-index.md \
+                          lib/librte_pmd_bond \
                           lib/librte_eal/common/include \
                           lib/librte_distributor \
                           lib/librte_ether \
Signature · 1 line
1.8.5.3

A message that is not in the archive (sent off-list or not yet received): cover.1402662300.git.declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#79 lore raw

Re: [PATCH v3 0/5] Link Bonding PMD Library

Quoted 58 lines · Declan Doherty

This patch contains the initial release of the Link Bonding PMD Library

Supporting bonding modes:
0 - Round Robin
1 - Active Backup
2 - Balance (Supporting 3 transmission polices)

	layer 2, layer 2+3, layer 3+4

3 - Broadcast

Version 3 of this patch set add the following functionality changes
- Link bonding command line option parsing / initialization support
- Unique name identifier to rte_eth_dev_data struct to identify virtual ethdev's which are to be added to bondded device from command line.
- Updates to EAL to support initialization of link bonding devices

Patch Set Description:
0001 - librte_pmd_bond + makefile changes
0002 - librte_eal / librte_ether changes to support bonding device intialization 0003 - link bonding unti test suite
0004 - testpmd link bonding support changes
0005 - doxygen additions

 app/test-pmd/cmdline.c                      |  571 ++++
 app/test-pmd/config.c                       |    4 +-
 app/test-pmd/parameters.c                   |    3 +
 app/test-pmd/testpmd.c                      |   37 +-
 app/test-pmd/testpmd.h                      |    2 +
 app/test/Makefile                           |    4 +-
 app/test/commands.c                         |    7 +
 app/test/packet_burst_generator.c           |  288 ++
 app/test/packet_burst_generator.h           |   78 +
 app/test/test.h                             |    1 +
 app/test/test_link_bonding.c                | 3958 +++++++++++++++++++++++++++
 app/test/virtual_pmd.c                      |  574 ++++
 app/test/virtual_pmd.h                      |   74 +
 config/common_bsdapp                        |    5 +
 config/common_linuxapp                      |    5 +
 doc/doxy-api-index.md                       |    1 +
 doc/doxy-api.conf                           |    1 +
 lib/Makefile                                |    1 +
 lib/librte_eal/common/eal_common_dev.c      |   66 +-
 lib/librte_eal/common/eal_common_pci.c      |    6 +
 lib/librte_eal/common/include/eal_private.h |    7 +
 lib/librte_eal/common/include/rte_dev.h     |    1 +
 lib/librte_ether/rte_ethdev.c               |   34 +-
 lib/librte_ether/rte_ethdev.h               |    7 +-
 lib/librte_pmd_bond/Makefile                |   32 +
 lib/librte_pmd_bond/rte_eth_bond.c          | 2149 +++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond.h          |  255 ++
 lib/librte_pmd_pcap/rte_eth_pcap.c          |   22 +-
 lib/librte_pmd_ring/rte_eth_ring.c          |   32 +-
 lib/librte_pmd_ring/rte_eth_ring.h          |    3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |    2 +-
 mk/rte.app.mk                               |    5 +
 32 files changed, 8192 insertions(+), 43 deletions(-)
Quoted 13 lines
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h
Signature · 1 line
1.8.5.3

This looks alot better, thank you. I've got a few comments in the individual patches, but on the whole, well done!
Neil

#80 lore raw

v4 cover Link Bonding Library

In reply to a message not in the archive

AThis patch contains the initial release of the Link Bonding PMD Library

Supporting bonding modes:
0 - Round Robin
1 - Active Backup
2 - Balance (Supporting 3 transmission polices)

	layer 2, layer 2+3, layer 3+4

3 - Broadcast

Version 4 of patch set:
- Fixes some checkpatch formatting issues
- Splits unique pmd naming and link bonding intialization changes in EAL into separate patches

Patch Set Description:
0001 - librte_pmd_bond + makefile changes
0002 - librte_ether changes to support unique naming of pmds 0003 - librte_eal changes to support bonding device intialization 0005 - link bonding unti test suite
0005 - testpmd link bonding support changes
0006 - doxygen additions

Declan Doherty (6):
Link Bonding Library (lib/librte_pmd_bond) initial release with
support for Mode 0 - Round Robin Mode 1 - Active Backup Mode 2 - Balance -> Supports 3 transmit polices (layer 2, layer 2+3, la Mode 3 - Broadcast
Support for unique interface naming of pmds
EAL support for link bonding device initialization
Link bonding Unit Tests
testpmd link bonding additions
Link Bonding Library doxygen additions

 app/test-pmd/cmdline.c                      |  571 ++++
 app/test-pmd/config.c                       |    4 +-
 app/test-pmd/parameters.c                   |    3 +
 app/test-pmd/testpmd.c                      |   37 +-
 app/test-pmd/testpmd.h                      |    2 +
 app/test/Makefile                           |    4 +-
 app/test/commands.c                         |    7 +
 app/test/packet_burst_generator.c           |  288 ++
 app/test/packet_burst_generator.h           |   78 +
 app/test/test.h                             |    1 +
 app/test/test_link_bonding.c                | 3958 +++++++++++++++++++++++++++
 app/test/virtual_pmd.c                      |  574 ++++
 app/test/virtual_pmd.h                      |   74 +
 config/common_bsdapp                        |    5 +
 config/common_linuxapp                      |    5 +
 doc/doxy-api-index.md                       |    1 +
 doc/doxy-api.conf                           |    1 +
 lib/Makefile                                |    1 +
 lib/librte_eal/common/eal_common_dev.c      |   66 +-
 lib/librte_eal/common/eal_common_pci.c      |    6 +
 lib/librte_eal/common/include/eal_private.h |    7 +
 lib/librte_eal/common/include/rte_dev.h     |    1 +
 lib/librte_ether/rte_ethdev.c               |   33 +-
 lib/librte_ether/rte_ethdev.h               |    7 +-
 lib/librte_pmd_bond/Makefile                |   32 +
 lib/librte_pmd_bond/rte_eth_bond.c          | 2149 +++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond.h          |  255 ++
 lib/librte_pmd_pcap/rte_eth_pcap.c          |   22 +-
 lib/librte_pmd_ring/rte_eth_ring.c          |   32 +-
 lib/librte_pmd_ring/rte_eth_ring.h          |    3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |    2 +-
 mk/rte.app.mk                               |    5 +
 32 files changed, 8191 insertions(+), 43 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h

A message that is not in the archive (sent off-list or not yet received): 1402917513-19495-1-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#82 lore raw

v5 cover Link Bonding Library

This patch contains the initial release of the Link Bonding PMD Library

Supporting bonding modes:
0 - Round Robin
1 - Active Backup
2 - Balance (Supporting 3 transmission polices)

	layer 2, layer 2+3, layer 3+4

3 - Broadcast

Version 5 of patch set:
Contains changes to EAL code to allow initialisation of Bonded devices from application startup options. rte_eal_init now calls rte_eal_pci_probe between calling rte_eal_dev_init with PRE and POST PCI probe flags. This gets around polluting the eal pci code with references to link bonding devices. Also rte_eal_pci_probe can now be called multiple times and will not try to re-initialize the driver if one already exists, this means that existing applications which currently call rte_eal_pci_probe will not be affected by this change

Patch Set Description:
0001 - librte_pmd_bond + makefile changes
0002 - librte_ether changes to support unique naming of pmds 0003 - librte_eal changes to support bonding device intialization 0005 - link bonding unti test suite
0005 - testpmd link bonding support changes
0006 - doxygen additions

Declan Doherty (6):
Link Bonding Library (lib/librte_pmd_bond) Support for unique interface naming of pmds EAL support for link bonding device initialization Link bonding Unit Tests
testpmd link bonding additions
Link Bonding Library doxygen additions

 app/test-pmd/cmdline.c                      |  579 ++++
 app/test-pmd/config.c                       |    4 +-
 app/test-pmd/parameters.c                   |    3 +
 app/test-pmd/testpmd.c                      |   40 +-
 app/test-pmd/testpmd.h                      |    2 +
 app/test/Makefile                           |    4 +-
 app/test/commands.c                         |    7 +
 app/test/packet_burst_generator.c           |  287 ++
 app/test/packet_burst_generator.h           |   78 +
 app/test/test.h                             |    1 +
 app/test/test_link_bonding.c                | 3958 +++++++++++++++++++++++++++
 app/test/virtual_pmd.c                      |  574 ++++
 app/test/virtual_pmd.h                      |   74 +
 config/common_bsdapp                        |    5 +
 config/common_linuxapp                      |    5 +
 doc/doxy-api-index.md                       |    1 +
 doc/doxy-api.conf                           |    1 +
 lib/Makefile                                |    1 +
 lib/librte_eal/bsdapp/eal/eal.c             |   10 +-
 lib/librte_eal/common/eal_common_dev.c      |   58 +-
 lib/librte_eal/common/eal_common_pci.c      |    3 +
 lib/librte_eal/common/include/eal_private.h |    7 -
 lib/librte_eal/common/include/rte_dev.h     |   13 +-
 lib/librte_eal/linuxapp/eal/eal.c           |   11 +-
 lib/librte_ether/rte_ethdev.c               |   32 +-
 lib/librte_ether/rte_ethdev.h               |    7 +-
 lib/librte_pmd_bond/Makefile                |   32 +
 lib/librte_pmd_bond/rte_eth_bond.c          | 2148 +++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond.h          |  255 ++
 lib/librte_pmd_pcap/rte_eth_pcap.c          |   22 +-
 lib/librte_pmd_ring/rte_eth_ring.c          |   32 +-
 lib/librte_pmd_ring/rte_eth_ring.h          |    3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |    2 +-
 mk/rte.app.mk                               |    5 +
 34 files changed, 8193 insertions(+), 71 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h

A message that is not in the archive (sent off-list or not yet received): 1403108063-27169-1-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

Acked-by
#84 lore raw
Quoted 72 lines · Declan Doherty

This patch contains the initial release of the Link Bonding PMD Library

Supporting bonding modes:
0 - Round Robin
1 - Active Backup
2 - Balance (Supporting 3 transmission polices)

	layer 2, layer 2+3, layer 3+4

3 - Broadcast

Version 5 of patch set:
Contains changes to EAL code to allow initialisation of Bonded devices from application startup options. rte_eal_init now calls rte_eal_pci_probe between calling rte_eal_dev_init with PRE and POST PCI probe flags. This gets around polluting the eal pci code with references to link bonding devices. Also rte_eal_pci_probe can now be called multiple times and will not try to re-initialize the driver if one already exists, this means that existing applications which currently call rte_eal_pci_probe will not be affected by this change

Patch Set Description:
0001 - librte_pmd_bond + makefile changes
0002 - librte_ether changes to support unique naming of pmds 0003 - librte_eal changes to support bonding device intialization 0005 - link bonding unti test suite
0005 - testpmd link bonding support changes
0006 - doxygen additions

Declan Doherty (6):
Link Bonding Library (lib/librte_pmd_bond) Support for unique interface naming of pmds EAL support for link bonding device initialization Link bonding Unit Tests
testpmd link bonding additions
Link Bonding Library doxygen additions

 app/test-pmd/cmdline.c                      |  579 ++++
 app/test-pmd/config.c                       |    4 +-
 app/test-pmd/parameters.c                   |    3 +
 app/test-pmd/testpmd.c                      |   40 +-
 app/test-pmd/testpmd.h                      |    2 +
 app/test/Makefile                           |    4 +-
 app/test/commands.c                         |    7 +
 app/test/packet_burst_generator.c           |  287 ++
 app/test/packet_burst_generator.h           |   78 +
 app/test/test.h                             |    1 +
 app/test/test_link_bonding.c                | 3958 +++++++++++++++++++++++++++
 app/test/virtual_pmd.c                      |  574 ++++
 app/test/virtual_pmd.h                      |   74 +
 config/common_bsdapp                        |    5 +
 config/common_linuxapp                      |    5 +
 doc/doxy-api-index.md                       |    1 +
 doc/doxy-api.conf                           |    1 +
 lib/Makefile                                |    1 +
 lib/librte_eal/bsdapp/eal/eal.c             |   10 +-
 lib/librte_eal/common/eal_common_dev.c      |   58 +-
 lib/librte_eal/common/eal_common_pci.c      |    3 +
 lib/librte_eal/common/include/eal_private.h |    7 -
 lib/librte_eal/common/include/rte_dev.h     |   13 +-
 lib/librte_eal/linuxapp/eal/eal.c           |   11 +-
 lib/librte_ether/rte_ethdev.c               |   32 +-
 lib/librte_ether/rte_ethdev.h               |    7 +-
 lib/librte_pmd_bond/Makefile                |   32 +
 lib/librte_pmd_bond/rte_eth_bond.c          | 2148 +++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond.h          |  255 ++
 lib/librte_pmd_pcap/rte_eth_pcap.c          |   22 +-
 lib/librte_pmd_ring/rte_eth_ring.c          |   32 +-
 lib/librte_pmd_ring/rte_eth_ring.h          |    3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |    2 +-
 mk/rte.app.mk                               |    5 +
 34 files changed, 8193 insertions(+), 71 deletions(-)
Quoted 10 lines
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h

For the series

Thanks for all the hard work!
Neil

#85 lore raw

v6 cover Link Bonding Library

In reply to a message not in the archive

This patch contains the initial release of the Link Bonding PMD Library

Supporting bonding modes:
0 - Round Robin
1 - Active Backup
2 - Balance (Supporting 3 transmission polices)

	layer 2, layer 2+3, layer 3+4

3 - Broadcast

Version 6 of patch set:
Small fix for tx burst function in round robin mode which caused packets not to be distributed evenly across slaves if the burst sizes is continually 1.

Patch Set Description:
0001 - librte_pmd_bond + makefile changes
0002 - librte_ether changes to support unique naming of pmds 0003 - librte_eal changes to support bonding device intialization 0005 - link bonding unti test suite
0005 - testpmd link bonding support changes
0006 - doxygen additions

Declan Doherty (6):
Link Bonding Library (lib/librte_pmd_bond) Support for unique interface naming of pmds EAL support for link bonding device initialization Link bonding Unit Tests
testpmd link bonding additions
Link Bonding Library doxygen additions

 app/test-pmd/cmdline.c                      |  579 ++++
 app/test-pmd/config.c                       |    4 +-
 app/test-pmd/parameters.c                   |    3 +
 app/test-pmd/testpmd.c                      |   40 +-
 app/test-pmd/testpmd.h                      |    2 +
 app/test/Makefile                           |    4 +-
 app/test/commands.c                         |    7 +
 app/test/packet_burst_generator.c           |  287 ++
 app/test/packet_burst_generator.h           |   78 +
 app/test/test.h                             |    1 +
 app/test/test_link_bonding.c                | 3958 +++++++++++++++++++++++++++
 app/test/virtual_pmd.c                      |  574 ++++
 app/test/virtual_pmd.h                      |   74 +
 config/common_bsdapp                        |    5 +
 config/common_linuxapp                      |    5 +
 doc/doxy-api-index.md                       |    1 +
 doc/doxy-api.conf                           |    1 +
 lib/Makefile                                |    1 +
 lib/librte_eal/bsdapp/eal/eal.c             |   10 +-
 lib/librte_eal/common/eal_common_dev.c      |   58 +-
 lib/librte_eal/common/eal_common_pci.c      |    3 +
 lib/librte_eal/common/include/eal_private.h |    7 -
 lib/librte_eal/common/include/rte_dev.h     |   13 +-
 lib/librte_eal/linuxapp/eal/eal.c           |   11 +-
 lib/librte_ether/rte_ethdev.c               |   32 +-
 lib/librte_ether/rte_ethdev.h               |    7 +-
 lib/librte_pmd_bond/Makefile                |   32 +
 lib/librte_pmd_bond/rte_eth_bond.c          | 2142 +++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond.h          |  255 ++
 lib/librte_pmd_pcap/rte_eth_pcap.c          |   22 +-
 lib/librte_pmd_ring/rte_eth_ring.c          |   32 +-
 lib/librte_pmd_ring/rte_eth_ring.h          |    3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |    2 +-
 mk/rte.app.mk                               |    5 +
 34 files changed, 8187 insertions(+), 71 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h

A message that is not in the archive (sent off-list or not yet received): 1403621531-30487-1-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#87 lore raw

v7 cover Link Bonding Library

This patch contains the initial release of the Link Bonding PMD Library

Supporting bonding modes:
0 - Round Robin
1 - Active Backup
2 - Balance (Supporting 3 transmission polices)

	layer 2, layer 2+3, layer 3+4

3 - Broadcast

Version 6 of patch set:
Debug tracing formatting issue in rte_eth_dev_allocate

Patch Set Description:
0001 - librte_pmd_bond + makefile changes
0002 - librte_ether changes to support unique naming of pmds 0003 - librte_eal changes to support bonding device intialization 0005 - link bonding unti test suite
0005 - testpmd link bonding support changes
0006 - doxygen additions

Declan Doherty (6):
Link Bonding Library (lib/librte_pmd_bond) Support for unique interface naming of pmds EAL support for link bonding device initialization Link bonding Unit Tests
testpmd link bonding additions
Link Bonding Library doxygen additions

 app/test-pmd/cmdline.c                      |  579 ++++
 app/test-pmd/config.c                       |    4 +-
 app/test-pmd/parameters.c                   |    3 +
 app/test-pmd/testpmd.c                      |   40 +-
 app/test-pmd/testpmd.h                      |    2 +
 app/test/Makefile                           |    4 +-
 app/test/commands.c                         |    7 +
 app/test/packet_burst_generator.c           |  287 ++
 app/test/packet_burst_generator.h           |   78 +
 app/test/test.h                             |    1 +
 app/test/test_link_bonding.c                | 3958 +++++++++++++++++++++++++++
 app/test/virtual_pmd.c                      |  574 ++++
 app/test/virtual_pmd.h                      |   74 +
 config/common_bsdapp                        |    5 +
 config/common_linuxapp                      |    5 +
 doc/doxy-api-index.md                       |    1 +
 doc/doxy-api.conf                           |    1 +
 lib/Makefile                                |    1 +
 lib/librte_eal/bsdapp/eal/eal.c             |   10 +-
 lib/librte_eal/common/eal_common_dev.c      |   58 +-
 lib/librte_eal/common/eal_common_pci.c      |    3 +
 lib/librte_eal/common/include/eal_private.h |    7 -
 lib/librte_eal/common/include/rte_dev.h     |   13 +-
 lib/librte_eal/linuxapp/eal/eal.c           |   11 +-
 lib/librte_ether/rte_ethdev.c               |   33 +-
 lib/librte_ether/rte_ethdev.h               |    7 +-
 lib/librte_pmd_bond/Makefile                |   32 +
 lib/librte_pmd_bond/rte_eth_bond.c          | 2142 +++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond.h          |  255 ++
 lib/librte_pmd_pcap/rte_eth_pcap.c          |   22 +-
 lib/librte_pmd_ring/rte_eth_ring.c          |   32 +-
 lib/librte_pmd_ring/rte_eth_ring.h          |    3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |    2 +-
 mk/rte.app.mk                               |    5 +
 34 files changed, 8188 insertions(+), 71 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h

A message that is not in the archive (sent off-list or not yet received): 1403625828-20956-1-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#89 lore raw

v8 cover Link Bonding Library

This patch contains the initial release of the Link Bonding PMD Library

Supporting bonding modes:
0 - Round Robin
1 - Active Backup
2 - Balance (Supporting 3 transmission polices)

	layer 2, layer 2+3, layer 3+4

3 - Broadcast

Version 8 of patch set:
This version splits the bonding library into 3 C files, containing the PMD specific code, the argument parsing code, and the public API code

Patch Set Description:
0001 - librte_pmd_bond + makefile changes
0002 - librte_ether changes to support unique naming of pmds 0003 - librte_eal changes to support bonding device intialization 0005 - link bonding unti test suite
0005 - testpmd link bonding support changes
0006 - doxygen additions

Declan Doherty (6):
Link Bonding Library (lib/librte_pmd_bond) Support for unique interface naming of pmds EAL support for link bonding device initialization Link bonding Unit Tests
testpmd link bonding additions
Link Bonding Library doxygen additions

 app/test-pmd/cmdline.c                      |  579 ++++
 app/test-pmd/config.c                       |    4 +-
 app/test-pmd/parameters.c                   |    3 +
 app/test-pmd/testpmd.c                      |   40 +-
 app/test-pmd/testpmd.h                      |    2 +
 app/test/Makefile                           |    4 +-
 app/test/commands.c                         |    7 +
 app/test/packet_burst_generator.c           |  287 ++
 app/test/packet_burst_generator.h           |   78 +
 app/test/test.h                             |    1 +
 app/test/test_link_bonding.c                | 3958 +++++++++++++++++++++++++++
 app/test/virtual_pmd.c                      |  574 ++++
 app/test/virtual_pmd.h                      |   74 +
 config/common_bsdapp                        |    5 +
 config/common_linuxapp                      |    5 +
 doc/doxy-api-index.md                       |    1 +
 doc/doxy-api.conf                           |    1 +
 lib/Makefile                                |    1 +
 lib/librte_eal/bsdapp/eal/eal.c             |   10 +-
 lib/librte_eal/common/eal_common_dev.c      |   58 +-
 lib/librte_eal/common/eal_common_pci.c      |    3 +
 lib/librte_eal/common/include/eal_private.h |    7 -
 lib/librte_eal/common/include/rte_dev.h     |   13 +-
 lib/librte_eal/linuxapp/eal/eal.c           |   11 +-
 lib/librte_ether/rte_ethdev.c               |   32 +-
 lib/librte_ether/rte_ethdev.h               |    7 +-
 lib/librte_pmd_bond/Makefile                |   34 +
 lib/librte_pmd_bond/rte_eth_bond.h          |  255 ++
 lib/librte_pmd_bond/rte_eth_bond_api.c      |  670 +++++
 lib/librte_pmd_bond/rte_eth_bond_pmd.c      | 1228 +++++++++
 lib/librte_pmd_bond/rte_eth_bond_private.h  |  218 ++
 lib/librte_pmd_bond/rte_eth_bond_vargs.c    |  255 ++
 lib/librte_pmd_pcap/rte_eth_pcap.c          |   22 +-
 lib/librte_pmd_ring/rte_eth_ring.c          |   32 +-
 lib/librte_pmd_ring/rte_eth_ring.h          |    3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |    2 +-
 mk/rte.app.mk                               |    5 +
 37 files changed, 8418 insertions(+), 71 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_api.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_pmd.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_private.h
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_vargs.c

A message that is not in the archive (sent off-list or not yet received): 1403726868-8161-1-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

Acked-by Pablo de Lara
#91 lore raw
Quoted 79 lines

-----Original Message-----
From: dev [mailto:[email protected]] On Behalf Of Declan Doherty
Sent: Wednesday, June 25, 2014 9:08 PM
To: [email protected]
Subject: [dpdk-dev] [PATCH v8 0/6] Link Bonding Library

This patch contains the initial release of the Link Bonding PMD Library

Supporting bonding modes:
0 - Round Robin
1 - Active Backup
2 - Balance (Supporting 3 transmission polices)

	layer 2, layer 2+3, layer 3+4

3 - Broadcast

Version 8 of patch set:
This version splits the bonding library into 3 C files, containing the PMD specific code, the argument parsing code, and the public API code

Patch Set Description:
0001 - librte_pmd_bond + makefile changes
0002 - librte_ether changes to support unique naming of pmds 0003 - librte_eal changes to support bonding device intialization 0005 - link bonding unti test suite
0005 - testpmd link bonding support changes
0006 - doxygen additions

Declan Doherty (6):
Link Bonding Library (lib/librte_pmd_bond) Support for unique interface naming of pmds EAL support for link bonding device initialization Link bonding Unit Tests
testpmd link bonding additions
Link Bonding Library doxygen additions

 app/test-pmd/cmdline.c                      |  579 ++++
 app/test-pmd/config.c                       |    4 +-
 app/test-pmd/parameters.c                   |    3 +
 app/test-pmd/testpmd.c                      |   40 +-
 app/test-pmd/testpmd.h                      |    2 +
 app/test/Makefile                           |    4 +-
 app/test/commands.c                         |    7 +
 app/test/packet_burst_generator.c           |  287 ++
 app/test/packet_burst_generator.h           |   78 +
 app/test/test.h                             |    1 +
 app/test/test_link_bonding.c                | 3958
+++++++++++++++++++++++++++
 app/test/virtual_pmd.c                      |  574 ++++
 app/test/virtual_pmd.h                      |   74 +
 config/common_bsdapp                        |    5 +
 config/common_linuxapp                      |    5 +
 doc/doxy-api-index.md                       |    1 +
 doc/doxy-api.conf                           |    1 +
 lib/Makefile                                |    1 +
 lib/librte_eal/bsdapp/eal/eal.c             |   10 +-
 lib/librte_eal/common/eal_common_dev.c      |   58 +-
 lib/librte_eal/common/eal_common_pci.c      |    3 +
 lib/librte_eal/common/include/eal_private.h |    7 -
 lib/librte_eal/common/include/rte_dev.h     |   13 +-
 lib/librte_eal/linuxapp/eal/eal.c           |   11 +-
 lib/librte_ether/rte_ethdev.c               |   32 +-
 lib/librte_ether/rte_ethdev.h               |    7 +-
 lib/librte_pmd_bond/Makefile                |   34 +
 lib/librte_pmd_bond/rte_eth_bond.h          |  255 ++
 lib/librte_pmd_bond/rte_eth_bond_api.c      |  670 +++++
 lib/librte_pmd_bond/rte_eth_bond_pmd.c      | 1228 +++++++++
 lib/librte_pmd_bond/rte_eth_bond_private.h  |  218 ++
 lib/librte_pmd_bond/rte_eth_bond_vargs.c    |  255 ++
 lib/librte_pmd_pcap/rte_eth_pcap.c          |   22 +-
 lib/librte_pmd_ring/rte_eth_ring.c          |   32 +-
 lib/librte_pmd_ring/rte_eth_ring.h          |    3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |    2 +-
 mk/rte.app.mk                               |    5 +
 37 files changed, 8418 insertions(+), 71 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
Quoted 8 lines
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_api.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_pmd.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_private.h
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_vargs.c
#92 lore raw

v9 cover link bonding

In reply to a message not in the archive

Hi Declan,

I've made some adjustments in your patches.
* Some renaming:
- RTE_PMD_BOND / PMD_BOND_KVARG -> PMD_BOND_NAME
- rte_pmd_bond_init -> bond_init
- rte_pmd_bond_drv -> bond_drv
- rte_eth_bond_vargs.c -> rte_eth_bond_args.c
* Some moves in doxygen configuration
* Removed rte_snprintf usages
* Reword commit logs

bond: new link bonding library
ethdev: add unique name to devices
eal: support link bonding device initialization
bond: unit tests
bond: testpmd support

But there is still something wrong in the Makefile:
the copyright is missing. I cannot add it by myself, so please send a v10 based on this v9 with copyright added.

Thanks

A message that is not in the archive (sent off-list or not yet received): 1403827075-9192-1-git-send-email-thomas.monjalon-pdR9zngts4EAvxtiuMwx3w@public.gmane.org

#94 lore raw

PATCH v9 1/5 bond: new link bonding library

From: Declan Doherty <[email protected]>

Initial release with support for
Mode 0 - Round Robin
Mode 1 - Active Backup
Mode 2 - Balance -> Supports 3 transmit polices (layer 2, layer 2+3, layer 3+4) Mode 3 - Broadcast

---
 config/common_bsdapp                       |    5 +
 config/common_linuxapp                     |    5 +
 doc/doxy-api-index.md                      |    1 +
 doc/doxy-api.conf                          |    1 +
 lib/Makefile                               |    1 +
 lib/librte_pmd_bond/Makefile               |   32 +
 lib/librte_pmd_bond/rte_eth_bond.h         |  255 ++++++
 lib/librte_pmd_bond/rte_eth_bond_api.c     |  662 +++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond_args.c    |  252 ++++++
 lib/librte_pmd_bond/rte_eth_bond_pmd.c     | 1212 ++++++++++++++++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond_private.h |  215 +++++
 mk/rte.app.mk                              |    4 +
 12 files changed, 2645 insertions(+)
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_api.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_args.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_pmd.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_private.h
config/common_bsdapp +5 -0
index d5db4ab..c243b0c 100644
@@ -206,6 +206,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=y
 
 #
+# Compile link bonding PMD library
+#
+CONFIG_RTE_LIBRTE_PMD_BOND=y
+
+#
 # Do prefetch of packet data within PMD driver receive function
 #
 CONFIG_RTE_PMD_PACKET_PREFETCH=y
config/common_linuxapp +5 -0
index c5c0cb6..6237ce5 100644
@@ -244,6 +244,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=n
 
 #
+# Compile link bonding PMD library
+#
+CONFIG_RTE_LIBRTE_PMD_BOND=y
+
+#
 # Compile Xen PMD
 #
 CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
doc/doxy-api-index.md +1 -0
index 7b26e98..d72659a 100644
@@ -38,6 +38,7 @@ There are many libraries, so their headers may be grouped by topics:
 - **device**:
   [ethdev]             (@ref rte_ethdev.h),
   [devargs]            (@ref rte_devargs.h),
+  [bond]               (@ref rte_eth_bond.h),
   [KNI]                (@ref rte_kni.h),
   [PCI]                (@ref rte_pci.h),
   [PCI IDs]            (@ref rte_pci_dev_ids.h)
doc/doxy-api.conf +1 -0
index f380d9a..1fd4492 100644
@@ -47,6 +47,7 @@ INPUT                   = doc/doxy-api-index.md \
                           lib/librte_pipeline \
                           lib/librte_port \
                           lib/librte_power \
+                          lib/librte_pmd_bond \
                           lib/librte_ring \
                           lib/librte_sched \
                           lib/librte_table \
lib/Makefile +1 -0
index c58c0c9..10c5bb3 100644
@@ -44,6 +44,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
 DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += librte_pmd_e1000
 DIRS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += librte_pmd_ixgbe
 DIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += librte_pmd_i40e
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += librte_pmd_bond
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_RING) += librte_pmd_ring
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += librte_pmd_pcap
 DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += librte_pmd_virtio
lib/librte_pmd_bond/Makefile new file +32 -0
new file mode 100644
index 0000000..6960551
@@ -0,0 +1,32 @@
+# <COPYRIGHT_TAG>
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_bond.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond_api.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond_pmd.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond_vargs.c
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_eth_bond.h
+
+# this lib depends upon:
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_mbuf
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_malloc
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_kvargs
+
+include $(RTE_SDK)/mk/rte.lib.mk
lib/librte_pmd_bond/rte_eth_bond.h new file +255 -0

255 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_api.c new file +662 -0

662 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_args.c new file +252 -0

252 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_pmd.c new file +1212 -0

1,212 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_private.h new file +215 -0

215 lines not on this page · raw message

mk/rte.app.mk +4 -0
index 8db9cde..a4624e5 100644
@@ -205,6 +205,10 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMD_PCAP),y)
 LDLIBS += -lrte_pmd_pcap -lpcap
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_PMD_BOND),y)
+LDLIBS += -lrte_pmd_bond
+endif
+
 endif
 
 LDLIBS += $(EXECENV_LDLIBS)
Signature · 1 line
2.0.0

A message that is not in the archive (sent off-list or not yet received): 1403827075-9192-2-git-send-email-thomas.monjalon-pdR9zngts4EAvxtiuMwx3w@public.gmane.org

#96 lore raw

Re: [PATCH v9 1/5] bond: new link bonding library

2014-06-27 01:57, Thomas Monjalon:

Quoted 1 line

+SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond_vargs.c

I forgot to rename the file here to rte_eth_bond_args.c.

Signature · 1 line
Thomas
#97 lore raw

PATCH v9 2/5 ethdev: add unique name to devices

In reply to a message not in the archive

From: Declan Doherty <[email protected]>

Adding support to rte_eth_dev_data structure to support unique name identifier for ethdevs to support adding slave ethdevs (specifically virtual devices which have no public unique identifier) to a link bonding device. This changes the API rte_eth_dev_allocate() to require a const char *name when allocating a ethdev, which also verifies that the name is unique and hasn’t been already used by an existed allocated rte_eth_dev. Also contains updates to virtual pmd’s to now call the API with a name parameter.

---
 lib/librte_ether/rte_ethdev.c            | 31 ++++++++++++++++++++++++++++---
 lib/librte_ether/rte_ethdev.h            |  7 ++++++-
 lib/librte_pmd_pcap/rte_eth_pcap.c       | 22 +++++++++++-----------
 lib/librte_pmd_ring/rte_eth_ring.c       | 32 +++++++++++++++++---------------
 lib/librte_pmd_ring/rte_eth_ring.h       |  3 ++-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c |  2 +-
 6 files changed, 65 insertions(+), 32 deletions(-)
lib/librte_ether/rte_ethdev.c +28 -3
index 8687499..a21cdb9 100644
@@ -65,6 +65,7 @@
 #include <rte_mbuf.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
+#include <rte_string_fns.h>
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"
@@ -153,21 +154,39 @@ rte_eth_dev_data_alloc(void)
 				RTE_MAX_ETHPORTS * sizeof(*rte_eth_dev_data));
 }
 
+static struct rte_eth_dev *
+rte_eth_dev_allocated(const char *name)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_ports; i++) {
+		if (strcmp(rte_eth_devices[i].data->name, name) == 0)
+			return &rte_eth_devices[i];
+	}
+	return NULL;
+}
+
 struct rte_eth_dev *
-rte_eth_dev_allocate(void)
+rte_eth_dev_allocate(const char *name)
 {
 	struct rte_eth_dev *eth_dev;
 
 	if (nb_ports == RTE_MAX_ETHPORTS) {
-		PMD_DEBUG_TRACE("Reached maximum number of ethernet ports\n");
+		PMD_DEBUG_TRACE("Reached maximum number of Ethernet ports\n");
 		return NULL;
 	}
 
 	if (rte_eth_dev_data == NULL)
 		rte_eth_dev_data_alloc();
 
+	if (rte_eth_dev_allocated(name) != NULL) {
+		PMD_DEBUG_TRACE("Ethernet Device with name %s already allocated!\n");
+		return NULL;
+	}
+
 	eth_dev = &rte_eth_devices[nb_ports];
 	eth_dev->data = &rte_eth_dev_data[nb_ports];
+	snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
 	eth_dev->data->port_id = nb_ports++;
 	return eth_dev;
 }
@@ -178,11 +197,17 @@ rte_eth_dev_init(struct rte_pci_driver *pci_drv,
 {
 	struct eth_driver    *eth_drv;
 	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
 	int diag;
 
 	eth_drv = (struct eth_driver *)pci_drv;
 
-	eth_dev = rte_eth_dev_allocate();
+	/* Create unique Ethernet device name using PCI address */
+	snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "%d:%d.%d",
+			pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
+
+	eth_dev = rte_eth_dev_allocate(ethdev_name);
 	if (eth_dev == NULL)
 		return -ENOMEM;
 
lib/librte_ether/rte_ethdev.h +6 -1
index 526331a..25f2df7 100644
@@ -1497,6 +1497,8 @@ struct rte_eth_dev_sriov {
 };
 #define RTE_ETH_DEV_SRIOV(dev)         ((dev)->data->sriov)
 
+#define RTE_ETH_NAME_MAX_LEN (32)
+
 /**
  * @internal
  * The data part, with no function pointers, associated with each ethernet device.
@@ -1505,6 +1507,8 @@ struct rte_eth_dev_sriov {
  * processes in a multi-process configuration.
  */
 struct rte_eth_dev_data {
+	char name[RTE_ETH_NAME_MAX_LEN]; /**< Unique identifier name */
+
 	void **rx_queues; /**< Array of pointers to RX queues. */
 	void **tx_queues; /**< Array of pointers to TX queues. */
 	uint16_t nb_rx_queues; /**< Number of RX queues. */
@@ -1560,10 +1564,11 @@ extern uint8_t rte_eth_dev_count(void);
  * Allocates a new ethdev slot for an ethernet device and returns the pointer
  * to that slot for the driver to use.
  *
+ * @param	name	Unique identifier name for each Ethernet device
  * @return
  *   - Slot in the rte_dev_devices array for a new device;
  */
-struct rte_eth_dev *rte_eth_dev_allocate(void);
+struct rte_eth_dev *rte_eth_dev_allocate(const char *name);
 
 struct eth_driver;
 /**
lib/librte_pmd_pcap/rte_eth_pcap.c +11 -11
index b3dbbda..12b7e0c 100644
@@ -534,7 +534,7 @@ open_tx_iface(const char *key __rte_unused, const char *value, void *extra_args)
 
 
 static int
-rte_pmd_init_internals(const unsigned nb_rx_queues,
+rte_pmd_init_internals(const char *name, const unsigned nb_rx_queues,
 		const unsigned nb_tx_queues,
 		const unsigned numa_node,
 		struct pmd_internals **internals,
@@ -558,20 +558,20 @@ rte_pmd_init_internals(const unsigned nb_rx_queues,
 	/* now do all data allocation - for eth_dev structure, dummy pci driver
 	 * and internal (private) data
 	 */
-	data = rte_zmalloc_socket(NULL, sizeof(*data), 0, numa_node);
+	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
 	if (data == NULL)
 		goto error;
 
-	pci_dev = rte_zmalloc_socket(NULL, sizeof(*pci_dev), 0, numa_node);
+	pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, numa_node);
 	if (pci_dev == NULL)
 		goto error;
 
-	*internals = rte_zmalloc_socket(NULL, sizeof(**internals), 0, numa_node);
+	*internals = rte_zmalloc_socket(name, sizeof(**internals), 0, numa_node);
 	if (*internals == NULL)
 		goto error;
 
 	/* reserve an ethdev entry */
-	*eth_dev = rte_eth_dev_allocate();
+	*eth_dev = rte_eth_dev_allocate(name);
 	if (*eth_dev == NULL)
 		goto error;
 
@@ -617,7 +617,7 @@ rte_pmd_init_internals(const unsigned nb_rx_queues,
 }
 
 static int
-rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
+rte_eth_from_pcaps_n_dumpers(const char *name, pcap_t * const rx_queues[],
 		const unsigned nb_rx_queues,
 		pcap_dumper_t * const tx_queues[],
 		const unsigned nb_tx_queues,
@@ -634,7 +634,7 @@ rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
 	if (tx_queues == NULL && nb_tx_queues > 0)
 		return -1;
 
-	if (rte_pmd_init_internals(nb_rx_queues, nb_tx_queues, numa_node,
+	if (rte_pmd_init_internals(name, nb_rx_queues, nb_tx_queues, numa_node,
 			&internals, &eth_dev, kvlist) < 0)
 		return -1;
 
@@ -652,7 +652,7 @@ rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
 }
 
 static int
-rte_eth_from_pcaps(pcap_t * const rx_queues[],
+rte_eth_from_pcaps(const char *name, pcap_t * const rx_queues[],
 		const unsigned nb_rx_queues,
 		pcap_t * const tx_queues[],
 		const unsigned nb_tx_queues,
@@ -669,7 +669,7 @@ rte_eth_from_pcaps(pcap_t * const rx_queues[],
 	if (tx_queues == NULL && nb_tx_queues > 0)
 		return -1;
 
-	if (rte_pmd_init_internals(nb_rx_queues, nb_tx_queues, numa_node,
+	if (rte_pmd_init_internals(name, nb_rx_queues, nb_tx_queues, numa_node,
 			&internals, &eth_dev, kvlist) < 0)
 		return -1;
 
@@ -760,10 +760,10 @@ rte_pmd_pcap_devinit(const char *name, const char *params)
 		return -1;
 
 	if (using_dumpers)
-		return rte_eth_from_pcaps_n_dumpers(pcaps.pcaps, pcaps.num_of_rx,
+		return rte_eth_from_pcaps_n_dumpers(name, pcaps.pcaps, pcaps.num_of_rx,
 				dumpers.dumpers, dumpers.num_of_tx, numa_node, kvlist);
 
-	return rte_eth_from_pcaps(pcaps.pcaps, pcaps.num_of_rx, dumpers.pcaps,
+	return rte_eth_from_pcaps(name, pcaps.pcaps, pcaps.num_of_rx, dumpers.pcaps,
 			dumpers.num_of_tx, numa_node, kvlist);
 
 }
lib/librte_pmd_ring/rte_eth_ring.c +17 -15
index ce7ad71..73c649e 100644
@@ -219,7 +219,7 @@ static struct eth_dev_ops ops = {
 };
 
 int
-rte_eth_from_rings(struct rte_ring *const rx_queues[],
+rte_eth_from_rings(const char *name, struct rte_ring *const rx_queues[],
 		const unsigned nb_rx_queues,
 		struct rte_ring *const tx_queues[],
 		const unsigned nb_tx_queues,
@@ -243,20 +243,20 @@ rte_eth_from_rings(struct rte_ring *const rx_queues[],
 	/* now do all data allocation - for eth_dev structure, dummy pci driver
 	 * and internal (private) data
 	 */
-	data = rte_zmalloc_socket(NULL, sizeof(*data), 0, numa_node);
+	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
 	if (data == NULL)
 		goto error;
 
-	pci_dev = rte_zmalloc_socket(NULL, sizeof(*pci_dev), 0, numa_node);
+	pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, numa_node);
 	if (pci_dev == NULL)
 		goto error;
 
-	internals = rte_zmalloc_socket(NULL, sizeof(*internals), 0, numa_node);
+	internals = rte_zmalloc_socket(name, sizeof(*internals), 0, numa_node);
 	if (internals == NULL)
 		goto error;
 
 	/* reserve an ethdev entry */
-	eth_dev = rte_eth_dev_allocate();
+	eth_dev = rte_eth_dev_allocate(name);
 	if (eth_dev == NULL)
 		goto error;
 
@@ -335,7 +335,7 @@ eth_dev_ring_create(const char *name, const unsigned numa_node,
 			return -1;
 	}
 
-	if (rte_eth_from_rings(rxtx, num_rings, rxtx, num_rings, numa_node))
+	if (rte_eth_from_rings(name, rxtx, num_rings, rxtx, num_rings, numa_node))
 		return -1;
 
 	return 0;
@@ -352,29 +352,31 @@ eth_dev_ring_pair_create(const char *name, const unsigned numa_node,
 	struct rte_ring *rx[RTE_PMD_RING_MAX_RX_RINGS];
 	struct rte_ring *tx[RTE_PMD_RING_MAX_TX_RINGS];
 	unsigned i;
-	char rng_name[RTE_RING_NAMESIZE];
+	char rx_rng_name[RTE_RING_NAMESIZE];
+	char tx_rng_name[RTE_RING_NAMESIZE];
 	unsigned num_rings = RTE_MIN(RTE_PMD_RING_MAX_RX_RINGS,
 			RTE_PMD_RING_MAX_TX_RINGS);
 
 	for (i = 0; i < num_rings; i++) {
-		snprintf(rng_name, sizeof(rng_name), "ETH_RX%u_%s", i, name);
+		snprintf(rx_rng_name, sizeof(rx_rng_name), "ETH_RX%u_%s", i, name);
 		rx[i] = (action == DEV_CREATE) ?
-				rte_ring_create(rng_name, 1024, numa_node,
+				rte_ring_create(rx_rng_name, 1024, numa_node,
 						RING_F_SP_ENQ|RING_F_SC_DEQ) :
-				rte_ring_lookup(rng_name);
+				rte_ring_lookup(rx_rng_name);
 		if (rx[i] == NULL)
 			return -1;
-		snprintf(rng_name, sizeof(rng_name), "ETH_TX%u_%s", i, name);
+		snprintf(tx_rng_name, sizeof(tx_rng_name), "ETH_TX%u_%s", i, name);
 		tx[i] = (action == DEV_CREATE) ?
-				rte_ring_create(rng_name, 1024, numa_node,
+				rte_ring_create(tx_rng_name, 1024, numa_node,
 						RING_F_SP_ENQ|RING_F_SC_DEQ):
-				rte_ring_lookup(rng_name);
+				rte_ring_lookup(tx_rng_name);
 		if (tx[i] == NULL)
 			return -1;
 	}
 
-	if (rte_eth_from_rings(rx, num_rings, tx, num_rings, numa_node) ||
-			rte_eth_from_rings(tx, num_rings, rx, num_rings, numa_node) )
+	if (rte_eth_from_rings(rx_rng_name, rx, num_rings, tx, num_rings,
+			numa_node) || rte_eth_from_rings(tx_rng_name, tx, num_rings, rx,
+					num_rings, numa_node))
 		return -1;
 
 	return 0;
lib/librte_pmd_ring/rte_eth_ring.h +2 -1
index ef29344..e6ae19e 100644
@@ -40,7 +40,8 @@ extern "C" {
 
 #include <rte_ring.h>
 
-int rte_eth_from_rings(struct rte_ring * const rx_queues[],
+int rte_eth_from_rings(const char *name,
+		struct rte_ring * const rx_queues[],
 		const unsigned nb_rx_queues,
 		struct rte_ring *const tx_queues[],
 		const unsigned nb_tx_queues,
lib/librte_pmd_xenvirt/rte_eth_xenvirt.c +1 -1
index 18c44f5..450332a 100644
@@ -647,7 +647,7 @@ eth_dev_xenvirt_create(const char *name, const char *params,
 		goto err;
 
 	/* reserve an ethdev entry */
-	eth_dev = rte_eth_dev_allocate();
+	eth_dev = rte_eth_dev_allocate(name);
 	if (eth_dev == NULL)
 		goto err;
 
Signature · 1 line
2.0.0
#98 lore raw

PATCH v9 3/5 eal: support link bonding device initialization

In reply to a message not in the archive

From: Declan Doherty <[email protected]>

Updating functionality in EAL to support adding link bonding devices via –vdev option. Link bonding devices will be initialized after all physical devices have been probed and initialized.

---
 lib/librte_eal/bsdapp/eal/eal.c             | 10 ++++-
 lib/librte_eal/common/eal_common_dev.c      | 58 ++++++++++++++++++++---------
 lib/librte_eal/common/eal_common_pci.c      |  3 ++
 lib/librte_eal/common/include/eal_private.h |  7 ----
 lib/librte_eal/common/include/rte_dev.h     | 14 ++++++-
 lib/librte_eal/linuxapp/eal/eal.c           | 11 +++++-
 6 files changed, 74 insertions(+), 29 deletions(-)
lib/librte_eal/bsdapp/eal/eal.c +9 -1
index ce0db03..ec57b26 100644
@@ -919,7 +919,7 @@ rte_eal_init(int argc, char **argv)
 
 	rte_eal_mcfg_complete();
 
-	if (rte_eal_dev_init() < 0)
+	if (rte_eal_dev_init(PMD_INIT_PRE_PCI_PROBE) < 0)
 		rte_panic("Cannot init pmd devices\n");
 
 	RTE_LCORE_FOREACH_SLAVE(i) {
@@ -951,6 +951,14 @@ rte_eal_init(int argc, char **argv)
 	rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
 	rte_eal_mp_wait_lcore();
 
+	/* Probe & Initialize PCI devices */
+	if (rte_eal_pci_probe())
+			rte_panic("Cannot probe PCI\n");
+
+	/* Initialize any outstanding devices */
+	if (rte_eal_dev_init(PMD_INIT_POST_PCI_PROBE) < 0)
+		rte_panic("Cannot init pmd devices\n");
+
 	return fctret;
 }
 
lib/librte_eal/common/eal_common_dev.c +40 -18

77 lines not on this page · raw message

lib/librte_eal/common/eal_common_pci.c +3 -0
index af809a8..c637361 100644
@@ -150,6 +150,9 @@ rte_eal_pci_probe(void)
 		probe_all = 1;
 
 	TAILQ_FOREACH(dev, &pci_device_list, next) {
+		/* check if device has already been initialized */
+		if (dev->driver != NULL)
+			continue;
 
 		/* set devargs in PCI structure */
 		devargs = pci_devargs_lookup(dev);
lib/librte_eal/common/include/eal_private.h +0 -7
index 232fcec..b440ffb 100644
@@ -196,11 +196,4 @@ int rte_eal_intr_init(void);
  */
 int rte_eal_alarm_init(void);
 
-/**
- * This function initialises any virtual devices
- *
- * This function is private to the EAL.
- */
-int rte_eal_dev_init(void);
-
 #endif /* _EAL_PRIVATE_H_ */
lib/librte_eal/common/include/rte_dev.h +12 -2
index f7e3a10..d89f1a5 100644
@@ -62,6 +62,16 @@ typedef int (rte_dev_init_t)(const char *name, const char *args);
 enum pmd_type {
 	PMD_VDEV = 0,
 	PMD_PDEV = 1,
+	PMD_BDEV = 2,	/**< Poll Mode Driver Bonded Device*/
+};
+
+#define PMD_BOND_NAME "eth_bond"
+
+/**
+ * Driver initialization */
+enum pmd_init_priority {
+	PMD_INIT_PRE_PCI_PROBE = 0,
+	PMD_INIT_POST_PCI_PROBE = 1,
 };
 
 /**
@@ -93,9 +103,9 @@ void rte_eal_driver_register(struct rte_driver *driver);
 void rte_eal_driver_unregister(struct rte_driver *driver);
 
 /**
- * Initalize all the registered drivers in this process
+ * Initialize all the registered drivers in this process
  */
-int rte_eal_dev_init(void);
+int rte_eal_dev_init(uint8_t init_priority);
 
 #define PMD_REGISTER_DRIVER(d)\
 void devinitfn_ ##d(void);\
lib/librte_eal/linuxapp/eal/eal.c +10 -1
index 00d74ed..d1c082d 100644
@@ -75,6 +75,7 @@
 #include <rte_atomic.h>
 #include <malloc_heap.h>
 #include <rte_eth_ring.h>
+#include <rte_dev.h>
 
 #include "eal_private.h"
 #include "eal_thread.h"
@@ -1142,7 +1143,7 @@ rte_eal_init(int argc, char **argv)
 	RTE_LOG(DEBUG, EAL, "Master core %u is ready (tid=%x)\n",
 		rte_config.master_lcore, (int)thread_id);
 
-	if (rte_eal_dev_init() < 0)
+	if (rte_eal_dev_init(PMD_INIT_PRE_PCI_PROBE) < 0)
 		rte_panic("Cannot init pmd devices\n");
 
 	RTE_LCORE_FOREACH_SLAVE(i) {
@@ -1172,6 +1173,14 @@ rte_eal_init(int argc, char **argv)
 	rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
 	rte_eal_mp_wait_lcore();
 
+	/* Probe & Initialize PCI devices */
+	if (rte_eal_pci_probe())
+			rte_panic("Cannot probe PCI\n");
+
+	/* Initialize any outstanding devices */
+	if (rte_eal_dev_init(PMD_INIT_POST_PCI_PROBE) < 0)
+		rte_panic("Cannot init pmd devices\n");
+
 	return fctret;
 }
 
Signature · 1 line
2.0.0
#99 lore raw

PATCH v9 4/5 bond: unit tests

In reply to a message not in the archive

From: Declan Doherty <[email protected]>

Including:
- code to generate packet bursts for testing rx and tx functionality of bonded device
- virtual/stubbed out ethdev for use as slave ethdev in testing

---
 app/test/Makefile                 |    4 +-
 app/test/commands.c               |    7 +
 app/test/packet_burst_generator.c |  287 +++
 app/test/packet_burst_generator.h |   78 +
 app/test/test.h                   |    1 +
 app/test/test_link_bonding.c      | 3958 +++++++++++++++++++++++++++++++++++++
 app/test/virtual_pmd.c            |  574 ++++++
 app/test/virtual_pmd.h            |   74 +
 8 files changed, 4982 insertions(+), 1 deletion(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
app/test/Makefile +3 -1
index 45d0cf2..cec2f2f 100644
@@ -102,7 +102,9 @@ SRCS-$(CONFIG_RTE_APP_TEST) += test_ivshmem.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_distributor.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_distributor_perf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_devargs.c
-
+SRCS-$(CONFIG_RTE_APP_TEST) += virtual_pmd.c
+SRCS-$(CONFIG_RTE_APP_TEST) += packet_burst_generator.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_link_bonding.c
 ifeq ($(CONFIG_RTE_APP_TEST),y)
 SRCS-$(CONFIG_RTE_LIBRTE_ACL) += test_acl.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring.c
app/test/commands.c +7 -0
index c9dc085..5f23420 100644
@@ -159,6 +159,10 @@ static void cmd_autotest_parsed(void *parsed_result,
 		ret = test_timer();
 	if (!strcmp(res->autotest, "timer_perf_autotest"))
 		ret = test_timer_perf();
+#ifdef RTE_LIBRTE_PMD_BOND
+	if (!strcmp(res->autotest, "link_bonding_autotest"))
+		ret = test_link_bonding();
+#endif
 	if (!strcmp(res->autotest, "mempool_autotest"))
 		ret = test_mempool();
 	if (!strcmp(res->autotest, "mempool_perf_autotest"))
@@ -227,6 +231,9 @@ cmdline_parse_token_string_t cmd_autotest_autotest =
 			"alarm_autotest#interrupt_autotest#"
 			"version_autotest#eal_fs_autotest#"
 			"cmdline_autotest#func_reentrancy_autotest#"
+#ifdef RTE_LIBRTE_PMD_BOND
+			"link_bonding_autotest#"
+#endif
 			"mempool_perf_autotest#hash_perf_autotest#"
 			"memcpy_perf_autotest#ring_perf_autotest#"
 			"red_autotest#meter_autotest#sched_autotest#"
app/test/packet_burst_generator.c new file +287 -0

287 lines not on this page · raw message

app/test/packet_burst_generator.h new file +78 -0

78 lines not on this page · raw message

app/test/test.h +1 -0
index c54e7ef..c00e1d6 100644
@@ -97,6 +97,7 @@ int test_distributor(void);
 int test_distributor_perf(void);
 int test_kvargs(void);
 int test_devargs(void);
+int test_link_bonding(void);
 
 int test_pci_run;
 
app/test/test_link_bonding.c new file +3958 -0

2,599 lines not on this page · raw message

app/test/virtual_pmd.c new file +574 -0

574 lines not on this page · raw message

app/test/virtual_pmd.h new file +74 -0

74 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.0.0

Part of the diff is not shown here. View the raw message.

#100 lore raw

PATCH v9 5/5 bond: testpmd support

In reply to a message not in the archive

From: Declan Doherty <[email protected]>

- Includes the ability to create new bonded devices.
- Add /remove bonding slave devices.
- Interogate bonded device stats/configuration
- Change bonding modes and select balance transmit polices

---
 app/test-pmd/cmdline.c    | 579 ++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/config.c     |   4 +-
 app/test-pmd/parameters.c |   3 +
 app/test-pmd/testpmd.c    |  40 +++-
 app/test-pmd/testpmd.h    |   2 +
 5 files changed, 619 insertions(+), 9 deletions(-)
app/test-pmd/cmdline.c +579 -0
index 45ce343..5cf93bb 100644
@@ -84,6 +84,9 @@
 #include <cmdline_socket.h>
 #include <cmdline.h>
 #include <rte_pci_dev_ids.h>
+#ifdef RTE_LIBRTE_PMD_BOND
+#include <rte_eth_bond.h>
+#endif
 
 #include "testpmd.h"
 
@@ -404,6 +407,31 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"   Show the bypass configuration for a bypass enabled NIC"
 			" using the lowest port on the NIC.\n\n"
 #endif
+#ifdef RTE_LIBRTE_PMD_BOND
+			"create bonded device (mode) (socket)\n"
+			"	Create a new bonded device with specific bonding mode and socket.\n\n"
+
+			"add bonding slave (slave_id) (port_id)\n"
+			"	Add a slave device to a bonded device.\n\n"
+
+			"remove bonding slave (slave_id) (port_id)\n"
+			"	Remove a slave device from a bonded device.\n\n"
+
+			"set bonding mode (value) (port_id)\n"
+			"	Set the bonding mode on a bonded device.\n\n"
+
+			"set bonding primary (slave_id) (port_id)\n"
+			"	Set the primary slave for a bonded device.\n\n"
+
+			"show bonding config (port_id)\n"
+			"	Show the bonding config for port_id.\n\n"
+
+			"set bonding mac_addr (port_id) (address)\n"
+			"	Set the MAC address of a bonded device.\n\n"
+
+			"set bonding xmit_balance_policy (port_id) (l2|l23|l34)\n"
+			"	Set the transmit balance policy for bonded device running in balance mode.\n\n"
+#endif
 
 			, list_pkt_forwarding_modes()
 		);
@@ -3031,6 +3059,547 @@ cmdline_parse_inst_t cmd_show_bypass_config = {
 };
 #endif
 
+#ifdef RTE_LIBRTE_PMD_BOND
+/* *** SET BONDING MODE *** */
+struct cmd_set_bonding_mode_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t mode;
+	uint8_t value;
+	uint8_t port_id;
+};
+
+static void cmd_set_bonding_mode_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_mode_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+
+	/* Set the bonding mode for the relevant port. */
+	if (0 != rte_eth_bond_mode_set(port_id, res->value))
+		printf("\t Failed to set bonding mode for port = %d.\n", port_id);
+}
+
+cmdline_parse_token_string_t cmd_setbonding_mode_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_mode_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_mode_mode =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		mode, "mode");
+cmdline_parse_token_num_t cmd_setbonding_mode_value =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+		value, UINT8);
+cmdline_parse_token_num_t cmd_setbonding_mode_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bonding_mode = {
+		.f = cmd_set_bonding_mode_parsed,
+		.help_str = "set bonding mode (mode_value) (port_id): Set the bonding mode for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *) &cmd_setbonding_mode_set,
+				(void *) &cmd_setbonding_mode_bonding,
+				(void *) &cmd_setbonding_mode_mode,
+				(void *) &cmd_setbonding_mode_value,
+				(void *) &cmd_setbonding_mode_port,
+				NULL
+		}
+};
+
+/* *** SET BALANCE XMIT POLICY *** */
+struct cmd_set_bonding_balance_xmit_policy_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t balance_xmit_policy;
+	uint8_t port_id;
+	cmdline_fixed_string_t policy;
+};
+
+static void cmd_set_bonding_balance_xmit_policy_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_balance_xmit_policy_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+	uint8_t policy;
+
+	if (!strcmp(res->policy, "l2")) {
+		policy = BALANCE_XMIT_POLICY_LAYER2;
+	} else if (!strcmp(res->policy, "l23")) {
+		policy = BALANCE_XMIT_POLICY_LAYER23;
+	} else if (!strcmp(res->policy, "l34")) {
+		policy = BALANCE_XMIT_POLICY_LAYER34;
+	} else {
+		printf("\t Invalid xmit policy selection");
+		return;
+	}
+
+	/* Set the bonding mode for the relevant port. */
+	if (0 != rte_eth_bond_xmit_policy_set(port_id, policy)) {
+		printf("\t Failed to set bonding balance xmit policy for port = %d.\n",
+				port_id);
+	}
+}
+
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_balance_xmit_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		balance_xmit_policy, "balance_xmit_policy");
+cmdline_parse_token_num_t cmd_setbonding_balance_xmit_policy_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		port_id, UINT8);
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		policy, "l2#l23#l34");
+
+cmdline_parse_inst_t cmd_set_balance_xmit_policy = {
+		.f = cmd_set_bonding_balance_xmit_policy_parsed,
+		.help_str = "set bonding balance_xmit_policy (port_id) (policy_value): Set the bonding balance_xmit_policy for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_setbonding_balance_xmit_policy_set,
+				(void *)&cmd_setbonding_balance_xmit_policy_bonding,
+				(void *)&cmd_setbonding_balance_xmit_policy_balance_xmit_policy,
+				(void *)&cmd_setbonding_balance_xmit_policy_port,
+				(void *)&cmd_setbonding_balance_xmit_policy_policy,
+				NULL
+		}
+};
+
+/* *** SHOW NIC BONDING CONFIGURATION *** */
+struct cmd_show_bonding_config_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+};
+
+static void cmd_show_bonding_config_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_show_bonding_config_result *res = parsed_result;
+	int bonding_mode;
+	uint8_t slaves[RTE_MAX_ETHPORTS];
+	int num_slaves, num_active_slaves;
+	int primary_id;
+	int i;
+	portid_t port_id = res->port_id;
+
+	/* Display the bonding mode.*/
+	bonding_mode = rte_eth_bond_mode_get(port_id);
+	if (bonding_mode < 0) {
+		printf("\tFailed to get bonding mode for port = %d\n", port_id);
+		return;
+	} else
+		printf("\tBonding mode: %d\n", bonding_mode);
+
+	if (bonding_mode == BONDING_MODE_BALANCE) {
+		int balance_xmit_policy;
+
+		balance_xmit_policy = rte_eth_bond_xmit_policy_get(port_id);
+		if (balance_xmit_policy < 0) {
+			printf("\tFailed to get balance xmit policy for port = %d\n",
+					port_id);
+			return;
+		} else {
+			printf("\tBalance Xmit Policy: ");
+
+			switch (balance_xmit_policy) {
+			case BALANCE_XMIT_POLICY_LAYER2:
+				printf("BALANCE_XMIT_POLICY_LAYER2");
+				break;
+			case BALANCE_XMIT_POLICY_LAYER23:
+				printf("BALANCE_XMIT_POLICY_LAYER23");
+				break;
+			case BALANCE_XMIT_POLICY_LAYER34:
+				printf("BALANCE_XMIT_POLICY_LAYER34");
+				break;
+			}
+			printf("\n");
+		}
+	}
+
+	num_slaves = rte_eth_bond_slaves_get(port_id, slaves, RTE_MAX_ETHPORTS);
+
+	if (num_slaves < 0) {
+		printf("\tFailed to get slave list for port = %d\n", port_id);
+		return;
+	}
+	if (num_slaves > 0) {
+		printf("\tSlaves (%d): [", num_slaves);
+		for (i = 0; i < num_slaves - 1; i++)
+			printf("%d ", slaves[i]);
+
+		printf("%d]\n", slaves[num_slaves - 1]);
+	} else {
+		printf("\tSlaves: []\n");
+
+	}
+
+	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
+			RTE_MAX_ETHPORTS);
+
+	if (num_active_slaves < 0) {
+		printf("\tFailed to get active slave list for port = %d\n", port_id);
+		return;
+	}
+	if (num_active_slaves > 0) {
+		printf("\tActive Slaves (%d): [", num_active_slaves);
+		for (i = 0; i < num_active_slaves - 1; i++)
+			printf("%d ", slaves[i]);
+
+		printf("%d]\n", slaves[num_active_slaves - 1]);
+
+	} else {
+		printf("\tActive Slaves: []\n");
+
+	}
+
+	primary_id = rte_eth_bond_primary_get(port_id);
+	if (primary_id < 0) {
+		printf("\tFailed to get primary slave for port = %d\n", port_id);
+		return;
+	} else
+		printf("\tPrimary: [%d]\n", primary_id);
+
+}
+
+cmdline_parse_token_string_t cmd_showbonding_config_show =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		show, "show");
+cmdline_parse_token_string_t cmd_showbonding_config_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_showbonding_config_config =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		config, "config");
+cmdline_parse_token_num_t cmd_showbonding_config_port =
+TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_config_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_show_bonding_config = {
+		.f = cmd_show_bonding_config_parsed,
+		.help_str =	"show bonding config (port_id): Show the bonding config for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_showbonding_config_show,
+				(void *)&cmd_showbonding_config_bonding,
+				(void *)&cmd_showbonding_config_config,
+				(void *)&cmd_showbonding_config_port,
+				NULL
+		}
+};
+
+/* *** SET BONDING PRIMARY *** */
+struct cmd_set_bonding_primary_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t primary;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_set_bonding_primary_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_primary_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_primary_set(master_port_id, slave_port_id)) {
+		printf("\t Failed to set primary slave for port = %d.\n",
+				master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_setbonding_primary_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_primary_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_primary_primary =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		primary, "primary");
+cmdline_parse_token_num_t cmd_setbonding_primary_slave =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+		slave_id, UINT8);
+cmdline_parse_token_num_t cmd_setbonding_primary_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bonding_primary = {
+		.f = cmd_set_bonding_primary_parsed,
+		.help_str = "set bonding primary (slave_id) (port_id): Set the primary slave for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_setbonding_primary_set,
+				(void *)&cmd_setbonding_primary_bonding,
+				(void *)&cmd_setbonding_primary_primary,
+				(void *)&cmd_setbonding_primary_slave,
+				(void *)&cmd_setbonding_primary_port,
+				NULL
+		}
+};
+
+/* *** ADD SLAVE *** */
+struct cmd_add_bonding_slave_result {
+	cmdline_fixed_string_t add;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t slave;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_add_bonding_slave_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_add_bonding_slave_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_slave_add(master_port_id, slave_port_id)) {
+		printf("\t Failed to add slave %d to master port = %d.\n",
+				slave_port_id, master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_addbonding_slave_add =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		add, "add");
+cmdline_parse_token_string_t cmd_addbonding_slave_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_addbonding_slave_slave =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		slave, "slave");
+cmdline_parse_token_num_t cmd_addbonding_slave_slaveid =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+		slave_id, UINT8);
+cmdline_parse_token_num_t cmd_addbonding_slave_port =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_add_bonding_slave = {
+		.f = cmd_add_bonding_slave_parsed,
+		.help_str = "add bonding slave (slave_id) (port_id): Add a slave device to a bonded device",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_addbonding_slave_add,
+				(void *)&cmd_addbonding_slave_bonding,
+				(void *)&cmd_addbonding_slave_slave,
+				(void *)&cmd_addbonding_slave_slaveid,
+				(void *)&cmd_addbonding_slave_port,
+				NULL
+		}
+};
+
+/* *** REMOVE SLAVE *** */
+struct cmd_remove_bonding_slave_result {
+	cmdline_fixed_string_t remove;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t slave;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_remove_bonding_slave_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_remove_bonding_slave_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_slave_remove(master_port_id, slave_port_id)) {
+		printf("\t Failed to remove slave %d from master port = %d.\n",
+				slave_port_id, master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_removebonding_slave_remove =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				remove, "remove");
+cmdline_parse_token_string_t cmd_removebonding_slave_bonding =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				bonding, "bonding");
+cmdline_parse_token_string_t cmd_removebonding_slave_slave =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				slave, "slave");
+cmdline_parse_token_num_t cmd_removebonding_slave_slaveid =
+		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				slave_id, UINT8);
+cmdline_parse_token_num_t cmd_removebonding_slave_port =
+		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				port_id, UINT8);
+
+cmdline_parse_inst_t cmd_remove_bonding_slave = {
+		.f = cmd_remove_bonding_slave_parsed,
+		.help_str = "remove bonding slave (slave_id) (port_id): Remove a slave device from a bonded device",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_removebonding_slave_remove,
+				(void *)&cmd_removebonding_slave_bonding,
+				(void *)&cmd_removebonding_slave_slave,
+				(void *)&cmd_removebonding_slave_slaveid,
+				(void *)&cmd_removebonding_slave_port,
+				NULL
+		}
+};
+
+/* *** CREATE BONDED DEVICE *** */
+struct cmd_create_bonded_device_result {
+	cmdline_fixed_string_t create;
+	cmdline_fixed_string_t bonded;
+	cmdline_fixed_string_t device;
+	uint8_t mode;
+	uint8_t socket;
+};
+
+static int bond_dev_num = 0;
+
+static void cmd_create_bonded_device_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_create_bonded_device_result *res = parsed_result;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+	int port_id;
+
+	if (test_done == 0) {
+		printf("Please stop forwarding first\n");
+		return;
+	}
+
+	snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "eth_bond_testpmd_%d",
+			bond_dev_num++);
+
+	/* Create a new bonded device. */
+	port_id = rte_eth_bond_create(ethdev_name, res->mode, res->socket);
+	if (port_id < 0) {
+		printf("\t Failed to create bonded device.\n");
+		return;
+	} else {
+		printf("Created new bonded device %s on (port %d).\n", ethdev_name,
+				port_id);
+
+		/* Update number of ports */
+		nb_ports = rte_eth_dev_count();
+		reconfig(port_id);
+		rte_eth_promiscuous_enable(port_id);
+	}
+
+}
+
+cmdline_parse_token_string_t cmd_createbonded_device_create =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				create, "create");
+cmdline_parse_token_string_t cmd_createbonded_device_bonded =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				bonded, "bonded");
+cmdline_parse_token_string_t cmd_createbonded_device_device =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				device, "device");
+cmdline_parse_token_num_t cmd_createbonded_device_mode =
+		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+				mode, UINT8);
+cmdline_parse_token_num_t cmd_createbonded_device_socket =
+		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+				socket, UINT8);
+
+cmdline_parse_inst_t cmd_create_bonded_device = {
+		.f = cmd_create_bonded_device_parsed,
+		.help_str = "create bonded device (mode) (socket): Create a new bonded device with specific bonding mode and socket",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_createbonded_device_create,
+				(void *)&cmd_createbonded_device_bonded,
+				(void *)&cmd_createbonded_device_device,
+				(void *)&cmd_createbonded_device_mode,
+				(void *)&cmd_createbonded_device_socket,
+				NULL
+		}
+};
+
+/* *** SET MAC ADDRESS IN BONDED DEVICE *** */
+struct cmd_set_bond_mac_addr_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t mac_addr;
+	uint8_t port_num;
+	struct ether_addr address;
+};
+
+static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bond_mac_addr_result *res = parsed_result;
+	int ret;
+
+	if (res->port_num >= nb_ports) {
+		printf("Port id %d must be less than %d\n", res->port_num, nb_ports);
+		return;
+	}
+
+	ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
+
+	/* check the return value and print it if is < 0 */
+	if (ret < 0)
+		printf("set_bond_mac_addr error: (%s)\n", strerror(-ret));
+}
+
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_set =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, set, "set");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, bonding,
+				"bonding");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, mac_addr,
+				"mac_addr");
+cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum =
+		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result, port_num, UINT8);
+cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr =
+		TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result, address);
+
+cmdline_parse_inst_t cmd_set_bond_mac_addr = {
+		.f = cmd_set_bond_mac_addr_parsed,
+		.data = (void *) 0,
+		.help_str = "set bonding mac_addr (port_id) (address): ",
+		.tokens = {
+				(void *)&cmd_set_bond_mac_addr_set,
+				(void *)&cmd_set_bond_mac_addr_bonding,
+				(void *)&cmd_set_bond_mac_addr_mac,
+				(void *)&cmd_set_bond_mac_addr_portnum,
+				(void *)&cmd_set_bond_mac_addr_addr,
+				NULL
+		}
+};
+
+#endif /* RTE_LIBRTE_PMD_BOND */
+
 /* *** SET FORWARDING MODE *** */
 struct cmd_set_fwd_mode_result {
 	cmdline_fixed_string_t set;
@@ -6572,6 +7141,16 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_bypass_timeout,
 	(cmdline_parse_inst_t *)&cmd_show_bypass_config,
 #endif
+#ifdef RTE_LIBRTE_PMD_BOND
+	(cmdline_parse_inst_t *) &cmd_set_bonding_mode,
+	(cmdline_parse_inst_t *) &cmd_show_bonding_config,
+	(cmdline_parse_inst_t *) &cmd_set_bonding_primary,
+	(cmdline_parse_inst_t *) &cmd_add_bonding_slave,
+	(cmdline_parse_inst_t *) &cmd_remove_bonding_slave,
+	(cmdline_parse_inst_t *) &cmd_create_bonded_device,
+	(cmdline_parse_inst_t *) &cmd_set_bond_mac_addr,
+	(cmdline_parse_inst_t *) &cmd_set_balance_xmit_policy,
+#endif
 	(cmdline_parse_inst_t *)&cmd_vlan_offload,
 	(cmdline_parse_inst_t *)&cmd_vlan_tpid,
 	(cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all,
app/test-pmd/config.c +3 -1
index 32f2134..c72f6ee 100644
@@ -252,6 +252,7 @@ void
 port_infos_display(portid_t port_id)
 {
 	struct rte_port *port;
+	struct ether_addr mac_addr;
 	struct rte_eth_link link;
 	int vlan_offload;
 	struct rte_mempool * mp;
@@ -265,7 +266,8 @@ port_infos_display(portid_t port_id)
 	rte_eth_link_get_nowait(port_id, &link);
 	printf("\n%s Infos for port %-2d %s\n",
 	       info_border, port_id, info_border);
-	print_ethaddr("MAC address: ", &port->eth_addr);
+	rte_eth_macaddr_get(port_id, &mac_addr);
+	print_ethaddr("MAC address: ", &mac_addr);
 	printf("\nConnect to socket: %u", port->socket_id);
 
 	if (port_numa[port_id] != NUMA_NO_CONFIG) {
app/test-pmd/parameters.c +3 -0
index 4bca0b0..9573a43 100644
@@ -75,6 +75,9 @@
 #include <cmdline_parse.h>
 #include <cmdline_parse_etheraddr.h>
 #endif
+#ifdef RTE_LIBRTE_PMD_BOND
+#include <rte_eth_bond.h>
+#endif
 
 #include "testpmd.h"
 
app/test-pmd/testpmd.c +32 -8
index 16fe596..e8a4b45 100644
@@ -300,7 +300,7 @@ struct rte_fdir_conf fdir_conf = {
 	.drop_queue = 127,
 };
 
-static volatile int test_done = 1; /* stop packet forwarding when set to 1. */
+volatile int test_done = 1; /* stop packet forwarding when set to 1. */
 
 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
@@ -625,6 +625,32 @@ init_config(void)
 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
 }
 
+
+void
+reconfig(portid_t new_port_id)
+{
+	struct rte_port *port;
+
+	/* Reconfiguration of Ethernet ports. */
+	ports = rte_realloc(ports,
+			    sizeof(struct rte_port) * nb_ports,
+			    CACHE_LINE_SIZE);
+	if (ports == NULL) {
+		rte_exit(EXIT_FAILURE, "rte_realloc(%d struct rte_port) failed\n",
+				nb_ports);
+	}
+
+	port = &ports[new_port_id];
+	rte_eth_dev_info_get(new_port_id, &port->dev_info);
+
+	/* set flag to initialize port/queue */
+	port->need_reconfig = 1;
+	port->need_reconfig_queues = 1;
+
+	init_port_config();
+}
+
+
 int
 init_fwd_streams(void)
 {
@@ -1252,7 +1278,7 @@ start_port(portid_t pid)
 	portid_t pi;
 	queueid_t qi;
 	struct rte_port *port;
-	uint8_t *mac_addr;
+	struct ether_addr mac_addr;
 
 	if (test_done == 0) {
 		printf("Please stop forwarding first\n");
@@ -1380,10 +1406,11 @@ start_port(portid_t pid)
 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
 			printf("Port %d can not be set into started\n", pi);
 
-		mac_addr = port->eth_addr.addr_bytes;
+		rte_eth_macaddr_get(pi, &mac_addr);
 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
-		       mac_addr[0], mac_addr[1], mac_addr[2],
-		       mac_addr[3], mac_addr[4], mac_addr[5]);
+				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
+				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
+				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
 
 		/* at least one port started, need checking link status */
 		need_check_link_status = 1;
@@ -1826,9 +1853,6 @@ main(int argc, char** argv)
 	if (diag < 0)
 		rte_panic("Cannot init EAL\n");
 
-	if (rte_eal_pci_probe())
-		rte_panic("Cannot probe PCI\n");
-
 	nb_ports = (portid_t) rte_eth_dev_count();
 	if (nb_ports == 0)
 		rte_exit(EXIT_FAILURE, "No probed ethernet devices - "
app/test-pmd/testpmd.h +2 -0
index e263616..ac86bfe 100644
@@ -281,6 +281,7 @@ extern uint16_t port_topology; /**< set by "--port-topology" parameter */
 extern uint8_t no_flush_rx; /**<set by "--no-flush-rx" parameter */
 extern uint8_t  mp_anon; /**< set by "--mp-anon" parameter */
 extern uint8_t no_link_check; /**<set by "--disable-link-check" parameter */
+extern volatile int test_done; /* stop packet forwarding when set to 1. */
 
 #ifdef RTE_NIC_BYPASS
 extern uint32_t bypass_timeout; /**< Store the NIC bypass watchdog timeout */
@@ -454,6 +455,7 @@ void fwd_config_display(void);
 void rxtx_config_display(void);
 void fwd_config_setup(void);
 void set_def_fwd_config(void);
+void reconfig(portid_t new_port_id);
 int init_fwd_streams(void);
 
 void port_mtu_set(portid_t port_id, uint16_t mtu);
Signature · 1 line
2.0.0
#101 lore raw

v10 cover link bonding

In reply to a message not in the archive

Fixed copyright in link bonding library Makefile

Declan Doherty (5):
bond: new link bonding library
ethdev: add unique name to devices
eal: support link bonding device initialization
bond: unit tests
bond: testpmd support

 app/test-pmd/cmdline.c                      |  579 ++++
 app/test-pmd/config.c                       |    4 +-
 app/test-pmd/parameters.c                   |    3 +
 app/test-pmd/testpmd.c                      |   40 +-
 app/test-pmd/testpmd.h                      |    2 +
 app/test/Makefile                           |    4 +-
 app/test/commands.c                         |    7 +
 app/test/packet_burst_generator.c           |  287 ++
 app/test/packet_burst_generator.h           |   78 +
 app/test/test.h                             |    1 +
 app/test/test_link_bonding.c                | 3958 +++++++++++++++++++++++++++
 app/test/virtual_pmd.c                      |  574 ++++
 app/test/virtual_pmd.h                      |   74 +
 config/common_bsdapp                        |    5 +
 config/common_linuxapp                      |    5 +
 doc/doxy-api-index.md                       |    1 +
 doc/doxy-api.conf                           |    1 +
 lib/Makefile                                |    1 +
 lib/librte_eal/bsdapp/eal/eal.c             |   10 +-
 lib/librte_eal/common/eal_common_dev.c      |   58 +-
 lib/librte_eal/common/eal_common_pci.c      |    3 +
 lib/librte_eal/common/include/eal_private.h |    7 -
 lib/librte_eal/common/include/rte_dev.h     |   14 +-
 lib/librte_eal/linuxapp/eal/eal.c           |   11 +-
 lib/librte_ether/rte_ethdev.c               |   31 +-
 lib/librte_ether/rte_ethdev.h               |    7 +-
 lib/librte_pmd_bond/Makefile                |   61 +
 lib/librte_pmd_bond/rte_eth_bond.h          |  255 ++
 lib/librte_pmd_bond/rte_eth_bond_api.c      |  662 +++++
 lib/librte_pmd_bond/rte_eth_bond_args.c     |  252 ++
 lib/librte_pmd_bond/rte_eth_bond_pmd.c      | 1212 ++++++++
 lib/librte_pmd_bond/rte_eth_bond_private.h  |  215 ++
 lib/librte_pmd_pcap/rte_eth_pcap.c          |   22 +-
 lib/librte_pmd_ring/rte_eth_ring.c          |   32 +-
 lib/librte_pmd_ring/rte_eth_ring.h          |    3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |    2 +-
 mk/rte.app.mk                               |    4 +
 37 files changed, 8414 insertions(+), 71 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_api.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_args.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_pmd.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_private.h

A message that is not in the archive (sent off-list or not yet received): 1403864324-12022-1-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#103 lore raw

Re: [PATCH v10 0/5] link bonding

2014-06-27 11:18, Declan Doherty:

Quoted 1 line

Fixed copyright in link bonding library Makefile

A small fix is needed in Makefile for renaming of file rte_eth_bond_args.c.

And more important, it cannot be built as an optional shared library as test applications call functions from the specific API.
The best design would be to have a base library always linked and an optional PMD layer.

Signature · 1 line
Thomas
#104 lore raw

v11 cover link bonding library

In reply to a message not in the archive

Hi Thomas,
This patchset contains the name change fix in the link bonding library makefile. I have also put a change into the unit test application makefile so that the link bonding tests are not built if the library is also not being built. It doesn't make sense to split the bonding libraries APIs into a seperate library, as they are directly coupled to with the bonding library implmentation

Declan Doherty (5):
bond: new link bonding library
ethdev: add unique name to devices
eal: support link bonding device initialization
bond: unit tests
bond: testpmd support

 app/test-pmd/cmdline.c                      |  579 ++++
 app/test-pmd/config.c                       |    4 +-
 app/test-pmd/parameters.c                   |    3 +
 app/test-pmd/testpmd.c                      |   40 +-
 app/test-pmd/testpmd.h                      |    2 +
 app/test/Makefile                           |    6 +-
 app/test/commands.c                         |    7 +
 app/test/packet_burst_generator.c           |  287 ++
 app/test/packet_burst_generator.h           |   78 +
 app/test/test.h                             |    1 +
 app/test/test_link_bonding.c                | 3958 +++++++++++++++++++++++++++
 app/test/virtual_pmd.c                      |  574 ++++
 app/test/virtual_pmd.h                      |   74 +
 config/common_bsdapp                        |    5 +
 config/common_linuxapp                      |    5 +
 doc/doxy-api-index.md                       |    1 +
 doc/doxy-api.conf                           |    1 +
 lib/Makefile                                |    1 +
 lib/librte_eal/bsdapp/eal/eal.c             |   10 +-
 lib/librte_eal/common/eal_common_dev.c      |   58 +-
 lib/librte_eal/common/eal_common_pci.c      |    3 +
 lib/librte_eal/common/include/eal_private.h |    7 -
 lib/librte_eal/common/include/rte_dev.h     |   14 +-
 lib/librte_eal/linuxapp/eal/eal.c           |   11 +-
 lib/librte_ether/rte_ethdev.c               |   31 +-
 lib/librte_ether/rte_ethdev.h               |    7 +-
 lib/librte_pmd_bond/Makefile                |   61 +
 lib/librte_pmd_bond/rte_eth_bond.h          |  255 ++
 lib/librte_pmd_bond/rte_eth_bond_api.c      |  662 +++++
 lib/librte_pmd_bond/rte_eth_bond_args.c     |  252 ++
 lib/librte_pmd_bond/rte_eth_bond_pmd.c      | 1212 ++++++++
 lib/librte_pmd_bond/rte_eth_bond_private.h  |  215 ++
 lib/librte_pmd_pcap/rte_eth_pcap.c          |   22 +-
 lib/librte_pmd_ring/rte_eth_ring.c          |   32 +-
 lib/librte_pmd_ring/rte_eth_ring.h          |    3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c    |    2 +-
 mk/rte.app.mk                               |    4 +
 37 files changed, 8416 insertions(+), 71 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_api.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_args.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_pmd.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_private.h

A message that is not in the archive (sent off-list or not yet received): 1404064161-26370-1-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#106 lore raw

Re: [PATCH v11 0/5] link bonding library

Hi Declan,

2014-06-29 18:49, Declan Doherty:

Quoted 6 lines

This patchset contains the name change fix in the link bonding library makefile. I have also put a change into the unit test application makefile so that the link bonding tests are not built if the library is also not being built. It doesn't make sense to split the bonding libraries APIs into a seperate library, as they are directly coupled to with the bonding library implmentation

You fixed optional building but there is still an issue when building shared library.
As you don't want to split the library to separate the PMD plugin from the specific API, I suggest to not consider it as a plugin (unlike other PMDs).

I've sent some patches about these 2 topics. If you agree, I'll apply them, merged with your serie.

Thanks

Signature · 1 line
Thomas
#107 lore raw

Re: [PATCH v11 0/5] link bonding library

Quoted 22 lines

-----Original Message-----
From: Thomas Monjalon [mailto:[email protected]]
Sent: Monday, June 30, 2014 10:21 AM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [PATCH v11 0/5] link bonding library

Hi Declan,

2014-06-29 18:49, Declan Doherty:

Quoted 6 lines

This patchset contains the name change fix in the link bonding library makefile. I have also put a change into the unit test application makefile so that the link bonding tests are not built if the library is also not being built. It doesn't make sense to split the bonding libraries APIs into a seperate library, as they are directly coupled to with the bonding library implmentation

You fixed optional building but there is still an issue when building shared library.
As you don't want to split the library to separate the PMD plugin from the specific API, I suggest to not consider it as a plugin (unlike other PMDs).

Quoted 6 lines

I've sent some patches about these 2 topics. If you agree, I'll apply them, merged with your serie.

Thanks
--
Thomas

Hi Thomas,
I'm happy for you to apply the makefile changes you have suggested and not consider the bonding PMD as a plugin, I think this makes the most sense considering it is a purely software library.

Thanks
Declan

A message that is not in the archive (sent off-list or not yet received): 345C63BAECC1AD42A2EC8C63AFFC3ADC2730631F-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org

#109 lore raw

Re: [PATCH v11 0/5] link bonding library

2014-06-30 09:28, Doherty, Declan:

Quoted 21 lines
Quoted 21 lines

-----Original Message-----
From: Thomas Monjalon [mailto:[email protected]]

Hi Declan,

2014-06-29 18:49, Declan Doherty:

Quoted 8 lines

This patchset contains the name change fix in the link bonding library makefile. I have also put a change into the unit test application makefile
so that the link bonding tests are not built if the library is also not being built. It doesn't make sense to split the bonding libraries APIs into
a seperate library, as they are directly coupled to with the bonding library implmentation

You fixed optional building but there is still an issue when building shared library.
As you don't want to split the library to separate the PMD plugin from the specific API, I suggest to not consider it as a plugin (unlike other PMDs).

Quoted 6 lines
Quoted 2 lines

I've sent some patches about these 2 topics. If you agree, I'll apply them, merged with your serie.

I'm happy for you to apply the makefile changes you have suggested and not consider the bonding PMD as a plugin, I think this makes the most sense considering it is a purely software library.

Applied with Robert's changes for version 1.7.0.

Thanks for all these revisions (v11 is currently the best score :)

Signature · 1 line
Thomas
#110 lore raw

PATCH v11 1/5 bond: new link bonding library

In reply to a message not in the archive

Initial release with support for
Mode 0 - Round Robin
Mode 1 - Active Backup
Mode 2 - Balance -> Supports 3 transmit polices (layer 2, layer 2+3, layer 3+4) Mode 3 - Broadcast

---
 config/common_bsdapp                       |    5 +
 config/common_linuxapp                     |    5 +
 doc/doxy-api-index.md                      |    1 +
 doc/doxy-api.conf                          |    1 +
 lib/Makefile                               |    1 +
 lib/librte_pmd_bond/Makefile               |   61 ++
 lib/librte_pmd_bond/rte_eth_bond.h         |  255 ++++++
 lib/librte_pmd_bond/rte_eth_bond_api.c     |  662 +++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond_args.c    |  252 ++++++
 lib/librte_pmd_bond/rte_eth_bond_pmd.c     | 1212 ++++++++++++++++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond_private.h |  215 +++++
 mk/rte.app.mk                              |    4 +
 12 files changed, 2674 insertions(+), 0 deletions(-)
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_api.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_args.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_pmd.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_private.h
config/common_bsdapp +5 -0
index d5db4ab..c243b0c 100644
@@ -206,6 +206,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=y
 
 #
+# Compile link bonding PMD library
+#
+CONFIG_RTE_LIBRTE_PMD_BOND=y
+
+#
 # Do prefetch of packet data within PMD driver receive function
 #
 CONFIG_RTE_PMD_PACKET_PREFETCH=y
config/common_linuxapp +5 -0
index c5c0cb6..6237ce5 100644
@@ -244,6 +244,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=n
 
 #
+# Compile link bonding PMD library
+#
+CONFIG_RTE_LIBRTE_PMD_BOND=y
+
+#
 # Compile Xen PMD
 #
 CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
doc/doxy-api-index.md +1 -0
index 7b26e98..d72659a 100644
@@ -38,6 +38,7 @@ There are many libraries, so their headers may be grouped by topics:
 - **device**:
   [ethdev]             (@ref rte_ethdev.h),
   [devargs]            (@ref rte_devargs.h),
+  [bond]               (@ref rte_eth_bond.h),
   [KNI]                (@ref rte_kni.h),
   [PCI]                (@ref rte_pci.h),
   [PCI IDs]            (@ref rte_pci_dev_ids.h)
doc/doxy-api.conf +1 -0
index f380d9a..1fd4492 100644
@@ -47,6 +47,7 @@ INPUT                   = doc/doxy-api-index.md \
                           lib/librte_pipeline \
                           lib/librte_port \
                           lib/librte_power \
+                          lib/librte_pmd_bond \
                           lib/librte_ring \
                           lib/librte_sched \
                           lib/librte_table \
lib/Makefile +1 -0
index c58c0c9..10c5bb3 100644
@@ -44,6 +44,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
 DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += librte_pmd_e1000
 DIRS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += librte_pmd_ixgbe
 DIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += librte_pmd_i40e
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += librte_pmd_bond
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_RING) += librte_pmd_ring
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += librte_pmd_pcap
 DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += librte_pmd_virtio
lib/librte_pmd_bond/Makefile new file +61 -0

61 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond.h new file +255 -0

255 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_api.c new file +662 -0

662 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_args.c new file +252 -0

252 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_pmd.c new file +1212 -0

1,212 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_private.h new file +215 -0

215 lines not on this page · raw message

mk/rte.app.mk +4 -0
index 8db9cde..a4624e5 100644
@@ -205,6 +205,10 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMD_PCAP),y)
 LDLIBS += -lrte_pmd_pcap -lpcap
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_PMD_BOND),y)
+LDLIBS += -lrte_pmd_bond
+endif
+
 endif
 
 LDLIBS += $(EXECENV_LDLIBS)
Signature · 1 line
1.7.0.7

A message that is not in the archive (sent off-list or not yet received): 1404064161-26370-2-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#112 lore raw

Re: [PATCH v11 1/5] bond: new link bonding library

Hi Declan,

2014-06-29 18:49, Declan Doherty:

mk/rte.app.mk ifeq ($(CONFIG_RTE_LIBRTE_PMD_PCAP),y) · line 212

Quoted 11 lines
mk/rte.app.mk +4 -0
@@ -205,6 +205,10 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMD_PCAP),y)
 LDLIBS += -lrte_pmd_pcap -lpcap
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_PMD_BOND),y)
+LDLIBS += -lrte_pmd_bond
+endif
+
 endif

This part is linking bonding library only in case of static libraries. But this library has a specific API. So it cannot be a plugin and must always be linked. That's why I suggested to split the library.
Instead, I suggest to always link with bonding library. See my proposal below:

mk/rte.app.mk +6 -1
@@ -175,7 +175,12 @@ LDLIBS += -lrte_pmd_xenvirt
 LDLIBS += -lxenstore
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_PMD_BOND),y)
+LDLIBS += -lrte_pmd_bond
+endif
+
 ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+# plugins (link only if static libraries)
 
 ifeq ($(CONFIG_RTE_LIBRTE_VMXNET3_PMD),y)
 LDLIBS += -lrte_pmd_vmxnet3_uio
@@ -205,7 +210,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMD_PCAP),y)
 LDLIBS += -lrte_pmd_pcap -lpcap
 endif
 
-endif
+endif # plugins (link only if static libraries)
 
 

Adding comments to explain plugin section will be clearer.

Signature · 1 line
Thomas
#113 lore raw

Re: [PATCH v11 1/5] bond: new link bonding library

In reply to a message not in the archive

Hi Declan,

Quoted 21 lines · Declan Doherty

Initial release with support for
Mode 0 - Round Robin
Mode 1 - Active Backup
Mode 2 - Balance -> Supports 3 transmit polices (layer 2, layer 2+3,
layer 3+4)
Mode 3 - Broadcast

---
 config/common_bsdapp                       |    5 +
 config/common_linuxapp                     |    5 +
 doc/doxy-api-index.md                      |    1 +
 doc/doxy-api.conf                          |    1 +
 lib/Makefile                               |    1 +
 lib/librte_pmd_bond/Makefile               |   61 ++
 lib/librte_pmd_bond/rte_eth_bond.h         |  255 ++++++
 lib/librte_pmd_bond/rte_eth_bond_api.c     |  662 +++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond_args.c    |  252 ++++++
 lib/librte_pmd_bond/rte_eth_bond_pmd.c     | 1212
++++++++++++++++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond_private.h |  215 +++++
Quoted 11 lines
 mk/rte.app.mk                              |    4 +
 12 files changed, 2674 insertions(+), 0 deletions(-)
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_api.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_args.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_pmd.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_private.h

I see a potential problem with bond_ethdev_rx_burst( ).
We could receive more packets than the caller asked for, and overrun the caller's rte_mbuf * array.
The fix could be something like this:

lib/librte_pmd_bond/rte_eth_bond_pmd.c +0 -0
@@ -73,13 +73,15 @@ bond_ethdev_rx_burst(void *queue, struct rte_mbuf

**bufs, uint16_t nb_pkts)
case BONDING_MODE_ROUND_ROBIN:
case BONDING_MODE_BROADCAST:
case BONDING_MODE_BALANCE:
- for (i = 0; i < internals->active_slave_count; i++) {
+ for (i = 0; i < internals->active_slave_count && nb_pkts;

i++) {
                        /* Offset of pointer to *bufs increases as packets

are received
* from other slaves */
num_rx_slave =
rte_eth_rx_burst(internals->active_slaves[i],

                                        bd_rx_q->queue_id, bufs +
num_rx_total, nb_pkts);
-                       if (num_rx_slave)
+                       if (num_rx_slave) {
                                num_rx_total += num_rx_slave;
+                               nb_pkts -= num_rx_slave;
+                       }
                }
                break;
        case BONDING_MODE_ACTIVE_BACKUP:

--
Regards,
Robert

A message that is not in the archive (sent off-list or not yet received): CA+cr1cojs0sx5s1ohwVcdT6ojQ_7PEwEAqmtCca0LAz_jkvVdw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org

#115 lore raw

Re: [PATCH v11 1/5] bond: new link bonding library

Hi Declan,

Do you confirm we should merge the Robert's patch in rc3?

2014-06-30 18:29, Robert Sanford:

Quoted 30 lines

I see a potential problem with bond_ethdev_rx_burst( ).
We could receive more packets than the caller asked for, and overrun the caller's rte_mbuf * array.
The fix could be something like this:

lib/librte_pmd_bond/rte_eth_bond_pmd.c +1 -1
@@ -73,13 +73,15 @@ bond_ethdev_rx_burst(void *queue, struct rte_mbuf
 **bufs, uint16_t nb_pkts)
        case BONDING_MODE_ROUND_ROBIN:
        case BONDING_MODE_BROADCAST:
        case BONDING_MODE_BALANCE:
-               for (i = 0; i < internals->active_slave_count; i++) {
+               for (i = 0; i < internals->active_slave_count && nb_pkts;
 i++) {
                        /* Offset of pointer to *bufs increases as packets

are received
* from other slaves */
num_rx_slave =
rte_eth_rx_burst(internals->active_slaves[i],

                                        bd_rx_q->queue_id, bufs +

num_rx_total, nb_pkts);

lib/librte_pmd_bond/rte_eth_bond_pmd.c +3 -1
-                       if (num_rx_slave)
+                       if (num_rx_slave) {
                                num_rx_total += num_rx_slave;
+                               nb_pkts -= num_rx_slave;
+                       }
                }
                break;
        case BONDING_MODE_ACTIVE_BACKUP:
#116 lore raw

Re: [PATCH v11 1/5] bond: new link bonding library

In reply to a message not in the archive

From: Robert Sanford [mailto:[email protected]]
Sent: Monday, June 30, 2014 11:30 PM
To: Doherty, Declan
Cc: [email protected]
Subject: Re: [dpdk-dev] [PATCH v11 1/5] bond: new link bonding library

Hi Declan,

On Sun, Jun 29, 2014 at 1:49 PM, Declan Doherty <[email protected]<mailto:[email protected]>> wrote:
Initial release with support for
Mode 0 - Round Robin
Mode 1 - Active Backup
Mode 2 - Balance -> Supports 3 transmit polices (layer 2, layer 2+3, layer 3+4)
Mode 3 - Broadcast

---
 config/common_bsdapp                       |    5 +
 config/common_linuxapp                     |    5 +
 doc/doxy-api-index.md<http://doxy-api-index.md>                      |    1 +
 doc/doxy-api.conf                          |    1 +
 lib/Makefile                               |    1 +
 lib/librte_pmd_bond/Makefile               |   61 ++
 lib/librte_pmd_bond/rte_eth_bond.h         |  255 ++++++
 lib/librte_pmd_bond/rte_eth_bond_api.c     |  662 +++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond_args.c    |  252 ++++++
 lib/librte_pmd_bond/rte_eth_bond_pmd.c     | 1212 ++++++++++++++++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond_private.h |  215 +++++
 mk/rte.app.mk<http://rte.app.mk>                              |    4 +
 12 files changed, 2674 insertions(+), 0 deletions(-)
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_api.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_args.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_pmd.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_private.h

I see a potential problem with bond_ethdev_rx_burst( ).
We could receive more packets than the caller asked for, and overrun the caller's rte_mbuf * array. The fix could be something like this:

lib/librte_pmd_bond/rte_eth_bond_pmd.c +4 -2
@@ -73,13 +73,15 @@ bond_ethdev_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
        case BONDING_MODE_ROUND_ROBIN:
        case BONDING_MODE_BROADCAST:
        case BONDING_MODE_BALANCE:
-               for (i = 0; i < internals->active_slave_count; i++) {
+               for (i = 0; i < internals->active_slave_count && nb_pkts; i++) {
                        /* Offset of pointer to *bufs increases as packets are received
                         * from other slaves */
                        num_rx_slave = rte_eth_rx_burst(internals->active_slaves[i],
                                        bd_rx_q->queue_id, bufs + num_rx_total, nb_pkts);
-                       if (num_rx_slave)
+                       if (num_rx_slave) {
                                num_rx_total += num_rx_slave;
+                               nb_pkts -= num_rx_slave;
+                       }
                }
                break;
        case BONDING_MODE_ACTIVE_BACKUP:

--
Regards,
Robert

Hi Robert, yes I see this could be an issue, although this currently shouldn’t cause an issue, as the currently supported bonding modes only expected to receive data on one slave at any time, if they are being used as part of a ether channel but when we add further bonding modes are which receive data on multiple slaves this would definitely be a problem.

Thomas, I’ve tested the above changes, is it possible to integrate this patch with the patchset for link bonding for the rc3.

Thanks
Declan

A message that is not in the archive (sent off-list or not yet received): 345C63BAECC1AD42A2EC8C63AFFC3ADC273077A5-kPTMFJFq+rF9qrmMLTLiibfspsVTdybXVpNB7YpNyf8@public.gmane.org

#118 lore raw

Re: [PATCH v11 1/5] bond: new link bonding library

2014-07-01 14:19, Doherty, Declan:

Quoted 8 lines

Hi Robert, yes I see this could be an issue, although this currently shouldn’t cause an issue, as the currently supported bonding modes only expected to receive data on one slave at any time, if they are being used as part of a ether channel but when we add further bonding modes are which receive data on multiple slaves this would definitely be a problem.

Thomas, I’ve tested the above changes, is it possible to integrate this patch with the patchset for link bonding for the rc3.

No problem.
It will be in.

Thanks Declan & Robert

Signature · 1 line
Thomas
#119 lore raw

PATCH v11 2/5 ethdev: add unique name to devices

In reply to a message not in the archive

Adding support to rte_eth_dev_data structure to support unique name identifier for ethdevs to support adding slave ethdevs (specifically virtual devices which have no public unique identifier) to a link bonding device. This changes the API rte_eth_dev_allocate() to require a const char *name when allocating a ethdev, which also verifies that the name is unique and hasn’t been already used by an existed allocated rte_eth_dev. Also contains updates to virtual pmd’s to now call the API with a name parameter.

---
 lib/librte_ether/rte_ethdev.c            |   31 ++++++++++++++++++++++++++--
 lib/librte_ether/rte_ethdev.h            |    7 +++++-
 lib/librte_pmd_pcap/rte_eth_pcap.c       |   22 ++++++++++----------
 lib/librte_pmd_ring/rte_eth_ring.c       |   32 +++++++++++++++--------------
 lib/librte_pmd_ring/rte_eth_ring.h       |    3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c |    2 +-
 6 files changed, 65 insertions(+), 32 deletions(-)
lib/librte_ether/rte_ethdev.c +28 -3
index ef81a76..0ebb8fb 100644
@@ -65,6 +65,7 @@
 #include <rte_mbuf.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
+#include <rte_string_fns.h>
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"
@@ -153,21 +154,39 @@ rte_eth_dev_data_alloc(void)
 				RTE_MAX_ETHPORTS * sizeof(*rte_eth_dev_data));
 }
 
+static struct rte_eth_dev *
+rte_eth_dev_allocated(const char *name)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_ports; i++) {
+		if (strcmp(rte_eth_devices[i].data->name, name) == 0)
+			return &rte_eth_devices[i];
+	}
+	return NULL;
+}
+
 struct rte_eth_dev *
-rte_eth_dev_allocate(void)
+rte_eth_dev_allocate(const char *name)
 {
 	struct rte_eth_dev *eth_dev;
 
 	if (nb_ports == RTE_MAX_ETHPORTS) {
-		PMD_DEBUG_TRACE("Reached maximum number of ethernet ports\n");
+		PMD_DEBUG_TRACE("Reached maximum number of Ethernet ports\n");
 		return NULL;
 	}
 
 	if (rte_eth_dev_data == NULL)
 		rte_eth_dev_data_alloc();
 
+	if (rte_eth_dev_allocated(name) != NULL) {
+		PMD_DEBUG_TRACE("Ethernet Device with name %s already allocated!\n");
+		return NULL;
+	}
+
 	eth_dev = &rte_eth_devices[nb_ports];
 	eth_dev->data = &rte_eth_dev_data[nb_ports];
+	snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
 	eth_dev->data->port_id = nb_ports++;
 	return eth_dev;
 }
@@ -178,11 +197,17 @@ rte_eth_dev_init(struct rte_pci_driver *pci_drv,
 {
 	struct eth_driver    *eth_drv;
 	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
 	int diag;
 
 	eth_drv = (struct eth_driver *)pci_drv;
 
-	eth_dev = rte_eth_dev_allocate();
+	/* Create unique Ethernet device name using PCI address */
+	snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "%d:%d.%d",
+			pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
+
+	eth_dev = rte_eth_dev_allocate(ethdev_name);
 	if (eth_dev == NULL)
 		return -ENOMEM;
 
lib/librte_ether/rte_ethdev.h +6 -1
index 2406e45..50df654 100644
@@ -1497,6 +1497,8 @@ struct rte_eth_dev_sriov {
 };
 #define RTE_ETH_DEV_SRIOV(dev)         ((dev)->data->sriov)
 
+#define RTE_ETH_NAME_MAX_LEN (32)
+
 /**
  * @internal
  * The data part, with no function pointers, associated with each ethernet device.
@@ -1505,6 +1507,8 @@ struct rte_eth_dev_sriov {
  * processes in a multi-process configuration.
  */
 struct rte_eth_dev_data {
+	char name[RTE_ETH_NAME_MAX_LEN]; /**< Unique identifier name */
+
 	void **rx_queues; /**< Array of pointers to RX queues. */
 	void **tx_queues; /**< Array of pointers to TX queues. */
 	uint16_t nb_rx_queues; /**< Number of RX queues. */
@@ -1560,10 +1564,11 @@ extern uint8_t rte_eth_dev_count(void);
  * Allocates a new ethdev slot for an ethernet device and returns the pointer
  * to that slot for the driver to use.
  *
+ * @param	name	Unique identifier name for each Ethernet device
  * @return
  *   - Slot in the rte_dev_devices array for a new device;
  */
-struct rte_eth_dev *rte_eth_dev_allocate(void);
+struct rte_eth_dev *rte_eth_dev_allocate(const char *name);
 
 struct eth_driver;
 /**
lib/librte_pmd_pcap/rte_eth_pcap.c +11 -11
index b3dbbda..12b7e0c 100644
@@ -534,7 +534,7 @@ open_tx_iface(const char *key __rte_unused, const char *value, void *extra_args)
 
 
 static int
-rte_pmd_init_internals(const unsigned nb_rx_queues,
+rte_pmd_init_internals(const char *name, const unsigned nb_rx_queues,
 		const unsigned nb_tx_queues,
 		const unsigned numa_node,
 		struct pmd_internals **internals,
@@ -558,20 +558,20 @@ rte_pmd_init_internals(const unsigned nb_rx_queues,
 	/* now do all data allocation - for eth_dev structure, dummy pci driver
 	 * and internal (private) data
 	 */
-	data = rte_zmalloc_socket(NULL, sizeof(*data), 0, numa_node);
+	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
 	if (data == NULL)
 		goto error;
 
-	pci_dev = rte_zmalloc_socket(NULL, sizeof(*pci_dev), 0, numa_node);
+	pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, numa_node);
 	if (pci_dev == NULL)
 		goto error;
 
-	*internals = rte_zmalloc_socket(NULL, sizeof(**internals), 0, numa_node);
+	*internals = rte_zmalloc_socket(name, sizeof(**internals), 0, numa_node);
 	if (*internals == NULL)
 		goto error;
 
 	/* reserve an ethdev entry */
-	*eth_dev = rte_eth_dev_allocate();
+	*eth_dev = rte_eth_dev_allocate(name);
 	if (*eth_dev == NULL)
 		goto error;
 
@@ -617,7 +617,7 @@ rte_pmd_init_internals(const unsigned nb_rx_queues,
 }
 
 static int
-rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
+rte_eth_from_pcaps_n_dumpers(const char *name, pcap_t * const rx_queues[],
 		const unsigned nb_rx_queues,
 		pcap_dumper_t * const tx_queues[],
 		const unsigned nb_tx_queues,
@@ -634,7 +634,7 @@ rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
 	if (tx_queues == NULL && nb_tx_queues > 0)
 		return -1;
 
-	if (rte_pmd_init_internals(nb_rx_queues, nb_tx_queues, numa_node,
+	if (rte_pmd_init_internals(name, nb_rx_queues, nb_tx_queues, numa_node,
 			&internals, &eth_dev, kvlist) < 0)
 		return -1;
 
@@ -652,7 +652,7 @@ rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
 }
 
 static int
-rte_eth_from_pcaps(pcap_t * const rx_queues[],
+rte_eth_from_pcaps(const char *name, pcap_t * const rx_queues[],
 		const unsigned nb_rx_queues,
 		pcap_t * const tx_queues[],
 		const unsigned nb_tx_queues,
@@ -669,7 +669,7 @@ rte_eth_from_pcaps(pcap_t * const rx_queues[],
 	if (tx_queues == NULL && nb_tx_queues > 0)
 		return -1;
 
-	if (rte_pmd_init_internals(nb_rx_queues, nb_tx_queues, numa_node,
+	if (rte_pmd_init_internals(name, nb_rx_queues, nb_tx_queues, numa_node,
 			&internals, &eth_dev, kvlist) < 0)
 		return -1;
 
@@ -760,10 +760,10 @@ rte_pmd_pcap_devinit(const char *name, const char *params)
 		return -1;
 
 	if (using_dumpers)
-		return rte_eth_from_pcaps_n_dumpers(pcaps.pcaps, pcaps.num_of_rx,
+		return rte_eth_from_pcaps_n_dumpers(name, pcaps.pcaps, pcaps.num_of_rx,
 				dumpers.dumpers, dumpers.num_of_tx, numa_node, kvlist);
 
-	return rte_eth_from_pcaps(pcaps.pcaps, pcaps.num_of_rx, dumpers.pcaps,
+	return rte_eth_from_pcaps(name, pcaps.pcaps, pcaps.num_of_rx, dumpers.pcaps,
 			dumpers.num_of_tx, numa_node, kvlist);
 
 }
lib/librte_pmd_ring/rte_eth_ring.c +17 -15
index ce7ad71..73c649e 100644
@@ -219,7 +219,7 @@ static struct eth_dev_ops ops = {
 };
 
 int
-rte_eth_from_rings(struct rte_ring *const rx_queues[],
+rte_eth_from_rings(const char *name, struct rte_ring *const rx_queues[],
 		const unsigned nb_rx_queues,
 		struct rte_ring *const tx_queues[],
 		const unsigned nb_tx_queues,
@@ -243,20 +243,20 @@ rte_eth_from_rings(struct rte_ring *const rx_queues[],
 	/* now do all data allocation - for eth_dev structure, dummy pci driver
 	 * and internal (private) data
 	 */
-	data = rte_zmalloc_socket(NULL, sizeof(*data), 0, numa_node);
+	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
 	if (data == NULL)
 		goto error;
 
-	pci_dev = rte_zmalloc_socket(NULL, sizeof(*pci_dev), 0, numa_node);
+	pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, numa_node);
 	if (pci_dev == NULL)
 		goto error;
 
-	internals = rte_zmalloc_socket(NULL, sizeof(*internals), 0, numa_node);
+	internals = rte_zmalloc_socket(name, sizeof(*internals), 0, numa_node);
 	if (internals == NULL)
 		goto error;
 
 	/* reserve an ethdev entry */
-	eth_dev = rte_eth_dev_allocate();
+	eth_dev = rte_eth_dev_allocate(name);
 	if (eth_dev == NULL)
 		goto error;
 
@@ -335,7 +335,7 @@ eth_dev_ring_create(const char *name, const unsigned numa_node,
 			return -1;
 	}
 
-	if (rte_eth_from_rings(rxtx, num_rings, rxtx, num_rings, numa_node))
+	if (rte_eth_from_rings(name, rxtx, num_rings, rxtx, num_rings, numa_node))
 		return -1;
 
 	return 0;
@@ -352,29 +352,31 @@ eth_dev_ring_pair_create(const char *name, const unsigned numa_node,
 	struct rte_ring *rx[RTE_PMD_RING_MAX_RX_RINGS];
 	struct rte_ring *tx[RTE_PMD_RING_MAX_TX_RINGS];
 	unsigned i;
-	char rng_name[RTE_RING_NAMESIZE];
+	char rx_rng_name[RTE_RING_NAMESIZE];
+	char tx_rng_name[RTE_RING_NAMESIZE];
 	unsigned num_rings = RTE_MIN(RTE_PMD_RING_MAX_RX_RINGS,
 			RTE_PMD_RING_MAX_TX_RINGS);
 
 	for (i = 0; i < num_rings; i++) {
-		snprintf(rng_name, sizeof(rng_name), "ETH_RX%u_%s", i, name);
+		snprintf(rx_rng_name, sizeof(rx_rng_name), "ETH_RX%u_%s", i, name);
 		rx[i] = (action == DEV_CREATE) ?
-				rte_ring_create(rng_name, 1024, numa_node,
+				rte_ring_create(rx_rng_name, 1024, numa_node,
 						RING_F_SP_ENQ|RING_F_SC_DEQ) :
-				rte_ring_lookup(rng_name);
+				rte_ring_lookup(rx_rng_name);
 		if (rx[i] == NULL)
 			return -1;
-		snprintf(rng_name, sizeof(rng_name), "ETH_TX%u_%s", i, name);
+		snprintf(tx_rng_name, sizeof(tx_rng_name), "ETH_TX%u_%s", i, name);
 		tx[i] = (action == DEV_CREATE) ?
-				rte_ring_create(rng_name, 1024, numa_node,
+				rte_ring_create(tx_rng_name, 1024, numa_node,
 						RING_F_SP_ENQ|RING_F_SC_DEQ):
-				rte_ring_lookup(rng_name);
+				rte_ring_lookup(tx_rng_name);
 		if (tx[i] == NULL)
 			return -1;
 	}
 
-	if (rte_eth_from_rings(rx, num_rings, tx, num_rings, numa_node) ||
-			rte_eth_from_rings(tx, num_rings, rx, num_rings, numa_node) )
+	if (rte_eth_from_rings(rx_rng_name, rx, num_rings, tx, num_rings,
+			numa_node) || rte_eth_from_rings(tx_rng_name, tx, num_rings, rx,
+					num_rings, numa_node))
 		return -1;
 
 	return 0;
lib/librte_pmd_ring/rte_eth_ring.h +2 -1
index ef29344..e6ae19e 100644
@@ -40,7 +40,8 @@ extern "C" {
 
 #include <rte_ring.h>
 
-int rte_eth_from_rings(struct rte_ring * const rx_queues[],
+int rte_eth_from_rings(const char *name,
+		struct rte_ring * const rx_queues[],
 		const unsigned nb_rx_queues,
 		struct rte_ring *const tx_queues[],
 		const unsigned nb_tx_queues,
lib/librte_pmd_xenvirt/rte_eth_xenvirt.c +1 -1
index 18c44f5..450332a 100644
@@ -647,7 +647,7 @@ eth_dev_xenvirt_create(const char *name, const char *params,
 		goto err;
 
 	/* reserve an ethdev entry */
-	eth_dev = rte_eth_dev_allocate();
+	eth_dev = rte_eth_dev_allocate(name);
 	if (eth_dev == NULL)
 		goto err;
 
Signature · 1 line
1.7.0.7
#120 lore raw

PATCH v11 3/5 eal: support link bonding device initialization

In reply to a message not in the archive

Updating functionality in EAL to support adding link bonding devices via –vdev option. Link bonding devices will be initialized after all physical devices have been probed and initialized.

---
 lib/librte_eal/bsdapp/eal/eal.c             |   10 ++++-
 lib/librte_eal/common/eal_common_dev.c      |   58 ++++++++++++++++++--------
 lib/librte_eal/common/eal_common_pci.c      |    3 +
 lib/librte_eal/common/include/eal_private.h |    7 ---
 lib/librte_eal/common/include/rte_dev.h     |   14 ++++++-
 lib/librte_eal/linuxapp/eal/eal.c           |   11 +++++-
 6 files changed, 74 insertions(+), 29 deletions(-)
lib/librte_eal/bsdapp/eal/eal.c +9 -1
index a1f014f..c53f63e 100644
@@ -874,7 +874,7 @@ rte_eal_init(int argc, char **argv)
 
 	rte_eal_mcfg_complete();
 
-	if (rte_eal_dev_init() < 0)
+	if (rte_eal_dev_init(PMD_INIT_PRE_PCI_PROBE) < 0)
 		rte_panic("Cannot init pmd devices\n");
 
 	RTE_LCORE_FOREACH_SLAVE(i) {
@@ -906,6 +906,14 @@ rte_eal_init(int argc, char **argv)
 	rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
 	rte_eal_mp_wait_lcore();
 
+	/* Probe & Initialize PCI devices */
+	if (rte_eal_pci_probe())
+			rte_panic("Cannot probe PCI\n");
+
+	/* Initialize any outstanding devices */
+	if (rte_eal_dev_init(PMD_INIT_POST_PCI_PROBE) < 0)
+		rte_panic("Cannot init pmd devices\n");
+
 	return fctret;
 }
 
lib/librte_eal/common/eal_common_dev.c +40 -18

77 lines not on this page · raw message

lib/librte_eal/common/eal_common_pci.c +3 -0
index af809a8..c637361 100644
@@ -150,6 +150,9 @@ rte_eal_pci_probe(void)
 		probe_all = 1;
 
 	TAILQ_FOREACH(dev, &pci_device_list, next) {
+		/* check if device has already been initialized */
+		if (dev->driver != NULL)
+			continue;
 
 		/* set devargs in PCI structure */
 		devargs = pci_devargs_lookup(dev);
lib/librte_eal/common/include/eal_private.h +0 -7
index 232fcec..b440ffb 100644
@@ -196,11 +196,4 @@ int rte_eal_intr_init(void);
  */
 int rte_eal_alarm_init(void);
 
-/**
- * This function initialises any virtual devices
- *
- * This function is private to the EAL.
- */
-int rte_eal_dev_init(void);
-
 #endif /* _EAL_PRIVATE_H_ */
lib/librte_eal/common/include/rte_dev.h +12 -2
index f7e3a10..d89f1a5 100644
@@ -62,6 +62,16 @@ typedef int (rte_dev_init_t)(const char *name, const char *args);
 enum pmd_type {
 	PMD_VDEV = 0,
 	PMD_PDEV = 1,
+	PMD_BDEV = 2,	/**< Poll Mode Driver Bonded Device*/
+};
+
+#define PMD_BOND_NAME "eth_bond"
+
+/**
+ * Driver initialization */
+enum pmd_init_priority {
+	PMD_INIT_PRE_PCI_PROBE = 0,
+	PMD_INIT_POST_PCI_PROBE = 1,
 };
 
 /**
@@ -93,9 +103,9 @@ void rte_eal_driver_register(struct rte_driver *driver);
 void rte_eal_driver_unregister(struct rte_driver *driver);
 
 /**
- * Initalize all the registered drivers in this process
+ * Initialize all the registered drivers in this process
  */
-int rte_eal_dev_init(void);
+int rte_eal_dev_init(uint8_t init_priority);
 
 #define PMD_REGISTER_DRIVER(d)\
 void devinitfn_ ##d(void);\
lib/librte_eal/linuxapp/eal/eal.c +10 -1
index d204387..573fd06 100644
@@ -75,6 +75,7 @@
 #include <rte_atomic.h>
 #include <malloc_heap.h>
 #include <rte_eth_ring.h>
+#include <rte_dev.h>
 
 #include "eal_private.h"
 #include "eal_thread.h"
@@ -1097,7 +1098,7 @@ rte_eal_init(int argc, char **argv)
 	RTE_LOG(DEBUG, EAL, "Master core %u is ready (tid=%x)\n",
 		rte_config.master_lcore, (int)thread_id);
 
-	if (rte_eal_dev_init() < 0)
+	if (rte_eal_dev_init(PMD_INIT_PRE_PCI_PROBE) < 0)
 		rte_panic("Cannot init pmd devices\n");
 
 	RTE_LCORE_FOREACH_SLAVE(i) {
@@ -1127,6 +1128,14 @@ rte_eal_init(int argc, char **argv)
 	rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
 	rte_eal_mp_wait_lcore();
 
+	/* Probe & Initialize PCI devices */
+	if (rte_eal_pci_probe())
+			rte_panic("Cannot probe PCI\n");
+
+	/* Initialize any outstanding devices */
+	if (rte_eal_dev_init(PMD_INIT_POST_PCI_PROBE) < 0)
+		rte_panic("Cannot init pmd devices\n");
+
 	return fctret;
 }
 
Signature · 1 line
1.7.0.7
#121 lore raw

PATCH v11 4/5 bond: unit tests

In reply to a message not in the archive

Including:
- code to generate packet bursts for testing rx and tx functionality of bonded device
- virtual/stubbed out ethdev for use as slave ethdev in testing

---
 app/test/Makefile                 |    6 +-
 app/test/commands.c               |    7 +
 app/test/packet_burst_generator.c |  287 +++
 app/test/packet_burst_generator.h |   78 +
 app/test/test.h                   |    1 +
 app/test/test_link_bonding.c      | 3958 +++++++++++++++++++++++++++++++++++++
 app/test/virtual_pmd.c            |  574 ++++++
 app/test/virtual_pmd.h            |   74 +
 8 files changed, 4984 insertions(+), 1 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
app/test/Makefile +5 -1
index 45d0cf2..e1b2c03 100644
@@ -102,7 +102,11 @@ SRCS-$(CONFIG_RTE_APP_TEST) += test_ivshmem.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_distributor.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_distributor_perf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_devargs.c
-
+ifeq ($(CONFIG_RTE_LIBRTE_PMD_BOND),y)
+SRCS-$(CONFIG_RTE_APP_TEST) += virtual_pmd.c
+SRCS-$(CONFIG_RTE_APP_TEST) += packet_burst_generator.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_link_bonding.c
+endif
 ifeq ($(CONFIG_RTE_APP_TEST),y)
 SRCS-$(CONFIG_RTE_LIBRTE_ACL) += test_acl.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring.c
app/test/commands.c +7 -0
index c9dc085..5f23420 100644
@@ -159,6 +159,10 @@ static void cmd_autotest_parsed(void *parsed_result,
 		ret = test_timer();
 	if (!strcmp(res->autotest, "timer_perf_autotest"))
 		ret = test_timer_perf();
+#ifdef RTE_LIBRTE_PMD_BOND
+	if (!strcmp(res->autotest, "link_bonding_autotest"))
+		ret = test_link_bonding();
+#endif
 	if (!strcmp(res->autotest, "mempool_autotest"))
 		ret = test_mempool();
 	if (!strcmp(res->autotest, "mempool_perf_autotest"))
@@ -227,6 +231,9 @@ cmdline_parse_token_string_t cmd_autotest_autotest =
 			"alarm_autotest#interrupt_autotest#"
 			"version_autotest#eal_fs_autotest#"
 			"cmdline_autotest#func_reentrancy_autotest#"
+#ifdef RTE_LIBRTE_PMD_BOND
+			"link_bonding_autotest#"
+#endif
 			"mempool_perf_autotest#hash_perf_autotest#"
 			"memcpy_perf_autotest#ring_perf_autotest#"
 			"red_autotest#meter_autotest#sched_autotest#"
app/test/packet_burst_generator.c new file +287 -0

287 lines not on this page · raw message

app/test/packet_burst_generator.h new file +78 -0

78 lines not on this page · raw message

app/test/test.h +1 -0
index c54e7ef..c00e1d6 100644
@@ -97,6 +97,7 @@ int test_distributor(void);
 int test_distributor_perf(void);
 int test_kvargs(void);
 int test_devargs(void);
+int test_link_bonding(void);
 
 int test_pci_run;
 
app/test/test_link_bonding.c new file +3958 -0

2,597 lines not on this page · raw message

app/test/virtual_pmd.c new file +574 -0

574 lines not on this page · raw message

app/test/virtual_pmd.h new file +74 -0

74 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.7.0.7

Part of the diff is not shown here. View the raw message.

A message that is not in the archive (sent off-list or not yet received): 1404064161-26370-5-git-send-email-declan.doherty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#123 lore raw

Re: [PATCH v11 4/5] bond: unit tests

Hi Declan,

2014-06-29 18:49, Declan Doherty:

app/test/Makefile SRCS-$(CONFIG_RTE_APP_TEST) += test_ivshmem.c · line 112

Quoted 8 lines
app/test/Makefile +5 -0
+ifeq ($(CONFIG_RTE_LIBRTE_PMD_BOND),y)
+SRCS-$(CONFIG_RTE_APP_TEST) += virtual_pmd.c
+SRCS-$(CONFIG_RTE_APP_TEST) += packet_burst_generator.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_link_bonding.c
+endif
 ifeq ($(CONFIG_RTE_APP_TEST),y)
 SRCS-$(CONFIG_RTE_LIBRTE_ACL) += test_acl.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring.c

I think there is a cleaner way to fix build without bonding. See my patch proposal below:

SRCS-$(CONFIG_RTE_APP_TEST) += virtual_pmd.c SRCS-$(CONFIG_RTE_APP_TEST) += packet_burst_generator.c
-SRCS-$(CONFIG_RTE_APP_TEST) += test_link_bonding.c
ifeq ($(CONFIG_RTE_APP_TEST),y) SRCS-$(CONFIG_RTE_LIBRTE_ACL) += test_acl.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += test_link_bonding.c
SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring.c

Signature · 1 line
Thomas
#124 lore raw

PATCH v11 5/5 bond: testpmd support

In reply to a message not in the archive

- Includes the ability to create new bonded devices.
- Add /remove bonding slave devices.
- Interogate bonded device stats/configuration
- Change bonding modes and select balance transmit polices

---
 app/test-pmd/cmdline.c    |  579 +++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/config.c     |    4 +-
 app/test-pmd/parameters.c |    3 +
 app/test-pmd/testpmd.c    |   40 +++-
 app/test-pmd/testpmd.h    |    2 +
 5 files changed, 619 insertions(+), 9 deletions(-)
app/test-pmd/cmdline.c +579 -0
index f61a31c..345be11 100644
@@ -84,6 +84,9 @@
 #include <cmdline_socket.h>
 #include <cmdline.h>
 #include <rte_pci_dev_ids.h>
+#ifdef RTE_LIBRTE_PMD_BOND
+#include <rte_eth_bond.h>
+#endif
 
 #include "testpmd.h"
 
@@ -412,6 +415,31 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"   Show the bypass configuration for a bypass enabled NIC"
 			" using the lowest port on the NIC.\n\n"
 #endif
+#ifdef RTE_LIBRTE_PMD_BOND
+			"create bonded device (mode) (socket)\n"
+			"	Create a new bonded device with specific bonding mode and socket.\n\n"
+
+			"add bonding slave (slave_id) (port_id)\n"
+			"	Add a slave device to a bonded device.\n\n"
+
+			"remove bonding slave (slave_id) (port_id)\n"
+			"	Remove a slave device from a bonded device.\n\n"
+
+			"set bonding mode (value) (port_id)\n"
+			"	Set the bonding mode on a bonded device.\n\n"
+
+			"set bonding primary (slave_id) (port_id)\n"
+			"	Set the primary slave for a bonded device.\n\n"
+
+			"show bonding config (port_id)\n"
+			"	Show the bonding config for port_id.\n\n"
+
+			"set bonding mac_addr (port_id) (address)\n"
+			"	Set the MAC address of a bonded device.\n\n"
+
+			"set bonding xmit_balance_policy (port_id) (l2|l23|l34)\n"
+			"	Set the transmit balance policy for bonded device running in balance mode.\n\n"
+#endif
 
 			, list_pkt_forwarding_modes()
 		);
@@ -3039,6 +3067,547 @@ cmdline_parse_inst_t cmd_show_bypass_config = {
 };
 #endif
 
+#ifdef RTE_LIBRTE_PMD_BOND
+/* *** SET BONDING MODE *** */
+struct cmd_set_bonding_mode_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t mode;
+	uint8_t value;
+	uint8_t port_id;
+};
+
+static void cmd_set_bonding_mode_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_mode_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+
+	/* Set the bonding mode for the relevant port. */
+	if (0 != rte_eth_bond_mode_set(port_id, res->value))
+		printf("\t Failed to set bonding mode for port = %d.\n", port_id);
+}
+
+cmdline_parse_token_string_t cmd_setbonding_mode_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_mode_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_mode_mode =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		mode, "mode");
+cmdline_parse_token_num_t cmd_setbonding_mode_value =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+		value, UINT8);
+cmdline_parse_token_num_t cmd_setbonding_mode_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bonding_mode = {
+		.f = cmd_set_bonding_mode_parsed,
+		.help_str = "set bonding mode (mode_value) (port_id): Set the bonding mode for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *) &cmd_setbonding_mode_set,
+				(void *) &cmd_setbonding_mode_bonding,
+				(void *) &cmd_setbonding_mode_mode,
+				(void *) &cmd_setbonding_mode_value,
+				(void *) &cmd_setbonding_mode_port,
+				NULL
+		}
+};
+
+/* *** SET BALANCE XMIT POLICY *** */
+struct cmd_set_bonding_balance_xmit_policy_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t balance_xmit_policy;
+	uint8_t port_id;
+	cmdline_fixed_string_t policy;
+};
+
+static void cmd_set_bonding_balance_xmit_policy_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_balance_xmit_policy_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+	uint8_t policy;
+
+	if (!strcmp(res->policy, "l2")) {
+		policy = BALANCE_XMIT_POLICY_LAYER2;
+	} else if (!strcmp(res->policy, "l23")) {
+		policy = BALANCE_XMIT_POLICY_LAYER23;
+	} else if (!strcmp(res->policy, "l34")) {
+		policy = BALANCE_XMIT_POLICY_LAYER34;
+	} else {
+		printf("\t Invalid xmit policy selection");
+		return;
+	}
+
+	/* Set the bonding mode for the relevant port. */
+	if (0 != rte_eth_bond_xmit_policy_set(port_id, policy)) {
+		printf("\t Failed to set bonding balance xmit policy for port = %d.\n",
+				port_id);
+	}
+}
+
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_balance_xmit_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		balance_xmit_policy, "balance_xmit_policy");
+cmdline_parse_token_num_t cmd_setbonding_balance_xmit_policy_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		port_id, UINT8);
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		policy, "l2#l23#l34");
+
+cmdline_parse_inst_t cmd_set_balance_xmit_policy = {
+		.f = cmd_set_bonding_balance_xmit_policy_parsed,
+		.help_str = "set bonding balance_xmit_policy (port_id) (policy_value): Set the bonding balance_xmit_policy for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_setbonding_balance_xmit_policy_set,
+				(void *)&cmd_setbonding_balance_xmit_policy_bonding,
+				(void *)&cmd_setbonding_balance_xmit_policy_balance_xmit_policy,
+				(void *)&cmd_setbonding_balance_xmit_policy_port,
+				(void *)&cmd_setbonding_balance_xmit_policy_policy,
+				NULL
+		}
+};
+
+/* *** SHOW NIC BONDING CONFIGURATION *** */
+struct cmd_show_bonding_config_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+};
+
+static void cmd_show_bonding_config_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_show_bonding_config_result *res = parsed_result;
+	int bonding_mode;
+	uint8_t slaves[RTE_MAX_ETHPORTS];
+	int num_slaves, num_active_slaves;
+	int primary_id;
+	int i;
+	portid_t port_id = res->port_id;
+
+	/* Display the bonding mode.*/
+	bonding_mode = rte_eth_bond_mode_get(port_id);
+	if (bonding_mode < 0) {
+		printf("\tFailed to get bonding mode for port = %d\n", port_id);
+		return;
+	} else
+		printf("\tBonding mode: %d\n", bonding_mode);
+
+	if (bonding_mode == BONDING_MODE_BALANCE) {
+		int balance_xmit_policy;
+
+		balance_xmit_policy = rte_eth_bond_xmit_policy_get(port_id);
+		if (balance_xmit_policy < 0) {
+			printf("\tFailed to get balance xmit policy for port = %d\n",
+					port_id);
+			return;
+		} else {
+			printf("\tBalance Xmit Policy: ");
+
+			switch (balance_xmit_policy) {
+			case BALANCE_XMIT_POLICY_LAYER2:
+				printf("BALANCE_XMIT_POLICY_LAYER2");
+				break;
+			case BALANCE_XMIT_POLICY_LAYER23:
+				printf("BALANCE_XMIT_POLICY_LAYER23");
+				break;
+			case BALANCE_XMIT_POLICY_LAYER34:
+				printf("BALANCE_XMIT_POLICY_LAYER34");
+				break;
+			}
+			printf("\n");
+		}
+	}
+
+	num_slaves = rte_eth_bond_slaves_get(port_id, slaves, RTE_MAX_ETHPORTS);
+
+	if (num_slaves < 0) {
+		printf("\tFailed to get slave list for port = %d\n", port_id);
+		return;
+	}
+	if (num_slaves > 0) {
+		printf("\tSlaves (%d): [", num_slaves);
+		for (i = 0; i < num_slaves - 1; i++)
+			printf("%d ", slaves[i]);
+
+		printf("%d]\n", slaves[num_slaves - 1]);
+	} else {
+		printf("\tSlaves: []\n");
+
+	}
+
+	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
+			RTE_MAX_ETHPORTS);
+
+	if (num_active_slaves < 0) {
+		printf("\tFailed to get active slave list for port = %d\n", port_id);
+		return;
+	}
+	if (num_active_slaves > 0) {
+		printf("\tActive Slaves (%d): [", num_active_slaves);
+		for (i = 0; i < num_active_slaves - 1; i++)
+			printf("%d ", slaves[i]);
+
+		printf("%d]\n", slaves[num_active_slaves - 1]);
+
+	} else {
+		printf("\tActive Slaves: []\n");
+
+	}
+
+	primary_id = rte_eth_bond_primary_get(port_id);
+	if (primary_id < 0) {
+		printf("\tFailed to get primary slave for port = %d\n", port_id);
+		return;
+	} else
+		printf("\tPrimary: [%d]\n", primary_id);
+
+}
+
+cmdline_parse_token_string_t cmd_showbonding_config_show =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		show, "show");
+cmdline_parse_token_string_t cmd_showbonding_config_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_showbonding_config_config =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		config, "config");
+cmdline_parse_token_num_t cmd_showbonding_config_port =
+TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_config_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_show_bonding_config = {
+		.f = cmd_show_bonding_config_parsed,
+		.help_str =	"show bonding config (port_id): Show the bonding config for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_showbonding_config_show,
+				(void *)&cmd_showbonding_config_bonding,
+				(void *)&cmd_showbonding_config_config,
+				(void *)&cmd_showbonding_config_port,
+				NULL
+		}
+};
+
+/* *** SET BONDING PRIMARY *** */
+struct cmd_set_bonding_primary_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t primary;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_set_bonding_primary_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_primary_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_primary_set(master_port_id, slave_port_id)) {
+		printf("\t Failed to set primary slave for port = %d.\n",
+				master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_setbonding_primary_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_primary_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_primary_primary =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		primary, "primary");
+cmdline_parse_token_num_t cmd_setbonding_primary_slave =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+		slave_id, UINT8);
+cmdline_parse_token_num_t cmd_setbonding_primary_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bonding_primary = {
+		.f = cmd_set_bonding_primary_parsed,
+		.help_str = "set bonding primary (slave_id) (port_id): Set the primary slave for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_setbonding_primary_set,
+				(void *)&cmd_setbonding_primary_bonding,
+				(void *)&cmd_setbonding_primary_primary,
+				(void *)&cmd_setbonding_primary_slave,
+				(void *)&cmd_setbonding_primary_port,
+				NULL
+		}
+};
+
+/* *** ADD SLAVE *** */
+struct cmd_add_bonding_slave_result {
+	cmdline_fixed_string_t add;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t slave;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_add_bonding_slave_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_add_bonding_slave_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_slave_add(master_port_id, slave_port_id)) {
+		printf("\t Failed to add slave %d to master port = %d.\n",
+				slave_port_id, master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_addbonding_slave_add =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		add, "add");
+cmdline_parse_token_string_t cmd_addbonding_slave_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_addbonding_slave_slave =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		slave, "slave");
+cmdline_parse_token_num_t cmd_addbonding_slave_slaveid =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+		slave_id, UINT8);
+cmdline_parse_token_num_t cmd_addbonding_slave_port =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_add_bonding_slave = {
+		.f = cmd_add_bonding_slave_parsed,
+		.help_str = "add bonding slave (slave_id) (port_id): Add a slave device to a bonded device",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_addbonding_slave_add,
+				(void *)&cmd_addbonding_slave_bonding,
+				(void *)&cmd_addbonding_slave_slave,
+				(void *)&cmd_addbonding_slave_slaveid,
+				(void *)&cmd_addbonding_slave_port,
+				NULL
+		}
+};
+
+/* *** REMOVE SLAVE *** */
+struct cmd_remove_bonding_slave_result {
+	cmdline_fixed_string_t remove;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t slave;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_remove_bonding_slave_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_remove_bonding_slave_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_slave_remove(master_port_id, slave_port_id)) {
+		printf("\t Failed to remove slave %d from master port = %d.\n",
+				slave_port_id, master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_removebonding_slave_remove =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				remove, "remove");
+cmdline_parse_token_string_t cmd_removebonding_slave_bonding =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				bonding, "bonding");
+cmdline_parse_token_string_t cmd_removebonding_slave_slave =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				slave, "slave");
+cmdline_parse_token_num_t cmd_removebonding_slave_slaveid =
+		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				slave_id, UINT8);
+cmdline_parse_token_num_t cmd_removebonding_slave_port =
+		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				port_id, UINT8);
+
+cmdline_parse_inst_t cmd_remove_bonding_slave = {
+		.f = cmd_remove_bonding_slave_parsed,
+		.help_str = "remove bonding slave (slave_id) (port_id): Remove a slave device from a bonded device",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_removebonding_slave_remove,
+				(void *)&cmd_removebonding_slave_bonding,
+				(void *)&cmd_removebonding_slave_slave,
+				(void *)&cmd_removebonding_slave_slaveid,
+				(void *)&cmd_removebonding_slave_port,
+				NULL
+		}
+};
+
+/* *** CREATE BONDED DEVICE *** */
+struct cmd_create_bonded_device_result {
+	cmdline_fixed_string_t create;
+	cmdline_fixed_string_t bonded;
+	cmdline_fixed_string_t device;
+	uint8_t mode;
+	uint8_t socket;
+};
+
+static int bond_dev_num = 0;
+
+static void cmd_create_bonded_device_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_create_bonded_device_result *res = parsed_result;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+	int port_id;
+
+	if (test_done == 0) {
+		printf("Please stop forwarding first\n");
+		return;
+	}
+
+	snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "eth_bond_testpmd_%d",
+			bond_dev_num++);
+
+	/* Create a new bonded device. */
+	port_id = rte_eth_bond_create(ethdev_name, res->mode, res->socket);
+	if (port_id < 0) {
+		printf("\t Failed to create bonded device.\n");
+		return;
+	} else {
+		printf("Created new bonded device %s on (port %d).\n", ethdev_name,
+				port_id);
+
+		/* Update number of ports */
+		nb_ports = rte_eth_dev_count();
+		reconfig(port_id);
+		rte_eth_promiscuous_enable(port_id);
+	}
+
+}
+
+cmdline_parse_token_string_t cmd_createbonded_device_create =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				create, "create");
+cmdline_parse_token_string_t cmd_createbonded_device_bonded =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				bonded, "bonded");
+cmdline_parse_token_string_t cmd_createbonded_device_device =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				device, "device");
+cmdline_parse_token_num_t cmd_createbonded_device_mode =
+		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+				mode, UINT8);
+cmdline_parse_token_num_t cmd_createbonded_device_socket =
+		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+				socket, UINT8);
+
+cmdline_parse_inst_t cmd_create_bonded_device = {
+		.f = cmd_create_bonded_device_parsed,
+		.help_str = "create bonded device (mode) (socket): Create a new bonded device with specific bonding mode and socket",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_createbonded_device_create,
+				(void *)&cmd_createbonded_device_bonded,
+				(void *)&cmd_createbonded_device_device,
+				(void *)&cmd_createbonded_device_mode,
+				(void *)&cmd_createbonded_device_socket,
+				NULL
+		}
+};
+
+/* *** SET MAC ADDRESS IN BONDED DEVICE *** */
+struct cmd_set_bond_mac_addr_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t mac_addr;
+	uint8_t port_num;
+	struct ether_addr address;
+};
+
+static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bond_mac_addr_result *res = parsed_result;
+	int ret;
+
+	if (res->port_num >= nb_ports) {
+		printf("Port id %d must be less than %d\n", res->port_num, nb_ports);
+		return;
+	}
+
+	ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
+
+	/* check the return value and print it if is < 0 */
+	if (ret < 0)
+		printf("set_bond_mac_addr error: (%s)\n", strerror(-ret));
+}
+
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_set =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, set, "set");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, bonding,
+				"bonding");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, mac_addr,
+				"mac_addr");
+cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum =
+		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result, port_num, UINT8);
+cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr =
+		TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result, address);
+
+cmdline_parse_inst_t cmd_set_bond_mac_addr = {
+		.f = cmd_set_bond_mac_addr_parsed,
+		.data = (void *) 0,
+		.help_str = "set bonding mac_addr (port_id) (address): ",
+		.tokens = {
+				(void *)&cmd_set_bond_mac_addr_set,
+				(void *)&cmd_set_bond_mac_addr_bonding,
+				(void *)&cmd_set_bond_mac_addr_mac,
+				(void *)&cmd_set_bond_mac_addr_portnum,
+				(void *)&cmd_set_bond_mac_addr_addr,
+				NULL
+		}
+};
+
+#endif /* RTE_LIBRTE_PMD_BOND */
+
 /* *** SET FORWARDING MODE *** */
 struct cmd_set_fwd_mode_result {
 	cmdline_fixed_string_t set;
@@ -6768,6 +7337,16 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_bypass_timeout,
 	(cmdline_parse_inst_t *)&cmd_show_bypass_config,
 #endif
+#ifdef RTE_LIBRTE_PMD_BOND
+	(cmdline_parse_inst_t *) &cmd_set_bonding_mode,
+	(cmdline_parse_inst_t *) &cmd_show_bonding_config,
+	(cmdline_parse_inst_t *) &cmd_set_bonding_primary,
+	(cmdline_parse_inst_t *) &cmd_add_bonding_slave,
+	(cmdline_parse_inst_t *) &cmd_remove_bonding_slave,
+	(cmdline_parse_inst_t *) &cmd_create_bonded_device,
+	(cmdline_parse_inst_t *) &cmd_set_bond_mac_addr,
+	(cmdline_parse_inst_t *) &cmd_set_balance_xmit_policy,
+#endif
 	(cmdline_parse_inst_t *)&cmd_vlan_offload,
 	(cmdline_parse_inst_t *)&cmd_vlan_tpid,
 	(cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all,
app/test-pmd/config.c +3 -1
index 32f2134..c72f6ee 100644
@@ -252,6 +252,7 @@ void
 port_infos_display(portid_t port_id)
 {
 	struct rte_port *port;
+	struct ether_addr mac_addr;
 	struct rte_eth_link link;
 	int vlan_offload;
 	struct rte_mempool * mp;
@@ -265,7 +266,8 @@ port_infos_display(portid_t port_id)
 	rte_eth_link_get_nowait(port_id, &link);
 	printf("\n%s Infos for port %-2d %s\n",
 	       info_border, port_id, info_border);
-	print_ethaddr("MAC address: ", &port->eth_addr);
+	rte_eth_macaddr_get(port_id, &mac_addr);
+	print_ethaddr("MAC address: ", &mac_addr);
 	printf("\nConnect to socket: %u", port->socket_id);
 
 	if (port_numa[port_id] != NUMA_NO_CONFIG) {
app/test-pmd/parameters.c +3 -0
index 4bca0b0..9573a43 100644
@@ -75,6 +75,9 @@
 #include <cmdline_parse.h>
 #include <cmdline_parse_etheraddr.h>
 #endif
+#ifdef RTE_LIBRTE_PMD_BOND
+#include <rte_eth_bond.h>
+#endif
 
 #include "testpmd.h"
 
app/test-pmd/testpmd.c +32 -8
index 16fe596..e8a4b45 100644
@@ -300,7 +300,7 @@ struct rte_fdir_conf fdir_conf = {
 	.drop_queue = 127,
 };
 
-static volatile int test_done = 1; /* stop packet forwarding when set to 1. */
+volatile int test_done = 1; /* stop packet forwarding when set to 1. */
 
 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
@@ -625,6 +625,32 @@ init_config(void)
 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
 }
 
+
+void
+reconfig(portid_t new_port_id)
+{
+	struct rte_port *port;
+
+	/* Reconfiguration of Ethernet ports. */
+	ports = rte_realloc(ports,
+			    sizeof(struct rte_port) * nb_ports,
+			    CACHE_LINE_SIZE);
+	if (ports == NULL) {
+		rte_exit(EXIT_FAILURE, "rte_realloc(%d struct rte_port) failed\n",
+				nb_ports);
+	}
+
+	port = &ports[new_port_id];
+	rte_eth_dev_info_get(new_port_id, &port->dev_info);
+
+	/* set flag to initialize port/queue */
+	port->need_reconfig = 1;
+	port->need_reconfig_queues = 1;
+
+	init_port_config();
+}
+
+
 int
 init_fwd_streams(void)
 {
@@ -1252,7 +1278,7 @@ start_port(portid_t pid)
 	portid_t pi;
 	queueid_t qi;
 	struct rte_port *port;
-	uint8_t *mac_addr;
+	struct ether_addr mac_addr;
 
 	if (test_done == 0) {
 		printf("Please stop forwarding first\n");
@@ -1380,10 +1406,11 @@ start_port(portid_t pid)
 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
 			printf("Port %d can not be set into started\n", pi);
 
-		mac_addr = port->eth_addr.addr_bytes;
+		rte_eth_macaddr_get(pi, &mac_addr);
 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
-		       mac_addr[0], mac_addr[1], mac_addr[2],
-		       mac_addr[3], mac_addr[4], mac_addr[5]);
+				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
+				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
+				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
 
 		/* at least one port started, need checking link status */
 		need_check_link_status = 1;
@@ -1826,9 +1853,6 @@ main(int argc, char** argv)
 	if (diag < 0)
 		rte_panic("Cannot init EAL\n");
 
-	if (rte_eal_pci_probe())
-		rte_panic("Cannot probe PCI\n");
-
 	nb_ports = (portid_t) rte_eth_dev_count();
 	if (nb_ports == 0)
 		rte_exit(EXIT_FAILURE, "No probed ethernet devices - "
app/test-pmd/testpmd.h +2 -0
index e263616..ac86bfe 100644
@@ -281,6 +281,7 @@ extern uint16_t port_topology; /**< set by "--port-topology" parameter */
 extern uint8_t no_flush_rx; /**<set by "--no-flush-rx" parameter */
 extern uint8_t  mp_anon; /**< set by "--mp-anon" parameter */
 extern uint8_t no_link_check; /**<set by "--disable-link-check" parameter */
+extern volatile int test_done; /* stop packet forwarding when set to 1. */
 
 #ifdef RTE_NIC_BYPASS
 extern uint32_t bypass_timeout; /**< Store the NIC bypass watchdog timeout */
@@ -454,6 +455,7 @@ void fwd_config_display(void);
 void rxtx_config_display(void);
 void fwd_config_setup(void);
 void set_def_fwd_config(void);
+void reconfig(portid_t new_port_id);
 int init_fwd_streams(void);
 
 void port_mtu_set(portid_t port_id, uint16_t mtu);
Signature · 1 line
1.7.0.7
#125 lore raw

PATCH v10 1/5 bond: new link bonding library

In reply to a message not in the archive

Initial release with support for
Mode 0 - Round Robin
Mode 1 - Active Backup
Mode 2 - Balance -> Supports 3 transmit polices (layer 2, layer 2+3, layer 3+4) Mode 3 - Broadcast

---
 config/common_bsdapp                       |    5 +
 config/common_linuxapp                     |    5 +
 doc/doxy-api-index.md                      |    1 +
 doc/doxy-api.conf                          |    1 +
 lib/Makefile                               |    1 +
 lib/librte_pmd_bond/Makefile               |   61 ++
 lib/librte_pmd_bond/rte_eth_bond.h         |  255 ++++++
 lib/librte_pmd_bond/rte_eth_bond_api.c     |  662 +++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond_args.c    |  252 ++++++
 lib/librte_pmd_bond/rte_eth_bond_pmd.c     | 1212 ++++++++++++++++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond_private.h |  215 +++++
 mk/rte.app.mk                              |    4 +
 12 files changed, 2674 insertions(+), 0 deletions(-)
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_api.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_args.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_pmd.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_private.h
config/common_bsdapp +5 -0
index d5db4ab..c243b0c 100644
@@ -206,6 +206,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=y
 
 #
+# Compile link bonding PMD library
+#
+CONFIG_RTE_LIBRTE_PMD_BOND=y
+
+#
 # Do prefetch of packet data within PMD driver receive function
 #
 CONFIG_RTE_PMD_PACKET_PREFETCH=y
config/common_linuxapp +5 -0
index c5c0cb6..6237ce5 100644
@@ -244,6 +244,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=n
 
 #
+# Compile link bonding PMD library
+#
+CONFIG_RTE_LIBRTE_PMD_BOND=y
+
+#
 # Compile Xen PMD
 #
 CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
doc/doxy-api-index.md +1 -0
index 7b26e98..d72659a 100644
@@ -38,6 +38,7 @@ There are many libraries, so their headers may be grouped by topics:
 - **device**:
   [ethdev]             (@ref rte_ethdev.h),
   [devargs]            (@ref rte_devargs.h),
+  [bond]               (@ref rte_eth_bond.h),
   [KNI]                (@ref rte_kni.h),
   [PCI]                (@ref rte_pci.h),
   [PCI IDs]            (@ref rte_pci_dev_ids.h)
doc/doxy-api.conf +1 -0
index f380d9a..1fd4492 100644
@@ -47,6 +47,7 @@ INPUT                   = doc/doxy-api-index.md \
                           lib/librte_pipeline \
                           lib/librte_port \
                           lib/librte_power \
+                          lib/librte_pmd_bond \
                           lib/librte_ring \
                           lib/librte_sched \
                           lib/librte_table \
lib/Makefile +1 -0
index c58c0c9..10c5bb3 100644
@@ -44,6 +44,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
 DIRS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += librte_pmd_e1000
 DIRS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += librte_pmd_ixgbe
 DIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += librte_pmd_i40e
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += librte_pmd_bond
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_RING) += librte_pmd_ring
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += librte_pmd_pcap
 DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += librte_pmd_virtio
lib/librte_pmd_bond/Makefile new file +61 -0

61 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond.h new file +255 -0

255 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_api.c new file +662 -0

662 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_args.c new file +252 -0

252 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_pmd.c new file +1212 -0

1,212 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_private.h new file +215 -0

215 lines not on this page · raw message

mk/rte.app.mk +4 -0
index 8db9cde..a4624e5 100644
@@ -205,6 +205,10 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMD_PCAP),y)
 LDLIBS += -lrte_pmd_pcap -lpcap
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_PMD_BOND),y)
+LDLIBS += -lrte_pmd_bond
+endif
+
 endif
 
 LDLIBS += $(EXECENV_LDLIBS)
Signature · 1 line
1.7.0.7
#126 lore raw

PATCH v10 2/5 ethdev: add unique name to devices

In reply to a message not in the archive

Adding support to rte_eth_dev_data structure to support unique name identifier for ethdevs to support adding slave ethdevs (specifically virtual devices which have no public unique identifier) to a link bonding device. This changes the API rte_eth_dev_allocate() to require a const char *name when allocating a ethdev, which also verifies that the name is unique and hasn’t been already used by an existed allocated rte_eth_dev. Also contains updates to virtual pmd’s to now call the API with a name parameter.

---
 lib/librte_ether/rte_ethdev.c            |   31 ++++++++++++++++++++++++++--
 lib/librte_ether/rte_ethdev.h            |    7 +++++-
 lib/librte_pmd_pcap/rte_eth_pcap.c       |   22 ++++++++++----------
 lib/librte_pmd_ring/rte_eth_ring.c       |   32 +++++++++++++++--------------
 lib/librte_pmd_ring/rte_eth_ring.h       |    3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c |    2 +-
 6 files changed, 65 insertions(+), 32 deletions(-)
lib/librte_ether/rte_ethdev.c +28 -3
index ef81a76..0ebb8fb 100644
@@ -65,6 +65,7 @@
 #include <rte_mbuf.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
+#include <rte_string_fns.h>
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"
@@ -153,21 +154,39 @@ rte_eth_dev_data_alloc(void)
 				RTE_MAX_ETHPORTS * sizeof(*rte_eth_dev_data));
 }
 
+static struct rte_eth_dev *
+rte_eth_dev_allocated(const char *name)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_ports; i++) {
+		if (strcmp(rte_eth_devices[i].data->name, name) == 0)
+			return &rte_eth_devices[i];
+	}
+	return NULL;
+}
+
 struct rte_eth_dev *
-rte_eth_dev_allocate(void)
+rte_eth_dev_allocate(const char *name)
 {
 	struct rte_eth_dev *eth_dev;
 
 	if (nb_ports == RTE_MAX_ETHPORTS) {
-		PMD_DEBUG_TRACE("Reached maximum number of ethernet ports\n");
+		PMD_DEBUG_TRACE("Reached maximum number of Ethernet ports\n");
 		return NULL;
 	}
 
 	if (rte_eth_dev_data == NULL)
 		rte_eth_dev_data_alloc();
 
+	if (rte_eth_dev_allocated(name) != NULL) {
+		PMD_DEBUG_TRACE("Ethernet Device with name %s already allocated!\n");
+		return NULL;
+	}
+
 	eth_dev = &rte_eth_devices[nb_ports];
 	eth_dev->data = &rte_eth_dev_data[nb_ports];
+	snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
 	eth_dev->data->port_id = nb_ports++;
 	return eth_dev;
 }
@@ -178,11 +197,17 @@ rte_eth_dev_init(struct rte_pci_driver *pci_drv,
 {
 	struct eth_driver    *eth_drv;
 	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
 	int diag;
 
 	eth_drv = (struct eth_driver *)pci_drv;
 
-	eth_dev = rte_eth_dev_allocate();
+	/* Create unique Ethernet device name using PCI address */
+	snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "%d:%d.%d",
+			pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
+
+	eth_dev = rte_eth_dev_allocate(ethdev_name);
 	if (eth_dev == NULL)
 		return -ENOMEM;
 
lib/librte_ether/rte_ethdev.h +6 -1
index 2406e45..50df654 100644
@@ -1497,6 +1497,8 @@ struct rte_eth_dev_sriov {
 };
 #define RTE_ETH_DEV_SRIOV(dev)         ((dev)->data->sriov)
 
+#define RTE_ETH_NAME_MAX_LEN (32)
+
 /**
  * @internal
  * The data part, with no function pointers, associated with each ethernet device.
@@ -1505,6 +1507,8 @@ struct rte_eth_dev_sriov {
  * processes in a multi-process configuration.
  */
 struct rte_eth_dev_data {
+	char name[RTE_ETH_NAME_MAX_LEN]; /**< Unique identifier name */
+
 	void **rx_queues; /**< Array of pointers to RX queues. */
 	void **tx_queues; /**< Array of pointers to TX queues. */
 	uint16_t nb_rx_queues; /**< Number of RX queues. */
@@ -1560,10 +1564,11 @@ extern uint8_t rte_eth_dev_count(void);
  * Allocates a new ethdev slot for an ethernet device and returns the pointer
  * to that slot for the driver to use.
  *
+ * @param	name	Unique identifier name for each Ethernet device
  * @return
  *   - Slot in the rte_dev_devices array for a new device;
  */
-struct rte_eth_dev *rte_eth_dev_allocate(void);
+struct rte_eth_dev *rte_eth_dev_allocate(const char *name);
 
 struct eth_driver;
 /**
lib/librte_pmd_pcap/rte_eth_pcap.c +11 -11
index b3dbbda..12b7e0c 100644
@@ -534,7 +534,7 @@ open_tx_iface(const char *key __rte_unused, const char *value, void *extra_args)
 
 
 static int
-rte_pmd_init_internals(const unsigned nb_rx_queues,
+rte_pmd_init_internals(const char *name, const unsigned nb_rx_queues,
 		const unsigned nb_tx_queues,
 		const unsigned numa_node,
 		struct pmd_internals **internals,
@@ -558,20 +558,20 @@ rte_pmd_init_internals(const unsigned nb_rx_queues,
 	/* now do all data allocation - for eth_dev structure, dummy pci driver
 	 * and internal (private) data
 	 */
-	data = rte_zmalloc_socket(NULL, sizeof(*data), 0, numa_node);
+	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
 	if (data == NULL)
 		goto error;
 
-	pci_dev = rte_zmalloc_socket(NULL, sizeof(*pci_dev), 0, numa_node);
+	pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, numa_node);
 	if (pci_dev == NULL)
 		goto error;
 
-	*internals = rte_zmalloc_socket(NULL, sizeof(**internals), 0, numa_node);
+	*internals = rte_zmalloc_socket(name, sizeof(**internals), 0, numa_node);
 	if (*internals == NULL)
 		goto error;
 
 	/* reserve an ethdev entry */
-	*eth_dev = rte_eth_dev_allocate();
+	*eth_dev = rte_eth_dev_allocate(name);
 	if (*eth_dev == NULL)
 		goto error;
 
@@ -617,7 +617,7 @@ rte_pmd_init_internals(const unsigned nb_rx_queues,
 }
 
 static int
-rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
+rte_eth_from_pcaps_n_dumpers(const char *name, pcap_t * const rx_queues[],
 		const unsigned nb_rx_queues,
 		pcap_dumper_t * const tx_queues[],
 		const unsigned nb_tx_queues,
@@ -634,7 +634,7 @@ rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
 	if (tx_queues == NULL && nb_tx_queues > 0)
 		return -1;
 
-	if (rte_pmd_init_internals(nb_rx_queues, nb_tx_queues, numa_node,
+	if (rte_pmd_init_internals(name, nb_rx_queues, nb_tx_queues, numa_node,
 			&internals, &eth_dev, kvlist) < 0)
 		return -1;
 
@@ -652,7 +652,7 @@ rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
 }
 
 static int
-rte_eth_from_pcaps(pcap_t * const rx_queues[],
+rte_eth_from_pcaps(const char *name, pcap_t * const rx_queues[],
 		const unsigned nb_rx_queues,
 		pcap_t * const tx_queues[],
 		const unsigned nb_tx_queues,
@@ -669,7 +669,7 @@ rte_eth_from_pcaps(pcap_t * const rx_queues[],
 	if (tx_queues == NULL && nb_tx_queues > 0)
 		return -1;
 
-	if (rte_pmd_init_internals(nb_rx_queues, nb_tx_queues, numa_node,
+	if (rte_pmd_init_internals(name, nb_rx_queues, nb_tx_queues, numa_node,
 			&internals, &eth_dev, kvlist) < 0)
 		return -1;
 
@@ -760,10 +760,10 @@ rte_pmd_pcap_devinit(const char *name, const char *params)
 		return -1;
 
 	if (using_dumpers)
-		return rte_eth_from_pcaps_n_dumpers(pcaps.pcaps, pcaps.num_of_rx,
+		return rte_eth_from_pcaps_n_dumpers(name, pcaps.pcaps, pcaps.num_of_rx,
 				dumpers.dumpers, dumpers.num_of_tx, numa_node, kvlist);
 
-	return rte_eth_from_pcaps(pcaps.pcaps, pcaps.num_of_rx, dumpers.pcaps,
+	return rte_eth_from_pcaps(name, pcaps.pcaps, pcaps.num_of_rx, dumpers.pcaps,
 			dumpers.num_of_tx, numa_node, kvlist);
 
 }
lib/librte_pmd_ring/rte_eth_ring.c +17 -15
index ce7ad71..73c649e 100644
@@ -219,7 +219,7 @@ static struct eth_dev_ops ops = {
 };
 
 int
-rte_eth_from_rings(struct rte_ring *const rx_queues[],
+rte_eth_from_rings(const char *name, struct rte_ring *const rx_queues[],
 		const unsigned nb_rx_queues,
 		struct rte_ring *const tx_queues[],
 		const unsigned nb_tx_queues,
@@ -243,20 +243,20 @@ rte_eth_from_rings(struct rte_ring *const rx_queues[],
 	/* now do all data allocation - for eth_dev structure, dummy pci driver
 	 * and internal (private) data
 	 */
-	data = rte_zmalloc_socket(NULL, sizeof(*data), 0, numa_node);
+	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
 	if (data == NULL)
 		goto error;
 
-	pci_dev = rte_zmalloc_socket(NULL, sizeof(*pci_dev), 0, numa_node);
+	pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, numa_node);
 	if (pci_dev == NULL)
 		goto error;
 
-	internals = rte_zmalloc_socket(NULL, sizeof(*internals), 0, numa_node);
+	internals = rte_zmalloc_socket(name, sizeof(*internals), 0, numa_node);
 	if (internals == NULL)
 		goto error;
 
 	/* reserve an ethdev entry */
-	eth_dev = rte_eth_dev_allocate();
+	eth_dev = rte_eth_dev_allocate(name);
 	if (eth_dev == NULL)
 		goto error;
 
@@ -335,7 +335,7 @@ eth_dev_ring_create(const char *name, const unsigned numa_node,
 			return -1;
 	}
 
-	if (rte_eth_from_rings(rxtx, num_rings, rxtx, num_rings, numa_node))
+	if (rte_eth_from_rings(name, rxtx, num_rings, rxtx, num_rings, numa_node))
 		return -1;
 
 	return 0;
@@ -352,29 +352,31 @@ eth_dev_ring_pair_create(const char *name, const unsigned numa_node,
 	struct rte_ring *rx[RTE_PMD_RING_MAX_RX_RINGS];
 	struct rte_ring *tx[RTE_PMD_RING_MAX_TX_RINGS];
 	unsigned i;
-	char rng_name[RTE_RING_NAMESIZE];
+	char rx_rng_name[RTE_RING_NAMESIZE];
+	char tx_rng_name[RTE_RING_NAMESIZE];
 	unsigned num_rings = RTE_MIN(RTE_PMD_RING_MAX_RX_RINGS,
 			RTE_PMD_RING_MAX_TX_RINGS);
 
 	for (i = 0; i < num_rings; i++) {
-		snprintf(rng_name, sizeof(rng_name), "ETH_RX%u_%s", i, name);
+		snprintf(rx_rng_name, sizeof(rx_rng_name), "ETH_RX%u_%s", i, name);
 		rx[i] = (action == DEV_CREATE) ?
-				rte_ring_create(rng_name, 1024, numa_node,
+				rte_ring_create(rx_rng_name, 1024, numa_node,
 						RING_F_SP_ENQ|RING_F_SC_DEQ) :
-				rte_ring_lookup(rng_name);
+				rte_ring_lookup(rx_rng_name);
 		if (rx[i] == NULL)
 			return -1;
-		snprintf(rng_name, sizeof(rng_name), "ETH_TX%u_%s", i, name);
+		snprintf(tx_rng_name, sizeof(tx_rng_name), "ETH_TX%u_%s", i, name);
 		tx[i] = (action == DEV_CREATE) ?
-				rte_ring_create(rng_name, 1024, numa_node,
+				rte_ring_create(tx_rng_name, 1024, numa_node,
 						RING_F_SP_ENQ|RING_F_SC_DEQ):
-				rte_ring_lookup(rng_name);
+				rte_ring_lookup(tx_rng_name);
 		if (tx[i] == NULL)
 			return -1;
 	}
 
-	if (rte_eth_from_rings(rx, num_rings, tx, num_rings, numa_node) ||
-			rte_eth_from_rings(tx, num_rings, rx, num_rings, numa_node) )
+	if (rte_eth_from_rings(rx_rng_name, rx, num_rings, tx, num_rings,
+			numa_node) || rte_eth_from_rings(tx_rng_name, tx, num_rings, rx,
+					num_rings, numa_node))
 		return -1;
 
 	return 0;
lib/librte_pmd_ring/rte_eth_ring.h +2 -1
index ef29344..e6ae19e 100644
@@ -40,7 +40,8 @@ extern "C" {
 
 #include <rte_ring.h>
 
-int rte_eth_from_rings(struct rte_ring * const rx_queues[],
+int rte_eth_from_rings(const char *name,
+		struct rte_ring * const rx_queues[],
 		const unsigned nb_rx_queues,
 		struct rte_ring *const tx_queues[],
 		const unsigned nb_tx_queues,
lib/librte_pmd_xenvirt/rte_eth_xenvirt.c +1 -1
index 18c44f5..450332a 100644
@@ -647,7 +647,7 @@ eth_dev_xenvirt_create(const char *name, const char *params,
 		goto err;
 
 	/* reserve an ethdev entry */
-	eth_dev = rte_eth_dev_allocate();
+	eth_dev = rte_eth_dev_allocate(name);
 	if (eth_dev == NULL)
 		goto err;
 
Signature · 1 line
1.7.0.7
#127 lore raw

PATCH v10 3/5 eal: support link bonding device initialization

In reply to a message not in the archive

Updating functionality in EAL to support adding link bonding devices via –vdev option. Link bonding devices will be initialized after all physical devices have been probed and initialized.

---
 lib/librte_eal/bsdapp/eal/eal.c             |   10 ++++-
 lib/librte_eal/common/eal_common_dev.c      |   58 ++++++++++++++++++--------
 lib/librte_eal/common/eal_common_pci.c      |    3 +
 lib/librte_eal/common/include/eal_private.h |    7 ---
 lib/librte_eal/common/include/rte_dev.h     |   14 ++++++-
 lib/librte_eal/linuxapp/eal/eal.c           |   11 +++++-
 6 files changed, 74 insertions(+), 29 deletions(-)
lib/librte_eal/bsdapp/eal/eal.c +9 -1
index a1f014f..c53f63e 100644
@@ -874,7 +874,7 @@ rte_eal_init(int argc, char **argv)
 
 	rte_eal_mcfg_complete();
 
-	if (rte_eal_dev_init() < 0)
+	if (rte_eal_dev_init(PMD_INIT_PRE_PCI_PROBE) < 0)
 		rte_panic("Cannot init pmd devices\n");
 
 	RTE_LCORE_FOREACH_SLAVE(i) {
@@ -906,6 +906,14 @@ rte_eal_init(int argc, char **argv)
 	rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
 	rte_eal_mp_wait_lcore();
 
+	/* Probe & Initialize PCI devices */
+	if (rte_eal_pci_probe())
+			rte_panic("Cannot probe PCI\n");
+
+	/* Initialize any outstanding devices */
+	if (rte_eal_dev_init(PMD_INIT_POST_PCI_PROBE) < 0)
+		rte_panic("Cannot init pmd devices\n");
+
 	return fctret;
 }
 
lib/librte_eal/common/eal_common_dev.c +40 -18

77 lines not on this page · raw message

lib/librte_eal/common/eal_common_pci.c +3 -0
index af809a8..c637361 100644
@@ -150,6 +150,9 @@ rte_eal_pci_probe(void)
 		probe_all = 1;
 
 	TAILQ_FOREACH(dev, &pci_device_list, next) {
+		/* check if device has already been initialized */
+		if (dev->driver != NULL)
+			continue;
 
 		/* set devargs in PCI structure */
 		devargs = pci_devargs_lookup(dev);
lib/librte_eal/common/include/eal_private.h +0 -7
index 232fcec..b440ffb 100644
@@ -196,11 +196,4 @@ int rte_eal_intr_init(void);
  */
 int rte_eal_alarm_init(void);
 
-/**
- * This function initialises any virtual devices
- *
- * This function is private to the EAL.
- */
-int rte_eal_dev_init(void);
-
 #endif /* _EAL_PRIVATE_H_ */
lib/librte_eal/common/include/rte_dev.h +12 -2
index f7e3a10..d89f1a5 100644
@@ -62,6 +62,16 @@ typedef int (rte_dev_init_t)(const char *name, const char *args);
 enum pmd_type {
 	PMD_VDEV = 0,
 	PMD_PDEV = 1,
+	PMD_BDEV = 2,	/**< Poll Mode Driver Bonded Device*/
+};
+
+#define PMD_BOND_NAME "eth_bond"
+
+/**
+ * Driver initialization */
+enum pmd_init_priority {
+	PMD_INIT_PRE_PCI_PROBE = 0,
+	PMD_INIT_POST_PCI_PROBE = 1,
 };
 
 /**
@@ -93,9 +103,9 @@ void rte_eal_driver_register(struct rte_driver *driver);
 void rte_eal_driver_unregister(struct rte_driver *driver);
 
 /**
- * Initalize all the registered drivers in this process
+ * Initialize all the registered drivers in this process
  */
-int rte_eal_dev_init(void);
+int rte_eal_dev_init(uint8_t init_priority);
 
 #define PMD_REGISTER_DRIVER(d)\
 void devinitfn_ ##d(void);\
lib/librte_eal/linuxapp/eal/eal.c +10 -1
index d204387..573fd06 100644
@@ -75,6 +75,7 @@
 #include <rte_atomic.h>
 #include <malloc_heap.h>
 #include <rte_eth_ring.h>
+#include <rte_dev.h>
 
 #include "eal_private.h"
 #include "eal_thread.h"
@@ -1097,7 +1098,7 @@ rte_eal_init(int argc, char **argv)
 	RTE_LOG(DEBUG, EAL, "Master core %u is ready (tid=%x)\n",
 		rte_config.master_lcore, (int)thread_id);
 
-	if (rte_eal_dev_init() < 0)
+	if (rte_eal_dev_init(PMD_INIT_PRE_PCI_PROBE) < 0)
 		rte_panic("Cannot init pmd devices\n");
 
 	RTE_LCORE_FOREACH_SLAVE(i) {
@@ -1127,6 +1128,14 @@ rte_eal_init(int argc, char **argv)
 	rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
 	rte_eal_mp_wait_lcore();
 
+	/* Probe & Initialize PCI devices */
+	if (rte_eal_pci_probe())
+			rte_panic("Cannot probe PCI\n");
+
+	/* Initialize any outstanding devices */
+	if (rte_eal_dev_init(PMD_INIT_POST_PCI_PROBE) < 0)
+		rte_panic("Cannot init pmd devices\n");
+
 	return fctret;
 }
 
Signature · 1 line
1.7.0.7
#128 lore raw

PATCH v10 4/5 bond: unit tests

In reply to a message not in the archive

Including:
- code to generate packet bursts for testing rx and tx functionality of bonded device
- virtual/stubbed out ethdev for use as slave ethdev in testing

---
 app/test/Makefile                 |    4 +-
 app/test/commands.c               |    7 +
 app/test/packet_burst_generator.c |  287 +++
 app/test/packet_burst_generator.h |   78 +
 app/test/test.h                   |    1 +
 app/test/test_link_bonding.c      | 3958 +++++++++++++++++++++++++++++++++++++
 app/test/virtual_pmd.c            |  574 ++++++
 app/test/virtual_pmd.h            |   74 +
 8 files changed, 4982 insertions(+), 1 deletions(-)
 create mode 100644 app/test/packet_burst_generator.c
 create mode 100644 app/test/packet_burst_generator.h
 create mode 100644 app/test/test_link_bonding.c
 create mode 100644 app/test/virtual_pmd.c
 create mode 100644 app/test/virtual_pmd.h
app/test/Makefile +3 -1
index 45d0cf2..cec2f2f 100644
@@ -102,7 +102,9 @@ SRCS-$(CONFIG_RTE_APP_TEST) += test_ivshmem.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_distributor.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_distributor_perf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_devargs.c
-
+SRCS-$(CONFIG_RTE_APP_TEST) += virtual_pmd.c
+SRCS-$(CONFIG_RTE_APP_TEST) += packet_burst_generator.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_link_bonding.c
 ifeq ($(CONFIG_RTE_APP_TEST),y)
 SRCS-$(CONFIG_RTE_LIBRTE_ACL) += test_acl.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring.c
app/test/commands.c +7 -0
index c9dc085..5f23420 100644
@@ -159,6 +159,10 @@ static void cmd_autotest_parsed(void *parsed_result,
 		ret = test_timer();
 	if (!strcmp(res->autotest, "timer_perf_autotest"))
 		ret = test_timer_perf();
+#ifdef RTE_LIBRTE_PMD_BOND
+	if (!strcmp(res->autotest, "link_bonding_autotest"))
+		ret = test_link_bonding();
+#endif
 	if (!strcmp(res->autotest, "mempool_autotest"))
 		ret = test_mempool();
 	if (!strcmp(res->autotest, "mempool_perf_autotest"))
@@ -227,6 +231,9 @@ cmdline_parse_token_string_t cmd_autotest_autotest =
 			"alarm_autotest#interrupt_autotest#"
 			"version_autotest#eal_fs_autotest#"
 			"cmdline_autotest#func_reentrancy_autotest#"
+#ifdef RTE_LIBRTE_PMD_BOND
+			"link_bonding_autotest#"
+#endif
 			"mempool_perf_autotest#hash_perf_autotest#"
 			"memcpy_perf_autotest#ring_perf_autotest#"
 			"red_autotest#meter_autotest#sched_autotest#"
app/test/packet_burst_generator.c new file +287 -0

287 lines not on this page · raw message

app/test/packet_burst_generator.h new file +78 -0

78 lines not on this page · raw message

app/test/test.h +1 -0
index c54e7ef..c00e1d6 100644
@@ -97,6 +97,7 @@ int test_distributor(void);
 int test_distributor_perf(void);
 int test_kvargs(void);
 int test_devargs(void);
+int test_link_bonding(void);
 
 int test_pci_run;
 
app/test/test_link_bonding.c new file +3958 -0

2,599 lines not on this page · raw message

app/test/virtual_pmd.c new file +574 -0

574 lines not on this page · raw message

app/test/virtual_pmd.h new file +74 -0

74 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.7.0.7

Part of the diff is not shown here. View the raw message.

#129 lore raw

PATCH v10 5/5 bond: testpmd support

In reply to a message not in the archive

- Includes the ability to create new bonded devices.
- Add /remove bonding slave devices.
- Interogate bonded device stats/configuration
- Change bonding modes and select balance transmit polices

---
 app/test-pmd/cmdline.c    |  579 +++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/config.c     |    4 +-
 app/test-pmd/parameters.c |    3 +
 app/test-pmd/testpmd.c    |   40 +++-
 app/test-pmd/testpmd.h    |    2 +
 5 files changed, 619 insertions(+), 9 deletions(-)
app/test-pmd/cmdline.c +579 -0
index f61a31c..345be11 100644
@@ -84,6 +84,9 @@
 #include <cmdline_socket.h>
 #include <cmdline.h>
 #include <rte_pci_dev_ids.h>
+#ifdef RTE_LIBRTE_PMD_BOND
+#include <rte_eth_bond.h>
+#endif
 
 #include "testpmd.h"
 
@@ -412,6 +415,31 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"   Show the bypass configuration for a bypass enabled NIC"
 			" using the lowest port on the NIC.\n\n"
 #endif
+#ifdef RTE_LIBRTE_PMD_BOND
+			"create bonded device (mode) (socket)\n"
+			"	Create a new bonded device with specific bonding mode and socket.\n\n"
+
+			"add bonding slave (slave_id) (port_id)\n"
+			"	Add a slave device to a bonded device.\n\n"
+
+			"remove bonding slave (slave_id) (port_id)\n"
+			"	Remove a slave device from a bonded device.\n\n"
+
+			"set bonding mode (value) (port_id)\n"
+			"	Set the bonding mode on a bonded device.\n\n"
+
+			"set bonding primary (slave_id) (port_id)\n"
+			"	Set the primary slave for a bonded device.\n\n"
+
+			"show bonding config (port_id)\n"
+			"	Show the bonding config for port_id.\n\n"
+
+			"set bonding mac_addr (port_id) (address)\n"
+			"	Set the MAC address of a bonded device.\n\n"
+
+			"set bonding xmit_balance_policy (port_id) (l2|l23|l34)\n"
+			"	Set the transmit balance policy for bonded device running in balance mode.\n\n"
+#endif
 
 			, list_pkt_forwarding_modes()
 		);
@@ -3039,6 +3067,547 @@ cmdline_parse_inst_t cmd_show_bypass_config = {
 };
 #endif
 
+#ifdef RTE_LIBRTE_PMD_BOND
+/* *** SET BONDING MODE *** */
+struct cmd_set_bonding_mode_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t mode;
+	uint8_t value;
+	uint8_t port_id;
+};
+
+static void cmd_set_bonding_mode_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_mode_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+
+	/* Set the bonding mode for the relevant port. */
+	if (0 != rte_eth_bond_mode_set(port_id, res->value))
+		printf("\t Failed to set bonding mode for port = %d.\n", port_id);
+}
+
+cmdline_parse_token_string_t cmd_setbonding_mode_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_mode_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_mode_mode =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
+		mode, "mode");
+cmdline_parse_token_num_t cmd_setbonding_mode_value =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+		value, UINT8);
+cmdline_parse_token_num_t cmd_setbonding_mode_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bonding_mode = {
+		.f = cmd_set_bonding_mode_parsed,
+		.help_str = "set bonding mode (mode_value) (port_id): Set the bonding mode for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *) &cmd_setbonding_mode_set,
+				(void *) &cmd_setbonding_mode_bonding,
+				(void *) &cmd_setbonding_mode_mode,
+				(void *) &cmd_setbonding_mode_value,
+				(void *) &cmd_setbonding_mode_port,
+				NULL
+		}
+};
+
+/* *** SET BALANCE XMIT POLICY *** */
+struct cmd_set_bonding_balance_xmit_policy_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t balance_xmit_policy;
+	uint8_t port_id;
+	cmdline_fixed_string_t policy;
+};
+
+static void cmd_set_bonding_balance_xmit_policy_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_balance_xmit_policy_result *res = parsed_result;
+	portid_t port_id = res->port_id;
+	uint8_t policy;
+
+	if (!strcmp(res->policy, "l2")) {
+		policy = BALANCE_XMIT_POLICY_LAYER2;
+	} else if (!strcmp(res->policy, "l23")) {
+		policy = BALANCE_XMIT_POLICY_LAYER23;
+	} else if (!strcmp(res->policy, "l34")) {
+		policy = BALANCE_XMIT_POLICY_LAYER34;
+	} else {
+		printf("\t Invalid xmit policy selection");
+		return;
+	}
+
+	/* Set the bonding mode for the relevant port. */
+	if (0 != rte_eth_bond_xmit_policy_set(port_id, policy)) {
+		printf("\t Failed to set bonding balance xmit policy for port = %d.\n",
+				port_id);
+	}
+}
+
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_balance_xmit_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		balance_xmit_policy, "balance_xmit_policy");
+cmdline_parse_token_num_t cmd_setbonding_balance_xmit_policy_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		port_id, UINT8);
+cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_policy =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
+		policy, "l2#l23#l34");
+
+cmdline_parse_inst_t cmd_set_balance_xmit_policy = {
+		.f = cmd_set_bonding_balance_xmit_policy_parsed,
+		.help_str = "set bonding balance_xmit_policy (port_id) (policy_value): Set the bonding balance_xmit_policy for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_setbonding_balance_xmit_policy_set,
+				(void *)&cmd_setbonding_balance_xmit_policy_bonding,
+				(void *)&cmd_setbonding_balance_xmit_policy_balance_xmit_policy,
+				(void *)&cmd_setbonding_balance_xmit_policy_port,
+				(void *)&cmd_setbonding_balance_xmit_policy_policy,
+				NULL
+		}
+};
+
+/* *** SHOW NIC BONDING CONFIGURATION *** */
+struct cmd_show_bonding_config_result {
+	cmdline_fixed_string_t show;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+};
+
+static void cmd_show_bonding_config_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_show_bonding_config_result *res = parsed_result;
+	int bonding_mode;
+	uint8_t slaves[RTE_MAX_ETHPORTS];
+	int num_slaves, num_active_slaves;
+	int primary_id;
+	int i;
+	portid_t port_id = res->port_id;
+
+	/* Display the bonding mode.*/
+	bonding_mode = rte_eth_bond_mode_get(port_id);
+	if (bonding_mode < 0) {
+		printf("\tFailed to get bonding mode for port = %d\n", port_id);
+		return;
+	} else
+		printf("\tBonding mode: %d\n", bonding_mode);
+
+	if (bonding_mode == BONDING_MODE_BALANCE) {
+		int balance_xmit_policy;
+
+		balance_xmit_policy = rte_eth_bond_xmit_policy_get(port_id);
+		if (balance_xmit_policy < 0) {
+			printf("\tFailed to get balance xmit policy for port = %d\n",
+					port_id);
+			return;
+		} else {
+			printf("\tBalance Xmit Policy: ");
+
+			switch (balance_xmit_policy) {
+			case BALANCE_XMIT_POLICY_LAYER2:
+				printf("BALANCE_XMIT_POLICY_LAYER2");
+				break;
+			case BALANCE_XMIT_POLICY_LAYER23:
+				printf("BALANCE_XMIT_POLICY_LAYER23");
+				break;
+			case BALANCE_XMIT_POLICY_LAYER34:
+				printf("BALANCE_XMIT_POLICY_LAYER34");
+				break;
+			}
+			printf("\n");
+		}
+	}
+
+	num_slaves = rte_eth_bond_slaves_get(port_id, slaves, RTE_MAX_ETHPORTS);
+
+	if (num_slaves < 0) {
+		printf("\tFailed to get slave list for port = %d\n", port_id);
+		return;
+	}
+	if (num_slaves > 0) {
+		printf("\tSlaves (%d): [", num_slaves);
+		for (i = 0; i < num_slaves - 1; i++)
+			printf("%d ", slaves[i]);
+
+		printf("%d]\n", slaves[num_slaves - 1]);
+	} else {
+		printf("\tSlaves: []\n");
+
+	}
+
+	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
+			RTE_MAX_ETHPORTS);
+
+	if (num_active_slaves < 0) {
+		printf("\tFailed to get active slave list for port = %d\n", port_id);
+		return;
+	}
+	if (num_active_slaves > 0) {
+		printf("\tActive Slaves (%d): [", num_active_slaves);
+		for (i = 0; i < num_active_slaves - 1; i++)
+			printf("%d ", slaves[i]);
+
+		printf("%d]\n", slaves[num_active_slaves - 1]);
+
+	} else {
+		printf("\tActive Slaves: []\n");
+
+	}
+
+	primary_id = rte_eth_bond_primary_get(port_id);
+	if (primary_id < 0) {
+		printf("\tFailed to get primary slave for port = %d\n", port_id);
+		return;
+	} else
+		printf("\tPrimary: [%d]\n", primary_id);
+
+}
+
+cmdline_parse_token_string_t cmd_showbonding_config_show =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		show, "show");
+cmdline_parse_token_string_t cmd_showbonding_config_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_showbonding_config_config =
+TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
+		config, "config");
+cmdline_parse_token_num_t cmd_showbonding_config_port =
+TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_config_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_show_bonding_config = {
+		.f = cmd_show_bonding_config_parsed,
+		.help_str =	"show bonding config (port_id): Show the bonding config for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_showbonding_config_show,
+				(void *)&cmd_showbonding_config_bonding,
+				(void *)&cmd_showbonding_config_config,
+				(void *)&cmd_showbonding_config_port,
+				NULL
+		}
+};
+
+/* *** SET BONDING PRIMARY *** */
+struct cmd_set_bonding_primary_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t primary;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_set_bonding_primary_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bonding_primary_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_primary_set(master_port_id, slave_port_id)) {
+		printf("\t Failed to set primary slave for port = %d.\n",
+				master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_setbonding_primary_set =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		set, "set");
+cmdline_parse_token_string_t cmd_setbonding_primary_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_setbonding_primary_primary =
+TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
+		primary, "primary");
+cmdline_parse_token_num_t cmd_setbonding_primary_slave =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+		slave_id, UINT8);
+cmdline_parse_token_num_t cmd_setbonding_primary_port =
+TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_set_bonding_primary = {
+		.f = cmd_set_bonding_primary_parsed,
+		.help_str = "set bonding primary (slave_id) (port_id): Set the primary slave for port_id",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_setbonding_primary_set,
+				(void *)&cmd_setbonding_primary_bonding,
+				(void *)&cmd_setbonding_primary_primary,
+				(void *)&cmd_setbonding_primary_slave,
+				(void *)&cmd_setbonding_primary_port,
+				NULL
+		}
+};
+
+/* *** ADD SLAVE *** */
+struct cmd_add_bonding_slave_result {
+	cmdline_fixed_string_t add;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t slave;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_add_bonding_slave_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_add_bonding_slave_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_slave_add(master_port_id, slave_port_id)) {
+		printf("\t Failed to add slave %d to master port = %d.\n",
+				slave_port_id, master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_addbonding_slave_add =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		add, "add");
+cmdline_parse_token_string_t cmd_addbonding_slave_bonding =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		bonding, "bonding");
+cmdline_parse_token_string_t cmd_addbonding_slave_slave =
+TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
+		slave, "slave");
+cmdline_parse_token_num_t cmd_addbonding_slave_slaveid =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+		slave_id, UINT8);
+cmdline_parse_token_num_t cmd_addbonding_slave_port =
+TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
+		port_id, UINT8);
+
+cmdline_parse_inst_t cmd_add_bonding_slave = {
+		.f = cmd_add_bonding_slave_parsed,
+		.help_str = "add bonding slave (slave_id) (port_id): Add a slave device to a bonded device",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_addbonding_slave_add,
+				(void *)&cmd_addbonding_slave_bonding,
+				(void *)&cmd_addbonding_slave_slave,
+				(void *)&cmd_addbonding_slave_slaveid,
+				(void *)&cmd_addbonding_slave_port,
+				NULL
+		}
+};
+
+/* *** REMOVE SLAVE *** */
+struct cmd_remove_bonding_slave_result {
+	cmdline_fixed_string_t remove;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t slave;
+	uint8_t slave_id;
+	uint8_t port_id;
+};
+
+static void cmd_remove_bonding_slave_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_remove_bonding_slave_result *res = parsed_result;
+	portid_t master_port_id = res->port_id;
+	portid_t slave_port_id = res->slave_id;
+
+	/* Set the primary slave for a bonded device. */
+	if (0 != rte_eth_bond_slave_remove(master_port_id, slave_port_id)) {
+		printf("\t Failed to remove slave %d from master port = %d.\n",
+				slave_port_id, master_port_id);
+		return;
+	}
+	init_port_config();
+}
+
+cmdline_parse_token_string_t cmd_removebonding_slave_remove =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				remove, "remove");
+cmdline_parse_token_string_t cmd_removebonding_slave_bonding =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				bonding, "bonding");
+cmdline_parse_token_string_t cmd_removebonding_slave_slave =
+		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				slave, "slave");
+cmdline_parse_token_num_t cmd_removebonding_slave_slaveid =
+		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				slave_id, UINT8);
+cmdline_parse_token_num_t cmd_removebonding_slave_port =
+		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
+				port_id, UINT8);
+
+cmdline_parse_inst_t cmd_remove_bonding_slave = {
+		.f = cmd_remove_bonding_slave_parsed,
+		.help_str = "remove bonding slave (slave_id) (port_id): Remove a slave device from a bonded device",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_removebonding_slave_remove,
+				(void *)&cmd_removebonding_slave_bonding,
+				(void *)&cmd_removebonding_slave_slave,
+				(void *)&cmd_removebonding_slave_slaveid,
+				(void *)&cmd_removebonding_slave_port,
+				NULL
+		}
+};
+
+/* *** CREATE BONDED DEVICE *** */
+struct cmd_create_bonded_device_result {
+	cmdline_fixed_string_t create;
+	cmdline_fixed_string_t bonded;
+	cmdline_fixed_string_t device;
+	uint8_t mode;
+	uint8_t socket;
+};
+
+static int bond_dev_num = 0;
+
+static void cmd_create_bonded_device_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_create_bonded_device_result *res = parsed_result;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+	int port_id;
+
+	if (test_done == 0) {
+		printf("Please stop forwarding first\n");
+		return;
+	}
+
+	snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "eth_bond_testpmd_%d",
+			bond_dev_num++);
+
+	/* Create a new bonded device. */
+	port_id = rte_eth_bond_create(ethdev_name, res->mode, res->socket);
+	if (port_id < 0) {
+		printf("\t Failed to create bonded device.\n");
+		return;
+	} else {
+		printf("Created new bonded device %s on (port %d).\n", ethdev_name,
+				port_id);
+
+		/* Update number of ports */
+		nb_ports = rte_eth_dev_count();
+		reconfig(port_id);
+		rte_eth_promiscuous_enable(port_id);
+	}
+
+}
+
+cmdline_parse_token_string_t cmd_createbonded_device_create =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				create, "create");
+cmdline_parse_token_string_t cmd_createbonded_device_bonded =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				bonded, "bonded");
+cmdline_parse_token_string_t cmd_createbonded_device_device =
+		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
+				device, "device");
+cmdline_parse_token_num_t cmd_createbonded_device_mode =
+		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+				mode, UINT8);
+cmdline_parse_token_num_t cmd_createbonded_device_socket =
+		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
+				socket, UINT8);
+
+cmdline_parse_inst_t cmd_create_bonded_device = {
+		.f = cmd_create_bonded_device_parsed,
+		.help_str = "create bonded device (mode) (socket): Create a new bonded device with specific bonding mode and socket",
+		.data = NULL,
+		.tokens = {
+				(void *)&cmd_createbonded_device_create,
+				(void *)&cmd_createbonded_device_bonded,
+				(void *)&cmd_createbonded_device_device,
+				(void *)&cmd_createbonded_device_mode,
+				(void *)&cmd_createbonded_device_socket,
+				NULL
+		}
+};
+
+/* *** SET MAC ADDRESS IN BONDED DEVICE *** */
+struct cmd_set_bond_mac_addr_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t bonding;
+	cmdline_fixed_string_t mac_addr;
+	uint8_t port_num;
+	struct ether_addr address;
+};
+
+static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
+		__attribute__((unused))  struct cmdline *cl,
+		__attribute__((unused)) void *data)
+{
+	struct cmd_set_bond_mac_addr_result *res = parsed_result;
+	int ret;
+
+	if (res->port_num >= nb_ports) {
+		printf("Port id %d must be less than %d\n", res->port_num, nb_ports);
+		return;
+	}
+
+	ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
+
+	/* check the return value and print it if is < 0 */
+	if (ret < 0)
+		printf("set_bond_mac_addr error: (%s)\n", strerror(-ret));
+}
+
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_set =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, set, "set");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, bonding,
+				"bonding");
+cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac =
+		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, mac_addr,
+				"mac_addr");
+cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum =
+		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result, port_num, UINT8);
+cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr =
+		TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result, address);
+
+cmdline_parse_inst_t cmd_set_bond_mac_addr = {
+		.f = cmd_set_bond_mac_addr_parsed,
+		.data = (void *) 0,
+		.help_str = "set bonding mac_addr (port_id) (address): ",
+		.tokens = {
+				(void *)&cmd_set_bond_mac_addr_set,
+				(void *)&cmd_set_bond_mac_addr_bonding,
+				(void *)&cmd_set_bond_mac_addr_mac,
+				(void *)&cmd_set_bond_mac_addr_portnum,
+				(void *)&cmd_set_bond_mac_addr_addr,
+				NULL
+		}
+};
+
+#endif /* RTE_LIBRTE_PMD_BOND */
+
 /* *** SET FORWARDING MODE *** */
 struct cmd_set_fwd_mode_result {
 	cmdline_fixed_string_t set;
@@ -6768,6 +7337,16 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_bypass_timeout,
 	(cmdline_parse_inst_t *)&cmd_show_bypass_config,
 #endif
+#ifdef RTE_LIBRTE_PMD_BOND
+	(cmdline_parse_inst_t *) &cmd_set_bonding_mode,
+	(cmdline_parse_inst_t *) &cmd_show_bonding_config,
+	(cmdline_parse_inst_t *) &cmd_set_bonding_primary,
+	(cmdline_parse_inst_t *) &cmd_add_bonding_slave,
+	(cmdline_parse_inst_t *) &cmd_remove_bonding_slave,
+	(cmdline_parse_inst_t *) &cmd_create_bonded_device,
+	(cmdline_parse_inst_t *) &cmd_set_bond_mac_addr,
+	(cmdline_parse_inst_t *) &cmd_set_balance_xmit_policy,
+#endif
 	(cmdline_parse_inst_t *)&cmd_vlan_offload,
 	(cmdline_parse_inst_t *)&cmd_vlan_tpid,
 	(cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all,
app/test-pmd/config.c +3 -1
index 32f2134..c72f6ee 100644
@@ -252,6 +252,7 @@ void
 port_infos_display(portid_t port_id)
 {
 	struct rte_port *port;
+	struct ether_addr mac_addr;
 	struct rte_eth_link link;
 	int vlan_offload;
 	struct rte_mempool * mp;
@@ -265,7 +266,8 @@ port_infos_display(portid_t port_id)
 	rte_eth_link_get_nowait(port_id, &link);
 	printf("\n%s Infos for port %-2d %s\n",
 	       info_border, port_id, info_border);
-	print_ethaddr("MAC address: ", &port->eth_addr);
+	rte_eth_macaddr_get(port_id, &mac_addr);
+	print_ethaddr("MAC address: ", &mac_addr);
 	printf("\nConnect to socket: %u", port->socket_id);
 
 	if (port_numa[port_id] != NUMA_NO_CONFIG) {
app/test-pmd/parameters.c +3 -0
index 4bca0b0..9573a43 100644
@@ -75,6 +75,9 @@
 #include <cmdline_parse.h>
 #include <cmdline_parse_etheraddr.h>
 #endif
+#ifdef RTE_LIBRTE_PMD_BOND
+#include <rte_eth_bond.h>
+#endif
 
 #include "testpmd.h"
 
app/test-pmd/testpmd.c +32 -8
index 16fe596..e8a4b45 100644
@@ -300,7 +300,7 @@ struct rte_fdir_conf fdir_conf = {
 	.drop_queue = 127,
 };
 
-static volatile int test_done = 1; /* stop packet forwarding when set to 1. */
+volatile int test_done = 1; /* stop packet forwarding when set to 1. */
 
 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
@@ -625,6 +625,32 @@ init_config(void)
 		rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
 }
 
+
+void
+reconfig(portid_t new_port_id)
+{
+	struct rte_port *port;
+
+	/* Reconfiguration of Ethernet ports. */
+	ports = rte_realloc(ports,
+			    sizeof(struct rte_port) * nb_ports,
+			    CACHE_LINE_SIZE);
+	if (ports == NULL) {
+		rte_exit(EXIT_FAILURE, "rte_realloc(%d struct rte_port) failed\n",
+				nb_ports);
+	}
+
+	port = &ports[new_port_id];
+	rte_eth_dev_info_get(new_port_id, &port->dev_info);
+
+	/* set flag to initialize port/queue */
+	port->need_reconfig = 1;
+	port->need_reconfig_queues = 1;
+
+	init_port_config();
+}
+
+
 int
 init_fwd_streams(void)
 {
@@ -1252,7 +1278,7 @@ start_port(portid_t pid)
 	portid_t pi;
 	queueid_t qi;
 	struct rte_port *port;
-	uint8_t *mac_addr;
+	struct ether_addr mac_addr;
 
 	if (test_done == 0) {
 		printf("Please stop forwarding first\n");
@@ -1380,10 +1406,11 @@ start_port(portid_t pid)
 			RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
 			printf("Port %d can not be set into started\n", pi);
 
-		mac_addr = port->eth_addr.addr_bytes;
+		rte_eth_macaddr_get(pi, &mac_addr);
 		printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
-		       mac_addr[0], mac_addr[1], mac_addr[2],
-		       mac_addr[3], mac_addr[4], mac_addr[5]);
+				mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
+				mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
+				mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
 
 		/* at least one port started, need checking link status */
 		need_check_link_status = 1;
@@ -1826,9 +1853,6 @@ main(int argc, char** argv)
 	if (diag < 0)
 		rte_panic("Cannot init EAL\n");
 
-	if (rte_eal_pci_probe())
-		rte_panic("Cannot probe PCI\n");
-
 	nb_ports = (portid_t) rte_eth_dev_count();
 	if (nb_ports == 0)
 		rte_exit(EXIT_FAILURE, "No probed ethernet devices - "
app/test-pmd/testpmd.h +2 -0
index e263616..ac86bfe 100644
@@ -281,6 +281,7 @@ extern uint16_t port_topology; /**< set by "--port-topology" parameter */
 extern uint8_t no_flush_rx; /**<set by "--no-flush-rx" parameter */
 extern uint8_t  mp_anon; /**< set by "--mp-anon" parameter */
 extern uint8_t no_link_check; /**<set by "--disable-link-check" parameter */
+extern volatile int test_done; /* stop packet forwarding when set to 1. */
 
 #ifdef RTE_NIC_BYPASS
 extern uint32_t bypass_timeout; /**< Store the NIC bypass watchdog timeout */
@@ -454,6 +455,7 @@ void fwd_config_display(void);
 void rxtx_config_display(void);
 void fwd_config_setup(void);
 void set_def_fwd_config(void);
+void reconfig(portid_t new_port_id);
 int init_fwd_streams(void);
 
 void port_mtu_set(portid_t port_id, uint16_t mtu);
Signature · 1 line
1.7.0.7
#130 lore raw

PATCH v8 1/6 Link Bonding Library (lib/librte_pmd_bond)

In reply to a message not in the archive

Initial release with support for
Mode 0 - Round Robin
Mode 1 - Active Backup
Mode 2 - Balance -> Supports 3 transmit polices (layer 2, layer 2+3, layer 3+4) Mode 3 - Broadcast

---
 config/common_bsdapp                       |    5 +
 config/common_linuxapp                     |    5 +
 lib/Makefile                               |    1 +
 lib/librte_pmd_bond/Makefile               |   34 +
 lib/librte_pmd_bond/rte_eth_bond.h         |  255 ++++++
 lib/librte_pmd_bond/rte_eth_bond_api.c     |  670 +++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond_pmd.c     | 1228 ++++++++++++++++++++++++++++
 lib/librte_pmd_bond/rte_eth_bond_private.h |  218 +++++
 lib/librte_pmd_bond/rte_eth_bond_vargs.c   |  255 ++++++
 mk/rte.app.mk                              |    5 +
 10 files changed, 2676 insertions(+), 0 deletions(-)
 create mode 100644 lib/librte_pmd_bond/Makefile
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond.h
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_api.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_pmd.c
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_private.h
 create mode 100644 lib/librte_pmd_bond/rte_eth_bond_vargs.c
config/common_bsdapp +5 -0
index 989e1da..214398b 100644
@@ -206,6 +206,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=y
 
 #
+# Compile link bonding pmd library
+#
+CONFIG_RTE_LIBRTE_PMD_BOND=y
+
+#
 # Do prefetch of packet data within PMD driver receive function
 #
 CONFIG_RTE_PMD_PACKET_PREFETCH=y
config/common_linuxapp +5 -0
index 5b896c3..2bf90df 100644
@@ -244,6 +244,11 @@ CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
 CONFIG_RTE_LIBRTE_PMD_PCAP=n
 
 #
+# Compile link bonding pmd library
+#
+CONFIG_RTE_LIBRTE_PMD_BOND=y
+
+#
 # Compile Xen PMD
 #
 CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
lib/Makefile +1 -0
index c58c0c9..88e875f 100644
@@ -49,6 +49,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += librte_pmd_pcap
 DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += librte_pmd_virtio
 DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += librte_pmd_vmxnet3
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += librte_pmd_xenvirt
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += librte_pmd_bond
 DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash
 DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm
 DIRS-$(CONFIG_RTE_LIBRTE_ACL) += librte_acl
lib/librte_pmd_bond/Makefile new file +34 -0
new file mode 100644
index 0000000..4128f61
@@ -0,0 +1,34 @@
+# <COPYRIGHT_TAG>
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_bond.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond_api.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond_pmd.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += rte_eth_bond_vargs.c
+
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_eth_bond.h
+
+
+# this lib depends upon:
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_mbuf
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_malloc
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_kvargs
+
+include $(RTE_SDK)/mk/rte.lib.mk
lib/librte_pmd_bond/rte_eth_bond.h new file +255 -0

255 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_api.c new file +670 -0

670 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_pmd.c new file +1228 -0

1,228 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_private.h new file +218 -0

218 lines not on this page · raw message

lib/librte_pmd_bond/rte_eth_bond_vargs.c new file +255 -0

255 lines not on this page · raw message

mk/rte.app.mk +5 -0
index 8db9cde..2539f46 100644
@@ -205,8 +205,13 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMD_PCAP),y)
 LDLIBS += -lrte_pmd_pcap -lpcap
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_PMD_BOND),y)
+LDLIBS += -lrte_pmd_bond
 endif
 
+endif
+
+
 LDLIBS += $(EXECENV_LDLIBS)
 
 LDLIBS += --end-group
Signature · 1 line
1.7.0.7
#131 lore raw

PATCH v8 2/6 Support for unique interface naming of pmds

In reply to a message not in the archive

Adding support to rte_eth_dev_data structure to support unique name identifier for ethdevs to support adding slave ethdevs (specifically virtual devices which have no public unique identifier) to a link bonding device. This changes the API rte_eth_dev_allocate() to require a const char *name when allocating a ethdev, which also verifies that the name is unique and hasn’t been already used by an existed allocated rte_eth_dev. Also contains updates to virtual pmd’s to now call the API with a name parameter.

---
 lib/librte_ether/rte_ethdev.c            |   32 +++++++++++++++++++++++++++--
 lib/librte_ether/rte_ethdev.h            |    7 +++++-
 lib/librte_pmd_pcap/rte_eth_pcap.c       |   22 ++++++++++----------
 lib/librte_pmd_ring/rte_eth_ring.c       |   32 +++++++++++++++--------------
 lib/librte_pmd_ring/rte_eth_ring.h       |    3 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c |    2 +-
 6 files changed, 66 insertions(+), 32 deletions(-)
lib/librte_ether/rte_ethdev.c +29 -3
index 7256841..d938603 100644
@@ -65,6 +65,7 @@
 #include <rte_mbuf.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
+#include <rte_string_fns.h>
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"
@@ -153,21 +154,40 @@ rte_eth_dev_data_alloc(void)
 				RTE_MAX_ETHPORTS * sizeof(*rte_eth_dev_data));
 }
 
+static struct rte_eth_dev *
+rte_eth_dev_allocated(const char *name)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_ports; i++) {
+		if (strcmp(rte_eth_devices[i].data->name, name) == 0)
+			return &rte_eth_devices[i];
+	}
+	return NULL;
+}
+
 struct rte_eth_dev *
-rte_eth_dev_allocate(void)
+rte_eth_dev_allocate(const char *name)
 {
 	struct rte_eth_dev *eth_dev;
 
 	if (nb_ports == RTE_MAX_ETHPORTS) {
-		PMD_DEBUG_TRACE("Reached maximum number of ethernet ports\n");
+		PMD_DEBUG_TRACE("Reached maximum number of Ethernet ports\n");
 		return NULL;
 	}
 
 	if (rte_eth_dev_data == NULL)
 		rte_eth_dev_data_alloc();
 
+	if (rte_eth_dev_allocated(name) != NULL) {
+		PMD_DEBUG_TRACE("Ethernet Device with name %s already allocated!\n");
+		return NULL;
+	}
+
 	eth_dev = &rte_eth_devices[nb_ports];
 	eth_dev->data = &rte_eth_dev_data[nb_ports];
+	rte_snprintf(eth_dev->data->name, sizeof(eth_dev->data->name),
+			"%s", name);
 	eth_dev->data->port_id = nb_ports++;
 	return eth_dev;
 }
@@ -178,11 +198,17 @@ rte_eth_dev_init(struct rte_pci_driver *pci_drv,
 {
 	struct eth_driver    *eth_drv;
 	struct rte_eth_dev *eth_dev;
+	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
 	int diag;
 
 	eth_drv = (struct eth_driver *)pci_drv;
 
-	eth_dev = rte_eth_dev_allocate();
+	/* Create unique Ethernet device name using PCI address */
+	rte_snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "%d:%d.%d",
+			pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
+
+	eth_dev = rte_eth_dev_allocate(ethdev_name);
 	if (eth_dev == NULL)
 		return -ENOMEM;
 
lib/librte_ether/rte_ethdev.h +6 -1
index 2406e45..50df654 100644
@@ -1497,6 +1497,8 @@ struct rte_eth_dev_sriov {
 };
 #define RTE_ETH_DEV_SRIOV(dev)         ((dev)->data->sriov)
 
+#define RTE_ETH_NAME_MAX_LEN (32)
+
 /**
  * @internal
  * The data part, with no function pointers, associated with each ethernet device.
@@ -1505,6 +1507,8 @@ struct rte_eth_dev_sriov {
  * processes in a multi-process configuration.
  */
 struct rte_eth_dev_data {
+	char name[RTE_ETH_NAME_MAX_LEN]; /**< Unique identifier name */
+
 	void **rx_queues; /**< Array of pointers to RX queues. */
 	void **tx_queues; /**< Array of pointers to TX queues. */
 	uint16_t nb_rx_queues; /**< Number of RX queues. */
@@ -1560,10 +1564,11 @@ extern uint8_t rte_eth_dev_count(void);
  * Allocates a new ethdev slot for an ethernet device and returns the pointer
  * to that slot for the driver to use.
  *
+ * @param	name	Unique identifier name for each Ethernet device
  * @return
  *   - Slot in the rte_dev_devices array for a new device;
  */
-struct rte_eth_dev *rte_eth_dev_allocate(void);
+struct rte_eth_dev *rte_eth_dev_allocate(const char *name);
 
 struct eth_driver;
 /**
lib/librte_pmd_pcap/rte_eth_pcap.c +11 -11
index b3dbbda..12b7e0c 100644
@@ -534,7 +534,7 @@ open_tx_iface(const char *key __rte_unused, const char *value, void *extra_args)
 
 
 static int
-rte_pmd_init_internals(const unsigned nb_rx_queues,
+rte_pmd_init_internals(const char *name, const unsigned nb_rx_queues,
 		const unsigned nb_tx_queues,
 		const unsigned numa_node,
 		struct pmd_internals **internals,
@@ -558,20 +558,20 @@ rte_pmd_init_internals(const unsigned nb_rx_queues,
 	/* now do all data allocation - for eth_dev structure, dummy pci driver
 	 * and internal (private) data
 	 */
-	data = rte_zmalloc_socket(NULL, sizeof(*data), 0, numa_node);
+	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
 	if (data == NULL)
 		goto error;
 
-	pci_dev = rte_zmalloc_socket(NULL, sizeof(*pci_dev), 0, numa_node);
+	pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, numa_node);
 	if (pci_dev == NULL)
 		goto error;
 
-	*internals = rte_zmalloc_socket(NULL, sizeof(**internals), 0, numa_node);
+	*internals = rte_zmalloc_socket(name, sizeof(**internals), 0, numa_node);
 	if (*internals == NULL)
 		goto error;
 
 	/* reserve an ethdev entry */
-	*eth_dev = rte_eth_dev_allocate();
+	*eth_dev = rte_eth_dev_allocate(name);
 	if (*eth_dev == NULL)
 		goto error;
 
@@ -617,7 +617,7 @@ rte_pmd_init_internals(const unsigned nb_rx_queues,
 }
 
 static int
-rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
+rte_eth_from_pcaps_n_dumpers(const char *name, pcap_t * const rx_queues[],
 		const unsigned nb_rx_queues,
 		pcap_dumper_t * const tx_queues[],
 		const unsigned nb_tx_queues,
@@ -634,7 +634,7 @@ rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
 	if (tx_queues == NULL && nb_tx_queues > 0)
 		return -1;
 
-	if (rte_pmd_init_internals(nb_rx_queues, nb_tx_queues, numa_node,
+	if (rte_pmd_init_internals(name, nb_rx_queues, nb_tx_queues, numa_node,
 			&internals, &eth_dev, kvlist) < 0)
 		return -1;
 
@@ -652,7 +652,7 @@ rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
 }
 
 static int
-rte_eth_from_pcaps(pcap_t * const rx_queues[],
+rte_eth_from_pcaps(const char *name, pcap_t * const rx_queues[],
 		const unsigned nb_rx_queues,
 		pcap_t * const tx_queues[],
 		const unsigned nb_tx_queues,
@@ -669,7 +669,7 @@ rte_eth_from_pcaps(pcap_t * const rx_queues[],
 	if (tx_queues == NULL && nb_tx_queues > 0)
 		return -1;
 
-	if (rte_pmd_init_internals(nb_rx_queues, nb_tx_queues, numa_node,
+	if (rte_pmd_init_internals(name, nb_rx_queues, nb_tx_queues, numa_node,
 			&internals, &eth_dev, kvlist) < 0)
 		return -1;
 
@@ -760,10 +760,10 @@ rte_pmd_pcap_devinit(const char *name, const char *params)
 		return -1;
 
 	if (using_dumpers)
-		return rte_eth_from_pcaps_n_dumpers(pcaps.pcaps, pcaps.num_of_rx,
+		return rte_eth_from_pcaps_n_dumpers(name, pcaps.pcaps, pcaps.num_of_rx,
 				dumpers.dumpers, dumpers.num_of_tx, numa_node, kvlist);
 
-	return rte_eth_from_pcaps(pcaps.pcaps, pcaps.num_of_rx, dumpers.pcaps,
+	return rte_eth_from_pcaps(name, pcaps.pcaps, pcaps.num_of_rx, dumpers.pcaps,
 			dumpers.num_of_tx, numa_node, kvlist);
 
 }
lib/librte_pmd_ring/rte_eth_ring.c +17 -15
index 10d4e24..f9174f1 100644
@@ -219,7 +219,7 @@ static struct eth_dev_ops ops = {
 };
 
 int
-rte_eth_from_rings(struct rte_ring *const rx_queues[],
+rte_eth_from_rings(const char *name, struct rte_ring *const rx_queues[],
 		const unsigned nb_rx_queues,
 		struct rte_ring *const tx_queues[],
 		const unsigned nb_tx_queues,
@@ -243,20 +243,20 @@ rte_eth_from_rings(struct rte_ring *const rx_queues[],
 	/* now do all data allocation - for eth_dev structure, dummy pci driver
 	 * and internal (private) data
 	 */
-	data = rte_zmalloc_socket(NULL, sizeof(*data), 0, numa_node);
+	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
 	if (data == NULL)
 		goto error;
 
-	pci_dev = rte_zmalloc_socket(NULL, sizeof(*pci_dev), 0, numa_node);
+	pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, numa_node);
 	if (pci_dev == NULL)
 		goto error;
 
-	internals = rte_zmalloc_socket(NULL, sizeof(*internals), 0, numa_node);
+	internals = rte_zmalloc_socket(name, sizeof(*internals), 0, numa_node);
 	if (internals == NULL)
 		goto error;
 
 	/* reserve an ethdev entry */
-	eth_dev = rte_eth_dev_allocate();
+	eth_dev = rte_eth_dev_allocate(name);
 	if (eth_dev == NULL)
 		goto error;
 
@@ -335,7 +335,7 @@ eth_dev_ring_create(const char *name, const unsigned numa_node,
 			return -1;
 	}
 
-	if (rte_eth_from_rings(rxtx, num_rings, rxtx, num_rings, numa_node))
+	if (rte_eth_from_rings(name, rxtx, num_rings, rxtx, num_rings, numa_node))
 		return -1;
 
 	return 0;
@@ -352,29 +352,31 @@ eth_dev_ring_pair_create(const char *name, const unsigned numa_node,
 	struct rte_ring *rx[RTE_PMD_RING_MAX_RX_RINGS];
 	struct rte_ring *tx[RTE_PMD_RING_MAX_TX_RINGS];
 	unsigned i;
-	char rng_name[RTE_RING_NAMESIZE];
+	char rx_rng_name[RTE_RING_NAMESIZE];
+	char tx_rng_name[RTE_RING_NAMESIZE];
 	unsigned num_rings = RTE_MIN(RTE_PMD_RING_MAX_RX_RINGS,
 			RTE_PMD_RING_MAX_TX_RINGS);
 
 	for (i = 0; i < num_rings; i++) {
-		rte_snprintf(rng_name, sizeof(rng_name), "ETH_RX%u_%s", i, name);
+		rte_snprintf(rx_rng_name, sizeof(rx_rng_name), "ETH_RX%u_%s", i, name);
 		rx[i] = (action == DEV_CREATE) ?
-				rte_ring_create(rng_name, 1024, numa_node,
+				rte_ring_create(rx_rng_name, 1024, numa_node,
 						RING_F_SP_ENQ|RING_F_SC_DEQ) :
-				rte_ring_lookup(rng_name);
+				rte_ring_lookup(rx_rng_name);
 		if (rx[i] == NULL)
 			return -1;
-		rte_snprintf(rng_name, sizeof(rng_name), "ETH_TX%u_%s", i, name);
+		rte_snprintf(tx_rng_name, sizeof(tx_rng_name), "ETH_TX%u_%s", i, name);
 		tx[i] = (action == DEV_CREATE) ?
-				rte_ring_create(rng_name, 1024, numa_node,
+				rte_ring_create(tx_rng_name, 1024, numa_node,
 						RING_F_SP_ENQ|RING_F_SC_DEQ):
-				rte_ring_lookup(rng_name);
+				rte_ring_lookup(tx_rng_name);
 		if (tx[i] == NULL)
 			return -1;
 	}
 
-	if (rte_eth_from_rings(rx, num_rings, tx, num_rings, numa_node) ||
-			rte_eth_from_rings(tx, num_rings, rx, num_rings, numa_node) )
+	if (rte_eth_from_rings(rx_rng_name, rx, num_rings, tx, num_rings,
+			numa_node) || rte_eth_from_rings(tx_rng_name, tx, num_rings, rx,
+					num_rings, numa_node))
 		return -1;
 
 	return 0;
lib/librte_pmd_ring/rte_eth_ring.h +2 -1
index ef29344..e6ae19e 100644
@@ -40,7 +40,8 @@ extern "C" {
 
 #include <rte_ring.h>
 
-int rte_eth_from_rings(struct rte_ring * const rx_queues[],
+int rte_eth_from_rings(const char *name,
+		struct rte_ring * const rx_queues[],
 		const unsigned nb_rx_queues,
 		struct rte_ring *const tx_queues[],
 		const unsigned nb_tx_queues,
lib/librte_pmd_xenvirt/rte_eth_xenvirt.c +1 -1
index 7c4d3fe..a0b4bdd 100644
@@ -647,7 +647,7 @@ eth_dev_xenvirt_create(const char *name, const char *params,
 		goto err;
 
 	/* reserve an ethdev entry */
-	eth_dev = rte_eth_dev_allocate();
+	eth_dev = rte_eth_dev_allocate(name);
 	if (eth_dev == NULL)
 		goto err;
 
Signature · 1 line
1.7.0.7