From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id 7DAD6B346 for ; Wed, 24 Sep 2014 12:52:22 +0200 (CEST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 24 Sep 2014 03:58:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.04,588,1406617200"; d="scan'208";a="596117801" Received: from fmsmsx108.amr.corp.intel.com ([10.18.124.206]) by fmsmga001.fm.intel.com with ESMTP; 24 Sep 2014 03:58:33 -0700 Received: from fmsmsx151.amr.corp.intel.com (10.18.125.4) by FMSMSX108.amr.corp.intel.com (10.18.124.206) with Microsoft SMTP Server (TLS) id 14.3.195.1; Wed, 24 Sep 2014 03:58:33 -0700 Received: from shsmsx152.ccr.corp.intel.com (10.239.6.52) by FMSMSX151.amr.corp.intel.com (10.18.125.4) with Microsoft SMTP Server (TLS) id 14.3.195.1; Wed, 24 Sep 2014 03:58:27 -0700 Received: from shsmsx101.ccr.corp.intel.com ([169.254.1.203]) by SHSMSX152.ccr.corp.intel.com ([169.254.6.190]) with mapi id 14.03.0195.001; Wed, 24 Sep 2014 18:58:25 +0800 From: "Xie, Huawei" To: "dev@dpdk.org" Thread-Topic: [PATCH] examples/vmdq: support i40e in vmdq example Thread-Index: AQHP1+XYW0yODSm1jE6fig+4eGw535wQHQew Date: Wed, 24 Sep 2014 10:58:25 +0000 Message-ID: References: <1411556015-27518-1-git-send-email-huawei.xie@intel.com> <1411556015-27518-2-git-send-email-huawei.xie@intel.com> In-Reply-To: <1411556015-27518-2-git-send-email-huawei.xie@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH] examples/vmdq: support i40e in vmdq example X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Sep 2014 10:52:23 -0000 This patch depends on "[dpdk-dev] [PATCH 0/6] i40e VMDQ support" > -----Original Message----- > From: Xie, Huawei > Sent: Wednesday, September 24, 2014 6:54 PM > To: dev@dpdk.org > Cc: Xie, Huawei > Subject: [PATCH] examples/vmdq: support i40e in vmdq example >=20 > This patch supports i40e in vmdq example. > 1. queue index is added by vmdq queue base in rte_eth_rx_burst. > 2. pool index is added by vmdq pool base when mac address is added to poo= ls. > 3. add some error message print > Besides, due to some limitation in PMD, > 1. mac addresses are needed to be pre-allocated to VMDQ pools. > 2. ports are started before mac allocation. >=20 > Signed-off-by: Huawei Xie > Acked-by: Chen Jing D(Mark) > Acked-by: Jijiang Liu > Acked-by: Changchun Ouyang > --- > examples/vmdq/main.c | 162 ++++++++++++++++++++++++++++++--------------- > ------ > 1 file changed, 97 insertions(+), 65 deletions(-) >=20 > diff --git a/examples/vmdq/main.c b/examples/vmdq/main.c > index 35df234..a7ffdef 100644 > --- a/examples/vmdq/main.c > +++ b/examples/vmdq/main.c > @@ -194,6 +194,13 @@ const uint16_t vlan_tags[] =3D { > 48, 49, 50, 51, 52, 53, 54, 55, > 56, 57, 58, 59, 60, 61, 62, 63, > }; > +const uint16_t num_vlans =3D RTE_DIM(vlan_tags); > +static uint16_t num_pf_queues, num_vmdq_queues; > +static uint16_t vmdq_pool_base, vmdq_queue_base; > +/* pool mac addr template, pool mac addr is like: 52 54 00 12 port# pool= # */ > +static struct ether_addr pool_addr_template =3D { > + .addr_bytes =3D {0x52, 0x54, 0x00, 0x12, 0x00, 0x00} > +}; >=20 > /* ethernet addresses of ports */ > static struct ether_addr vmdq_ports_eth_addr[RTE_MAX_ETHPORTS]; > @@ -213,22 +220,9 @@ get_eth_conf(struct rte_eth_conf *eth_conf, uint32_t > num_pools) > unsigned i; >=20 > conf.nb_queue_pools =3D (enum rte_eth_nb_pools)num_pools; > + conf.nb_pool_maps =3D num_pools; > conf.enable_default_pool =3D 0; > conf.default_pool =3D 0; /* set explicit value, even if not used */ > - switch (num_pools) { > - /* For 10G NIC like 82599, 128 is valid for queue number */ > - case MAX_POOL_NUM_10G: > - num_queues =3D MAX_QUEUE_NUM_10G; > - conf.nb_pool_maps =3D MAX_POOL_MAP_NUM_10G; > - break; > - /* For 1G NIC like i350, 82580 and 82576, 8 is valid for queue number *= / > - case MAX_POOL_NUM_1G: > - num_queues =3D MAX_QUEUE_NUM_1G; > - conf.nb_pool_maps =3D MAX_POOL_MAP_NUM_1G; > - break; > - default: > - return -1; > - } >=20 > for (i =3D 0; i < conf.nb_pool_maps; i++){ > conf.pool_map[i].vlan_id =3D vlan_tags[ i ]; > @@ -242,40 +236,6 @@ get_eth_conf(struct rte_eth_conf *eth_conf, uint32_t > num_pools) > } >=20 > /* > - * Validate the pool number accrording to the max pool number gotten for= m > dev_info > - * If the pool number is invalid, give the error message and return -1 > - */ > -static inline int > -validate_num_pools(uint32_t max_nb_pools) > -{ > - if (num_pools > max_nb_pools) { > - printf("invalid number of pools\n"); > - return -1; > - } > - > - switch (max_nb_pools) { > - /* For 10G NIC like 82599, 64 is valid for pool number */ > - case MAX_POOL_NUM_10G: > - if (num_pools !=3D MAX_POOL_NUM_10G) { > - printf("invalid number of pools\n"); > - return -1; > - } > - break; > - /* For 1G NIC like i350, 82580 and 82576, 8 is valid for pool number */ > - case MAX_POOL_NUM_1G: > - if (num_pools !=3D MAX_POOL_NUM_1G) { > - printf("invalid number of pools\n"); > - return -1; > - } > - break; > - default: > - return -1; > - } > - > - return 0; > -} > - > -/* > * Initialises a given port using global settings and with the rx buffer= s > * coming from the mbuf_pool passed as parameter > */ > @@ -284,26 +244,55 @@ port_init(uint8_t port, struct rte_mempool > *mbuf_pool) > { > struct rte_eth_dev_info dev_info; > struct rte_eth_conf port_conf; > - uint16_t rxRings, txRings =3D (uint16_t)rte_lcore_count(); > + uint16_t rxRings, txRings; > const uint16_t rxRingSize =3D RTE_TEST_RX_DESC_DEFAULT, txRingSize =3D > RTE_TEST_TX_DESC_DEFAULT; > int retval; > uint16_t q; > + uint16_t queues_per_pool; > uint32_t max_nb_pools; >=20 > /* The max pool number from dev_info will be used to validate the pool > number specified in cmd line */ > rte_eth_dev_info_get (port, &dev_info); > max_nb_pools =3D (uint32_t)dev_info.max_vmdq_pools; > - retval =3D validate_num_pools(max_nb_pools); > - if (retval < 0) > - return retval; > + if (num_pools !=3D max_nb_pools) { > + printf("num_pools %d !=3D max_nb_pools %d! Currently we only" > + "support configuring all vmdq pools\n", > + num_pools, max_nb_pools); > + return -1; > + } >=20 > retval =3D get_eth_conf(&port_conf, num_pools); > if (retval < 0) > return retval; >=20 > + /* > + * NIC queues are divided into pf queues and vmdq queues. > + */ > + /* There is assumption here all ports have the same configuration */ > + num_pf_queues =3D dev_info.max_rx_queues - > dev_info.vmdq_queue_num; > + queues_per_pool =3D dev_info.vmdq_queue_num / > dev_info.max_vmdq_pools; > + num_vmdq_queues =3D num_pools * queues_per_pool; > + num_queues =3D num_pf_queues + num_vmdq_queues; > + vmdq_queue_base =3D dev_info.vmdq_queue_base; > + vmdq_pool_base =3D dev_info.vmdq_pool_base; > + > + printf("pf queue num: %u, configured vmdq pool num: %u," > + " each vmdq pool has %u queues\n", > + num_pf_queues, num_pools, queues_per_pool); > + printf("vmdq queue base: %d pool base %d\n", > + vmdq_queue_base, vmdq_pool_base); > if (port >=3D rte_eth_dev_count()) return -1; >=20 > - rxRings =3D (uint16_t)num_queues, > + /* > + * Though in this example, we only receive packets from the first queue > + * of each pool and send packets through first rte_lcore_count() tx > + * queues of vmdq queues, all queues including pf queues are setup. > + * This is because VMDQ queues doesn't always start from zero, and the > + * PMD layer doesn't support selectively initialising part of rx/tx > + * queues well. > + */ > + rxRings =3D (uint16_t)dev_info.max_rx_queues; > + txRings =3D (uint16_t)dev_info.max_tx_queues; > retval =3D rte_eth_dev_configure(port, rxRings, txRings, &port_conf); > if (retval !=3D 0) > return retval; > @@ -312,20 +301,26 @@ port_init(uint8_t port, struct rte_mempool > *mbuf_pool) > retval =3D rte_eth_rx_queue_setup(port, q, rxRingSize, > rte_eth_dev_socket_id(port), > &rx_conf_default, > mbuf_pool); > - if (retval < 0) > + if (retval < 0) { > + printf("initialise rx queue %d failed\n", q); > return retval; > + } > } >=20 > for (q =3D 0; q < txRings; q ++) { > retval =3D rte_eth_tx_queue_setup(port, q, txRingSize, > rte_eth_dev_socket_id(port), > &tx_conf_default); > - if (retval < 0) > + if (retval < 0) { > + printf("initialise tx queue %d failed\n", q); > return retval; > + } > } >=20 > retval =3D rte_eth_dev_start(port); > - if (retval < 0) > + if (retval < 0) { > + printf("port %d start failed\n", port); > return retval; > + } >=20 > rte_eth_macaddr_get(port, &vmdq_ports_eth_addr[port]); > printf("Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8 > @@ -338,6 +333,25 @@ port_init(uint8_t port, struct rte_mempool > *mbuf_pool) > vmdq_ports_eth_addr[port].addr_bytes[4], > vmdq_ports_eth_addr[port].addr_bytes[5]); >=20 > + /* Set mac for each pool */ > + for (q =3D 0; q < num_pools; q++) { > + struct ether_addr mac; > + mac =3D pool_addr_template; > + mac.addr_bytes[4] =3D port; > + mac.addr_bytes[5] =3D q; > + printf("Port %u vmdq pool %u set > mac %02x:%02x:%02x:%02x:%02x:%02x\n", > + port, q, > + mac.addr_bytes[0], mac.addr_bytes[1], > + mac.addr_bytes[2], mac.addr_bytes[3], > + mac.addr_bytes[4], mac.addr_bytes[5]); > + retval =3D rte_eth_dev_mac_addr_add(port, &mac, > + q + vmdq_pool_base); > + if (retval) { > + printf("mac addr add failed at pool %d\n", q); > + return retval; > + } > + } > + > return 0; > } >=20 > @@ -353,6 +367,11 @@ vmdq_parse_num_pools(const char *q_arg) > if ((q_arg[0] =3D=3D '\0') || (end =3D=3D NULL) || (*end !=3D '\0')) > return -1; >=20 > + if (num_pools > num_vlans) { > + printf("num_pools %d > num_vlans %d\n", num_pools, > num_vlans); > + return -1; > + } > + > num_pools =3D n; >=20 > return 0; > @@ -481,7 +500,7 @@ lcore_main(__attribute__((__unused__)) void* dummy) > uint16_t core_id =3D 0; > uint16_t startQueue, endQueue; > uint16_t q, i, p; > - const uint16_t remainder =3D (uint16_t)(num_queues % num_cores); > + const uint16_t remainder =3D (uint16_t)(num_vmdq_queues % num_cores); >=20 > for (i =3D 0; i < num_cores; i ++) > if (lcore_ids[i] =3D=3D lcore_id) { > @@ -491,17 +510,27 @@ lcore_main(__attribute__((__unused__)) void* > dummy) >=20 > if (remainder !=3D 0) { > if (core_id < remainder) { > - startQueue =3D (uint16_t)(core_id * > (num_queues/num_cores + 1)); > - endQueue =3D (uint16_t)(startQueue + > (num_queues/num_cores) + 1); > + startQueue =3D (uint16_t)(core_id * > + (num_vmdq_queues / num_cores + 1)); > + endQueue =3D (uint16_t)(startQueue + > + (num_vmdq_queues / num_cores) + 1); > } else { > - startQueue =3D (uint16_t)(core_id * > (num_queues/num_cores) + remainder); > - endQueue =3D (uint16_t)(startQueue + > (num_queues/num_cores)); > + startQueue =3D (uint16_t)(core_id * > + (num_vmdq_queues / num_cores) + > + remainder); > + endQueue =3D (uint16_t)(startQueue + > + (num_vmdq_queues / num_cores)); > } > } else { > - startQueue =3D (uint16_t)(core_id * (num_queues/num_cores)); > - endQueue =3D (uint16_t)(startQueue + (num_queues/num_cores)); > + startQueue =3D (uint16_t)(core_id * > + (num_vmdq_queues / num_cores)); > + endQueue =3D (uint16_t)(startQueue + > + (num_vmdq_queues / num_cores)); > } >=20 > + /* vmdq queue idx doesn't always start from zero.*/ > + startQueue +=3D vmdq_queue_base; > + endQueue +=3D vmdq_queue_base; > printf("core %u(lcore %u) reading queues %i-%i\n", (unsigned)core_id, > (unsigned)lcore_id, startQueue, endQueue - 1); >=20 > @@ -533,8 +562,11 @@ lcore_main(__attribute__((__unused__)) void* dummy) > for (i =3D 0; i < rxCount; i++) > update_mac_address(buf[i], dport); >=20 > - const uint16_t txCount =3D > rte_eth_tx_burst(dport, > - core_id, buf, rxCount); > + const uint16_t txCount =3D rte_eth_tx_burst( > + dport, > + vmdq_queue_base + core_id, > + buf, > + rxCount); >=20 > if (txCount !=3D rxCount) { > for (i =3D txCount; i < rxCount; i++) > -- > 1.8.1.4