* [PATCH] cfgfile: fix comments - style and return value
From: Dmitriy Yakovlev @ 2016-10-19 0:33 UTC (permalink / raw)
To: dev; +Cc: Dmitriy Yakovlev
Fixed style and return values in Doxygen comments.
Signed-off-by: Dmitriy Yakovlev <bombermag@gmail.com>
---
lib/librte_cfgfile/rte_cfgfile.h | 31 ++++++++++++++++++-------------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/lib/librte_cfgfile/rte_cfgfile.h b/lib/librte_cfgfile/rte_cfgfile.h
index e81a5a2..735e022 100644
--- a/lib/librte_cfgfile/rte_cfgfile.h
+++ b/lib/librte_cfgfile/rte_cfgfile.h
@@ -88,7 +88,7 @@ struct rte_cfgfile *rte_cfgfile_load(const char *filename, int flags);
* @param length
* Maximum section name length
* @return
-* 0 on success, error code otherwise
+* Number of sections
*/
int rte_cfgfile_num_sections(struct rte_cfgfile *cfg, const char *sec_name,
size_t length);
@@ -102,13 +102,13 @@ int rte_cfgfile_num_sections(struct rte_cfgfile *cfg, const char *sec_name,
* @param cfg
* Config file
* @param sections
-* Array containing section names after successful invocation. Each elemen
+* Array containing section names after successful invocation. Each element
* of this array should be preallocated by the user with at least
* CFG_NAME_LEN characters.
* @param max_sections
* Maximum number of section names to be stored in sections array
* @return
-* 0 on success, error code otherwise
+* Number of populated sections names
*/
int rte_cfgfile_sections(struct rte_cfgfile *cfg, char *sections[],
int max_sections);
@@ -136,12 +136,13 @@ int rte_cfgfile_has_section(struct rte_cfgfile *cfg, const char *sectionname);
* @param sectionname
* Section name
* @return
-* Number of entries in section
+* Number of entries in section on success, -1 otherwise
*/
int rte_cfgfile_section_num_entries(struct rte_cfgfile *cfg,
const char *sectionname);
-/** Get section entries as key-value pairs
+/**
+* Get section entries as key-value pairs
*
* If multiple sections have the given name this function operates on the
* first one.
@@ -156,14 +157,15 @@ int rte_cfgfile_section_num_entries(struct rte_cfgfile *cfg,
* @param max_entries
* Maximum number of section entries to be stored in entries array
* @return
-* 0 on success, error code otherwise
+* Number of entries populated on success, -1 otherwise
*/
int rte_cfgfile_section_entries(struct rte_cfgfile *cfg,
const char *sectionname,
struct rte_cfgfile_entry *entries,
int max_entries);
-/** Get section entries as key-value pairs
+/**
+* Get section entries as key-value pairs
*
* The index of a section is the same as the index of its name in the
* result of rte_cfgfile_sections. This API can be used when there are
@@ -182,7 +184,7 @@ int rte_cfgfile_section_entries(struct rte_cfgfile *cfg,
* @param max_entries
* Maximum number of section entries to be stored in entries array
* @return
-* Number of entries populated on success, negative error code otherwise
+* Number of entries populated on success, -1 otherwise
*/
int rte_cfgfile_section_entries_by_index(struct rte_cfgfile *cfg,
int index,
@@ -190,7 +192,8 @@ int rte_cfgfile_section_entries_by_index(struct rte_cfgfile *cfg,
struct rte_cfgfile_entry *entries,
int max_entries);
-/** Get value of the named entry in named config file section
+/**
+* Get value of the named entry in named config file section
*
* If multiple sections have the given name this function operates on the
* first one.
@@ -202,13 +205,14 @@ int rte_cfgfile_section_entries_by_index(struct rte_cfgfile *cfg,
* @param entryname
* Entry name
* @return
-* Entry value
+* Entry value on success, NULL otherwise
*/
const char *rte_cfgfile_get_entry(struct rte_cfgfile *cfg,
const char *sectionname,
const char *entryname);
-/** Check if given entry exists in named config file section
+/**
+* Check if given entry exists in named config file section
*
* If multiple sections have the given name this function operates on the
* first one.
@@ -225,12 +229,13 @@ const char *rte_cfgfile_get_entry(struct rte_cfgfile *cfg,
int rte_cfgfile_has_entry(struct rte_cfgfile *cfg, const char *sectionname,
const char *entryname);
-/** Close config file
+/**
+* Close config file
*
* @param cfg
* Config file
* @return
-* 0 on success, error code otherwise
+* 0 on success, -1 otherwise
*/
int rte_cfgfile_close(struct rte_cfgfile *cfg);
--
1.9.1
^ permalink raw reply related
* [opnfv-tech-discuss][apex][ovsnfv]Problem showed up with OVS/DPDK with Cisco VIC adapter
From: Thomas F Herbert @ 2016-10-18 20:35 UTC (permalink / raw)
To: dev@dpdk.org
Cc: Keith Burns, Edward Warnicke, opnfv-tech-discuss@lists.opnfv.org
All:
This is not necessarily related to VPP but rather to OVS/DPDK.
In OPNFV we found the following problem when using UCS NIC.
The UCS fabric seems to set a VLAN tag on untagged packets.
Any thoughts from DPDK and VPP folks would be appreciated.
http://dpdk.org/doc/guides-16.07/nics/enic.html
https://jira.opnfv.org/browse/APEX-333
It is currently deploying DPDK 16.04 and OVS 2.5.90
I could not find a user accessible setting to do this that would work.
The workaround for now we came up with is to set a flow in OVS to strip
the tag.
https://gerrit.opnfv.org/gerrit/#/c/23315/
Another solution is to set the nic to strip the vlan in rte eth code or
write a DPDK "app" to set the nic.
http://dpdk.org/doc/guides-16.07/nics/enic.html
--TFH
--
*Thomas F Herbert*
SDN Group
Office of Technology
*Red Hat*
^ permalink raw reply
* [PATCH] net/ixgbe: fix vlan insert parameter type and its use
From: E. Scott Daniels @ 2016-10-18 19:13 UTC (permalink / raw)
To: helin.zhang, bernard.iremonger; +Cc: dev, az5157, E. Scott Daniels
The final parameter to rte_pmd_ixgbe_set_vf_vlan_insert is uint8_t
and treated as a binary flag when it needs to be a uint16_t
and treated as a VLAN id. The data sheet (sect 8.2.3.27.13) describes
the right most 16 bits as the VLAN id that is to be inserted; the
16.11 code is accepting only a 1 or 0 thus effectively only
allowing the VLAN id 1 to be inserted (0 disables the insertion
setting).
This patch changes the final parm name to represent the data that
is being accepted (vlan_id), changes the type to permit all valid
VLAN ids, and validates the parameter based on the range of 0 to
4095. Corresponding changes to prototype and documentation in the
.h file.
Fixes: 49e248223e9f71 ("net/ixgbe: add API for VF management")
Signed-off-by: E. Scott Daniels <daniels@research.att.com>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 8 ++++----
drivers/net/ixgbe/rte_pmd_ixgbe.h | 9 +++++----
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 4ca5747..316af73 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -4727,7 +4727,7 @@ rte_pmd_ixgbe_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
}
int
-rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf, uint8_t on)
+rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf, uint16_t vlan_id)
{
struct ixgbe_hw *hw;
uint32_t ctrl;
@@ -4742,13 +4742,13 @@ rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf, uint8_t on)
if (vf >= dev_info.max_vfs)
return -EINVAL;
- if (on > 1)
+ if (vlan_id > 4095)
return -EINVAL;
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
ctrl = IXGBE_READ_REG(hw, IXGBE_VMVIR(vf));
- if (on) {
- ctrl = on;
+ if (vlan_id) {
+ ctrl = vlan_id;
ctrl |= IXGBE_VMVIR_VLANA_DEFAULT;
} else {
ctrl = 0;
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe.h b/drivers/net/ixgbe/rte_pmd_ixgbe.h
index 2fdf530..c2fb826 100644
--- a/drivers/net/ixgbe/rte_pmd_ixgbe.h
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe.h
@@ -99,16 +99,17 @@ int rte_pmd_ixgbe_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
* The port identifier of the Ethernet device.
* @param vf
* ID specifying VF.
- * @param on
- * 1 - Enable VF's vlan insert.
- * 0 - Disable VF's vlan insert
+ * @param vlan_id
+ * 0 - Disable VF's vlan insert.
+ * n - Enable; n is inserted as the vlan id.
*
* @return
* - (0) if successful.
* - (-ENODEV) if *port* invalid.
* - (-EINVAL) if bad parameter.
*/
-int rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf, uint8_t on);
+int rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf,
+ uint16_t vlan_id);
/**
* Enable/Disable tx loopback
--
1.9.1
^ permalink raw reply related
* Re: [PATCH] drivers: make driver names consistent
From: Thomas Monjalon @ 2016-10-18 16:46 UTC (permalink / raw)
To: Yuanhan Liu; +Cc: Jan Blunck, De Lara Guarch, Pablo, dev, Mcnamara, John
In-Reply-To: <20161018141837.GN16751@yliu-dev.sh.intel.com>
2016-10-18 22:18, Yuanhan Liu:
> On Tue, Oct 18, 2016 at 03:42:54PM +0200, Thomas Monjalon wrote:
> > 2016-10-18 21:06, Yuanhan Liu:
> > > On Tue, Oct 18, 2016 at 02:50:16PM +0200, Jan Blunck wrote:
> > > > >From my understanding this is a massive API breakage. This forces all
> > > > existing users of the virtual PMDs to change with zero benefit. Even
> > > > if that isn't enough it also makes it impossible to switch between
> > > > releases by recompiling.
> > > >
> > > > Can we please revert these changes and work on some aliasing support
> > > > for the PMDs to fix it long term?
> > >
> > > +1. Aliasing is also something I would suggest before making such renames.
> >
> > It is a brutal change, yes.
> > It was announced in 16.07 release notes though.
>
> Yes, but it still took me a while (by running git bisect) to figure out
> what went wrong: I wasn't aware of such note, that I was thinking maybe
> something is broken.
>
> Later I also got quite few same complains. It may also took them a while
> to know what's happened.
>
> Anyway, my point is, for this kind of change, we should have added the
> alias support firstly.
Yes.
> If that's been done, then the announcement is not
> needed at all?
The announcement would be needed to remove the aliases, later.
> > We can try to make this change more progressive by keeping old names
> > as aliases for some time.
> > Is there a volunteer to work on vdev names aliases,
> > with the target of integrating them in RC2 or RC3?
^ permalink raw reply
* Re: [PATCH] drivers: make driver names consistent
From: Thomas Monjalon @ 2016-10-18 16:45 UTC (permalink / raw)
To: Jan Blunck; +Cc: Yuanhan Liu, De Lara Guarch, Pablo, dev, Mcnamara, John
In-Reply-To: <CALe+Z00mtGMMWBveSwma2hjQgGpuotUOH+fz0nEKpxG4PDiY2w@mail.gmail.com>
2016-10-18 17:26, Jan Blunck:
> On Tue, Oct 18, 2016 at 3:42 PM, Thomas Monjalon
> <thomas.monjalon@6wind.com> wrote:
> > 2016-10-18 21:06, Yuanhan Liu:
> >> On Tue, Oct 18, 2016 at 02:50:16PM +0200, Jan Blunck wrote:
> >> > >From my understanding this is a massive API breakage. This forces all
> >> > existing users of the virtual PMDs to change with zero benefit. Even
> >> > if that isn't enough it also makes it impossible to switch between
> >> > releases by recompiling.
> >> >
> >> > Can we please revert these changes and work on some aliasing support
> >> > for the PMDs to fix it long term?
> >>
> >> +1. Aliasing is also something I would suggest before making such renames.
> >
> > It is a brutal change, yes.
> > It was announced in 16.07 release notes though.
> >
>
> "But the plans were on display ..." (HHGTTG)
>
> > We can try to make this change more progressive by keeping old names
> > as aliases for some time.
> > Is there a volunteer to work on vdev names aliases,
> > with the target of integrating them in RC2 or RC3?
> >
>
> I'll give it a try ...
Thanks Jan
^ permalink raw reply
* Re: Project Governance and Linux Foundation
From: Jerin Jacob @ 2016-10-18 16:26 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: Dave Neary, O'Driscoll, Tim, dev, users
In-Reply-To: <1547412.qzivax5BEW@xps13>
On Tue, Oct 18, 2016 at 03:27:27PM +0200, Thomas Monjalon wrote:
> 2016-10-18 17:04, Jerin Jacob:
> > On Mon, Oct 17, 2016 at 05:23:42PM -0400, Dave Neary wrote:
> > > > I still hear concerns on this, and based on discussions with others who put their names to the post below, they do too. I think it's a perception that we need to address.
> > >
> > > I would say that there is still a perception issue, for companies who
> > > look at the active developers, the owners of the project's resources
> > > (infra, domain name), and who have heard anecdotal evidence of issues in
> > > the past. I think the project has made a lot of progress since I have
> > > been following it, and I do not believe there are any major issues with
> > > the independence of the project. However, there are still concerned
> > > parties on this front, and the concerns can be easily addressed by a
> > > move to the LF.
> >
> > +1
>
> How can we solve issues if you don't give more details than
> "hear concerns" or "heard anecdotal evidence of issues"?
Honestly, I don't see any issue in the current DPDK project execution.
The concern was more towards the fact that multi-vendor infrastructure project
like DPDK owned and controlled by the single company.
We believe, Moving to LF will fix that issue/perception and it will
enable more users to use/consume/invest DPDK in their products.
Having said that, Does anyone see any issue in moving to LF?
If yes, Then we should enumerate the issues and discuss further.
Jerin
^ permalink raw reply
* Re: [PATCH v2 2/2] drivers/i40e: fix the hash filter invalid calculation in X722
From: Ferruh Yigit @ 2016-10-18 16:25 UTC (permalink / raw)
To: Jeff Guo, helin.zhang, jingjing.wu; +Cc: dev
In-Reply-To: <1476582005-110811-2-git-send-email-jia.guo@intel.com>
On 10/16/2016 2:40 AM, Jeff Guo wrote:
> As X722 extracts IPv4 header to Field Vector different with XL710/X710,
> need to corresponding to modify the fields of IPv4 header in input set
> to map different default Field Vector Table of different NICs.
>
> Signed-off-by: Jeff Guo <jia.guo@intel.com>
>
> ---
> v2:
> fix compile error when x722 macro is not defined and simplify
> the code to avoid duplication.
> ---
> drivers/net/i40e/i40e_ethdev.c | 73 ++++++++++++++++++++++++++++++++++--------
> 1 file changed, 60 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 920fd6d..7895c11 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -211,6 +211,16 @@
> #define I40E_REG_INSET_L3_SRC_IP4 0x0001800000000000ULL
> /* Destination IPv4 address */
> #define I40E_REG_INSET_L3_DST_IP4 0x0000001800000000ULL
> +#ifdef X722_SUPPORT
If agreed on removing #ifdef X722_SUPPORT, please apply this into this
patch too.
> +/* Source IPv4 address for X722 */
> +#define I40E_X722_REG_INSET_L3_SRC_IP4 0x0006000000000000ULL
> +/* Destination IPv4 address for X722 */
> +#define I40E_X722_REG_INSET_L3_DST_IP4 0x0000060000000000ULL
> +/* IPv4 Protocol */
> +#define I40E_X722_REG_INSET_L3_IP4_PROTO 0x0010000000000000ULL
> +/* IPv4 Time to Live */
> +#define I40E_X722_REG_INSET_L3_IP4_TTL 0x0010000000000000ULL
> +#endif
> /* IPv4 Type of Service (TOS) */
> #define I40E_REG_INSET_L3_IP4_TOS 0x0040000000000000ULL
> /* IPv4 Protocol */
> @@ -7581,7 +7591,7 @@ i40e_parse_input_set(uint64_t *inset,
> * and vice versa
> */
> static uint64_t
> -i40e_translate_input_set_reg(uint64_t input)
> +i40e_translate_input_set_reg(enum i40e_mac_type type, uint64_t input)
> {
> uint64_t val = 0;
> uint16_t i;
> @@ -7589,17 +7599,13 @@ i40e_translate_input_set_reg(uint64_t input)
> static const struct {
> uint64_t inset;
> uint64_t inset_reg;
> - } inset_map[] = {
> + } inset_map_common[] = {
> {I40E_INSET_DMAC, I40E_REG_INSET_L2_DMAC},
> {I40E_INSET_SMAC, I40E_REG_INSET_L2_SMAC},
> {I40E_INSET_VLAN_OUTER, I40E_REG_INSET_L2_OUTER_VLAN},
> {I40E_INSET_VLAN_INNER, I40E_REG_INSET_L2_INNER_VLAN},
> {I40E_INSET_LAST_ETHER_TYPE, I40E_REG_INSET_LAST_ETHER_TYPE},
> - {I40E_INSET_IPV4_SRC, I40E_REG_INSET_L3_SRC_IP4},
> - {I40E_INSET_IPV4_DST, I40E_REG_INSET_L3_DST_IP4},
> {I40E_INSET_IPV4_TOS, I40E_REG_INSET_L3_IP4_TOS},
> - {I40E_INSET_IPV4_PROTO, I40E_REG_INSET_L3_IP4_PROTO},
> - {I40E_INSET_IPV4_TTL, I40E_REG_INSET_L3_IP4_TTL},
> {I40E_INSET_IPV6_SRC, I40E_REG_INSET_L3_SRC_IP6},
> {I40E_INSET_IPV6_DST, I40E_REG_INSET_L3_DST_IP6},
> {I40E_INSET_IPV6_TC, I40E_REG_INSET_L3_IP6_TC},
> @@ -7627,16 +7633,56 @@ i40e_translate_input_set_reg(uint64_t input)
> {I40E_INSET_FLEX_PAYLOAD_W7, I40E_REG_INSET_FLEX_PAYLOAD_WORD7},
> {I40E_INSET_FLEX_PAYLOAD_W8, I40E_REG_INSET_FLEX_PAYLOAD_WORD8},
> };
> +#ifdef X722_SUPPORT
> +
> + /* some different registers map in x722*/
> + static const struct {
> + uint64_t inset;
> + uint64_t inset_reg;
> + } inset_map_diff_x722[] = {
Can you please extract struct declaration, and re-use that to create
instances.
> + {I40E_INSET_IPV4_SRC, I40E_X722_REG_INSET_L3_SRC_IP4},
> + {I40E_INSET_IPV4_DST, I40E_X722_REG_INSET_L3_DST_IP4},
> + {I40E_INSET_IPV4_PROTO, I40E_X722_REG_INSET_L3_IP4_PROTO},
> + {I40E_INSET_IPV4_TTL, I40E_X722_REG_INSET_L3_IP4_TTL},
> + };
> +#endif
> +
> + static const struct {
> + uint64_t inset;
> + uint64_t inset_reg;
> + } inset_map_diff_not_x722[] = {
> + {I40E_INSET_IPV4_SRC, I40E_REG_INSET_L3_SRC_IP4},
> + {I40E_INSET_IPV4_DST, I40E_REG_INSET_L3_DST_IP4},
> + {I40E_INSET_IPV4_PROTO, I40E_REG_INSET_L3_IP4_PROTO},
> + {I40E_INSET_IPV4_TTL, I40E_REG_INSET_L3_IP4_TTL},
> + };
>
> if (input == 0)
> return val;
>
> /* Translate input set to register aware inset */
> - for (i = 0; i < RTE_DIM(inset_map); i++) {
> - if (input & inset_map[i].inset)
> - val |= inset_map[i].inset_reg;
> +#ifdef X722_SUPPORT
> + if (type == I40E_MAC_X722) {
> + for (i = 0; i < RTE_DIM(inset_map_diff_x722); i++) {
> + if (input & inset_map_diff_x722[i].inset)
> + val |= inset_map_diff_x722[i].inset_reg;
> + }
> + } else {
> + for (i = 0; i < RTE_DIM(inset_map_diff_not_x722); i++) {
> + if (input & inset_map_diff_not_x722[i].inset)
> + val |= inset_map_diff_not_x722[i].inset_reg;
> + }
> + }
> +#else
Since #ifdef removed, #else part should be gone.
> + for (i = 0; i < RTE_DIM(inset_map_diff_not_x722); i++) {
> + if (input & inset_map_diff_not_x722[i].inset)
> + val |= inset_map_diff_not_x722[i].inset_reg;
> + }
> +#endif
> + for (i = 0; i < RTE_DIM(inset_map_common); i++) {
> + if (input & inset_map_common[i].inset)
> + val |= inset_map_common[i].inset_reg;
> }
> -
> return val;
> }
>
> @@ -7719,7 +7765,8 @@ i40e_filter_input_set_init(struct i40e_pf *pf)
> I40E_INSET_MASK_NUM_REG);
> if (num < 0)
> return;
> - inset_reg = i40e_translate_input_set_reg(input_set);
> + inset_reg = i40e_translate_input_set_reg(hw->mac.type,
> + input_set);
>
> i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
> (uint32_t)(inset_reg & UINT32_MAX));
> @@ -7810,7 +7857,7 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
> if (num < 0)
> return -EINVAL;
>
> - inset_reg |= i40e_translate_input_set_reg(input_set);
> + inset_reg |= i40e_translate_input_set_reg(hw->mac.type, input_set);
>
> i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
> (uint32_t)(inset_reg & UINT32_MAX));
> @@ -7888,7 +7935,7 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
> if (num < 0)
> return -EINVAL;
>
> - inset_reg |= i40e_translate_input_set_reg(input_set);
> + inset_reg |= i40e_translate_input_set_reg(hw->mac.type, input_set);
>
> i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
> (uint32_t)(inset_reg & UINT32_MAX));
>
^ permalink raw reply
* Re: [PATCH v2 1/2] drivers/i40e: fix X722 macro absence result in compile
From: Ferruh Yigit @ 2016-10-18 16:22 UTC (permalink / raw)
To: Ananyev, Konstantin, Guo, Jia, Zhang, Helin, Wu, Jingjing; +Cc: dev@dpdk.org
In-Reply-To: <2601191342CEEE43887BDE71AB9772583F0C23DD@irsmsx105.ger.corp.intel.com>
On 10/17/2016 10:54 AM, Ananyev, Konstantin wrote:
> Hi Jeff,
>
>>
>> hi, Konstantin
>> Thanks your constructive suggestion. I don't think your question is
>> silly and we also think about the code style simply and effective, but
>> may be i would interpret the reason why we do that.
>>
>> 1) Sure, user definitely can choose to define the macro or not when
>> building dpdk i40e PMD, but i don't think it is
>> necessary to invoke a ret_config option to let up layer user freedom use
>> it, because only the older version i40e driver does not support X722,
>> the newer version i40e driver will always support X722, so the macro
>> will be default hard code in the makefile. and we will use mac.type to
>> distinguish the difference register configure in run time. So we may
>> consider the macro just like a flag that highlight the difference of the
>> shared code between X710 and X722, that would benify the X710/X722 pmd
>> development but hardly no use to exposure to the up layer user.
>>
>> 2) i think the answer also could find from above. But i think if we
>> develop go to a certain stage in the future, mute the macro or use
>> script to remove them like the way from hw driver, for support all
>> device types maybe not a bad idea, right?
>
> Sorry, but I still didn't get it.
> If i40e driver will always support X722 then why do we need that macro at all?
> Why just not to remove it completely then?
> Same about run-time vs build-time choice:
> If let say i40e_get_rss_key() has to behave in a different way, why not to create
> i40e_get_rss_key_x722() and use it when hw mactype is x7222?
> Or at least inside i40e_get_rss_key() do something like:
> if (hw->mac.type == I40E_MAC_X722) {...} else {...}
> ?
> Why instead you have to pollute whole i40e code with all these #ifdef x7222/#else ...?
> Obviously that looks pretty ugly and hard to maintain.
It is not possible to remove "#ifdef x7222" from shared code, but what
about removing it from DPDK piece of the code, and code as it is always
defined?
If this is OK, this patch is not more required.
And the removing #ifdef work can be done in another patch later.
> Konstantin
^ permalink raw reply
* Re: [PATCH 1/3] mbuf: embedding timestamp into the packet
From: Olivier Matz @ 2016-10-18 15:43 UTC (permalink / raw)
To: dev
In-Reply-To: <1476369308-17021-2-git-send-email-olegk@mellanox.com>
On 10/13/2016 04:35 PM, Oleg Kuporosov wrote:
> The hard requirement of financial services industry is accurate
> timestamping aligned with the packet itself. This patch is to satisfy
> this requirement:
>
> - include uint64_t timestamp field into rte_mbuf with minimal impact to
> throughput/latency. Keep it just simple uint64_t in ns (more than 580
> years) would be enough for immediate needs while using full
> struct timespec with twice bigger size would have much stronger
> performance impact as missed cacheline0.
>
> - it is possible as there is 6-bytes gap in 1st cacheline (fast path)
> and moving uint16_t vlan_tci_outer field to 2nd cacheline.
>
> - such move will only impact for pretty rare usable VLAN RX stripping
> mode for outer TCI (it used only for one NIC i40e from the whole set and
> allows to keep minimal performance impact for RX/TX timestamps.
This argument is difficult to accept. One can say you are adding
a field for a pretty rare case used by only one NIC :)
Honestly, I'm not able to judge whether timestamp is more important than
vlan_tci_outer. As room is tight in the first cache line, your patch
submission is the occasion to raise the question: how to decide what
should be in the first part of the mbuf? There are also some other
candidates for moving: m->seqn is only used in librte_reorder and it
is not set in the RX part of a driver.
About the timestamp, it would be valuable to have other opinions,
not only about the placement of the field in the structure, but also
to check that this API is also usable for other NICs.
Have you measured the impact of having the timestamp in the second part
of the mbuf?
Changing the mbuf structure should happen as rarely as possible, and we
have to make sure we take the correct decisions. I think we will
discuss this at dpdk userland 2016.
Apart from that, I wonder if an ol_flag should be added to tell that
the timestamp field is valid in the mbuf.
Regards,
Olivier
^ permalink raw reply
* [PATCH 2/2] vhost: Add indirect desc support to the Rx no-mergeable path
From: Maxime Coquelin @ 2016-10-18 15:35 UTC (permalink / raw)
To: yuanhan.liu, dev, mst; +Cc: zhihong.wang, ciara.loftus, Maxime Coquelin
In-Reply-To: <1476804939-8675-1-git-send-email-maxime.coquelin@redhat.com>
Linux virtio-net kernel driver uses indirect descriptors when
mergeable buffers are not used.
This patch adds its support, fixing the use of indirect
descriptors with these guests.
Cc: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Cc: Ciara Loftus <ciara.loftus@intel.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
lib/librte_vhost/virtio_net.c | 30 +++++++++++++++++++++++-------
1 file changed, 23 insertions(+), 7 deletions(-)
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index 0941186..8365894 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -186,8 +186,8 @@ copy_virtio_net_hdr(struct virtio_net *dev, uint64_t desc_addr,
}
static inline int __attribute__((always_inline))
-copy_mbuf_to_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
- struct rte_mbuf *m, uint16_t desc_idx)
+copy_mbuf_to_desc(struct virtio_net *dev, struct vring_desc *descs,
+ struct rte_mbuf *m, uint16_t desc_idx, uint32_t size)
{
uint32_t desc_avail, desc_offset;
uint32_t mbuf_avail, mbuf_offset;
@@ -196,7 +196,7 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
uint64_t desc_addr;
struct virtio_net_hdr_mrg_rxbuf virtio_hdr = {{0, 0, 0, 0, 0, 0}, 0};
- desc = &vq->desc[desc_idx];
+ desc = &descs[desc_idx];
desc_addr = gpa_to_vva(dev, desc->addr);
/*
* Checking of 'desc_addr' placed outside of 'unlikely' macro to avoid
@@ -233,10 +233,10 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
/* Room in vring buffer is not enough */
return -1;
}
- if (unlikely(desc->next >= vq->size))
+ if (unlikely(desc->next >= size))
return -1;
- desc = &vq->desc[desc->next];
+ desc = &descs[desc->next];
desc_addr = gpa_to_vva(dev, desc->addr);
if (unlikely(!desc_addr))
return -1;
@@ -276,8 +276,9 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
struct vhost_virtqueue *vq;
uint16_t avail_idx, free_entries, start_idx;
uint16_t desc_indexes[MAX_PKT_BURST];
+ struct vring_desc *descs;
uint16_t used_idx;
- uint32_t i;
+ uint32_t i, sz;
LOG_DEBUG(VHOST_DATA, "(%d) %s\n", dev->vid, __func__);
if (unlikely(!is_valid_virt_queue_idx(queue_id, 0, dev->virt_qp_nb))) {
@@ -319,7 +320,22 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
uint16_t desc_idx = desc_indexes[i];
int err;
- err = copy_mbuf_to_desc(dev, vq, pkts[i], desc_idx);
+ if (vq->desc[desc_idx].flags & VRING_DESC_F_INDIRECT) {
+ descs = (struct vring_desc *)(uintptr_t)gpa_to_vva(dev,
+ vq->desc[desc_idx].addr);
+ if (unlikely(!descs)) {
+ count = i;
+ break;
+ }
+
+ desc_idx = 0;
+ sz = vq->desc[desc_idx].len / sizeof(*descs);
+ } else {
+ descs = vq->desc;
+ sz = vq->size;
+ }
+
+ err = copy_mbuf_to_desc(dev, descs, pkts[i], desc_idx, sz);
if (unlikely(err)) {
used_idx = (start_idx + i) & (vq->size - 1);
vq->used->ring[used_idx].len = dev->vhost_hlen;
--
2.7.4
^ permalink raw reply related
* [PATCH 1/2] vhost: Add indirect desc support to Rx mergeable path
From: Maxime Coquelin @ 2016-10-18 15:35 UTC (permalink / raw)
To: yuanhan.liu, dev, mst; +Cc: zhihong.wang, ciara.loftus, Maxime Coquelin
In-Reply-To: <1476804939-8675-1-git-send-email-maxime.coquelin@redhat.com>
Windows virtio-net driver uses indirect descriptors with
mergeable buffers.
This patch adds its support, fixing the use of indirect
descriptors with these guests.
Cc: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Cc: Zhihong Wang <zhihong.wang@intel.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
lib/librte_vhost/virtio_net.c | 43 ++++++++++++++++++++++++++++---------------
1 file changed, 28 insertions(+), 15 deletions(-)
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index b784dba..0941186 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -351,29 +351,41 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
}
static inline int __attribute__((always_inline))
-fill_vec_buf(struct vhost_virtqueue *vq, uint32_t avail_idx,
- uint32_t *vec_idx, struct buf_vector *buf_vec,
- uint16_t *desc_chain_head, uint16_t *desc_chain_len)
+fill_vec_buf(struct virtio_net *dev, struct vhost_virtqueue *vq,
+ uint32_t avail_idx, uint32_t *vec_idx,
+ struct buf_vector *buf_vec, uint16_t *desc_chain_head,
+ uint16_t *desc_chain_len)
{
uint16_t idx = vq->avail->ring[avail_idx & (vq->size - 1)];
uint32_t vec_id = *vec_idx;
uint32_t len = 0;
+ struct vring_desc *descs = vq->desc;
*desc_chain_head = idx;
+
+ if (vq->desc[idx].flags & VRING_DESC_F_INDIRECT) {
+ descs = (struct vring_desc *)(uintptr_t)
+ gpa_to_vva(dev, vq->desc[idx].addr);
+ if (unlikely(!descs))
+ return -1;
+
+ idx = 0;
+ }
+
while (1) {
if (unlikely(vec_id >= BUF_VECTOR_MAX || idx >= vq->size))
return -1;
- len += vq->desc[idx].len;
- buf_vec[vec_id].buf_addr = vq->desc[idx].addr;
- buf_vec[vec_id].buf_len = vq->desc[idx].len;
+ len += descs[idx].len;
+ buf_vec[vec_id].buf_addr = descs[idx].addr;
+ buf_vec[vec_id].buf_len = descs[idx].len;
buf_vec[vec_id].desc_idx = idx;
vec_id++;
- if ((vq->desc[idx].flags & VRING_DESC_F_NEXT) == 0)
+ if ((descs[idx].flags & VRING_DESC_F_NEXT) == 0)
break;
- idx = vq->desc[idx].next;
+ idx = descs[idx].next;
}
*desc_chain_len = len;
@@ -386,9 +398,9 @@ fill_vec_buf(struct vhost_virtqueue *vq, uint32_t avail_idx,
* Returns -1 on fail, 0 on success
*/
static inline int
-reserve_avail_buf_mergeable(struct vhost_virtqueue *vq, uint32_t size,
- struct buf_vector *buf_vec, uint16_t *num_buffers,
- uint16_t avail_head)
+reserve_avail_buf_mergeable(struct virtio_net *dev, struct vhost_virtqueue *vq,
+ uint32_t size, struct buf_vector *buf_vec,
+ uint16_t *num_buffers, uint16_t avail_head)
{
uint16_t cur_idx;
uint32_t vec_idx = 0;
@@ -404,8 +416,8 @@ reserve_avail_buf_mergeable(struct vhost_virtqueue *vq, uint32_t size,
if (unlikely(cur_idx == avail_head))
return -1;
- if (unlikely(fill_vec_buf(vq, cur_idx, &vec_idx, buf_vec,
- &head_idx, &len) < 0))
+ if (unlikely(fill_vec_buf(dev, vq, cur_idx, &vec_idx, buf_vec,
+ &head_idx, &len) < 0))
return -1;
len = RTE_MIN(len, size);
update_shadow_used_ring(vq, head_idx, len);
@@ -546,8 +558,9 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
for (pkt_idx = 0; pkt_idx < count; pkt_idx++) {
uint32_t pkt_len = pkts[pkt_idx]->pkt_len + dev->vhost_hlen;
- if (unlikely(reserve_avail_buf_mergeable(vq, pkt_len, buf_vec,
- &num_buffers, avail_head) < 0)) {
+ if (unlikely(reserve_avail_buf_mergeable(dev, vq,
+ pkt_len, buf_vec, &num_buffers,
+ avail_head) < 0)) {
LOG_DEBUG(VHOST_DATA,
"(%d) failed to get enough desc from vring\n",
dev->vid);
--
2.7.4
^ permalink raw reply related
* [PATCH 0/2] vhost: Add support to indirect descriptors on Rx path
From: Maxime Coquelin @ 2016-10-18 15:35 UTC (permalink / raw)
To: yuanhan.liu, dev, mst; +Cc: zhihong.wang, ciara.loftus, Maxime Coquelin
Indirect descriptor feature has been enabled in v16.11-rc1, but only TX path
was implemented.
However, some configurations expect it is supported for the Rx path:
- Windows guests with and without mergeable buffers enabled
- Linux guests with Kernel drivr with mergeable buffers disabled
This series add the support of indirect descs for the Rx path, and has been
tested with following configurations:
- Windows guest with indirect ON, mergeeable ON/OFF
- Linux guest with Kernel driver with indirect ON/OFF, mergeable ON/OFF
- Linux guest with Virtio PMD with mergeable ON/OFF
The performance degradation measured with/without this series with Virtio PMD
is around 1% (which doesn't use indirect descs for the Rx path).
The series is based on top of "vhost: optimize mergeable Rx path" v7.
Maxime Coquelin (2):
vhost: Add indirect desc support to Rx mergeable path
vhost: Add indirect desc support to the Rx no-mergeable path
lib/librte_vhost/virtio_net.c | 73 ++++++++++++++++++++++++++++++-------------
1 file changed, 51 insertions(+), 22 deletions(-)
--
2.7.4
^ permalink raw reply
* Re: [PATCH] drivers: make driver names consistent
From: Jan Blunck @ 2016-10-18 15:26 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: Yuanhan Liu, De Lara Guarch, Pablo, dev, Mcnamara, John
In-Reply-To: <10195497.iZAVVgVpbs@xps13>
On Tue, Oct 18, 2016 at 3:42 PM, Thomas Monjalon
<thomas.monjalon@6wind.com> wrote:
> 2016-10-18 21:06, Yuanhan Liu:
>> On Tue, Oct 18, 2016 at 02:50:16PM +0200, Jan Blunck wrote:
>> > >From my understanding this is a massive API breakage. This forces all
>> > existing users of the virtual PMDs to change with zero benefit. Even
>> > if that isn't enough it also makes it impossible to switch between
>> > releases by recompiling.
>> >
>> > Can we please revert these changes and work on some aliasing support
>> > for the PMDs to fix it long term?
>>
>> +1. Aliasing is also something I would suggest before making such renames.
>
> It is a brutal change, yes.
> It was announced in 16.07 release notes though.
>
"But the plans were on display ..." (HHGTTG)
> We can try to make this change more progressive by keeping old names
> as aliases for some time.
> Is there a volunteer to work on vdev names aliases,
> with the target of integrating them in RC2 or RC3?
>
I'll give it a try ...
^ permalink raw reply
* Re: [PATCH] Revert "bonding: use existing enslaved device queues"
From: Jan Blunck @ 2016-10-18 15:19 UTC (permalink / raw)
To: Ilya Maximets
Cc: dev, Declan Doherty, Heetae Ahn, Yuanhan Liu, Eric Kinzie,
Bernard Iremonger, stable
In-Reply-To: <ec342fd4-5151-b0cb-a5cb-6d67eda760f3@samsung.com>
On Tue, Oct 18, 2016 at 2:49 PM, Ilya Maximets <i.maximets@samsung.com> wrote:
> On 18.10.2016 15:28, Jan Blunck wrote:
>> If the application already configured queues the PMD should not
>> silently claim ownership and reset them.
>>
>> What exactly is the problem when changing MTU? This works fine from
>> what I can tell.
>
> Following scenario leads to APP PANIC:
>
> 1. mempool_1 = rte_mempool_create()
> 2. rte_eth_rx_queue_setup(bond0, ..., mempool_1);
> 3. rte_eth_dev_start(bond0);
> 4. mempool_2 = rte_mempool_create();
> 5. rte_eth_dev_stop(bond0);
> 6. rte_eth_rx_queue_setup(bond0, ..., mempool_2);
> 7. rte_eth_dev_start(bond0);
> * RX queues still use 'mempool_1' because reconfiguration doesn't affect them. *
> 8. rte_mempool_free(mempool_1);
> 9. On any rx operation we'll get PANIC because of using freed 'mempool_1':
> PANIC in rte_mempool_get_ops():
> assert "(ops_index >= 0) && (ops_index < RTE_MEMPOOL_MAX_OPS_IDX)" failed
>
> You may just start OVS 2.6 with DPDK bonding device and attempt to change MTU via 'mtu_request'.
> Bug is easily reproducible.
>
I see. I'm not 100% that this is expected to work without leaking the
driver's queues though. The driver is allowed to do allocations in
its rx_queue_setup() function that are being freed via
rx_queue_release() later. But rx_queue_release() is only called if you
reconfigure the
device with 0 queues. From what I understand there is no other way to
reconfigure a device to use another mempool.
But ... even that wouldn't work with the bonding driver right now: the
bonding master only configures the slaves during startup. I can put
that on my todo list.
Coming back to your original problem: changing the MTU for the bond
does work through rte_eth_dev_set_mtu() for slaves supporting that. In
any other case you could (re-)configure rxmode.max_rx_pkt_len (and
jumbo_frame / enable_scatter accordingly). This does work without a
call to rte_eth_rx_queue_setup().
Hope this helps,
Jan
> Best regards, Ilya Maximets.
>
>>
>> On Wed, Sep 7, 2016 at 2:28 PM, Ilya Maximets <i.maximets@samsung.com> wrote:
>>> This reverts commit 5b7bb2bda5519b7800f814df64d4e015282140e5.
>>>
>>> It is necessary to reconfigure all queues every time because configuration
>>> can be changed.
>>>
>>> For example, if we're reconfiguring bonding device with new memory pool,
>>> already configured queues will still use the old one. And if the old
>>> mempool be freed, application likely will panic in attempt to use
>>> freed mempool.
>>>
>>> This happens when we use the bonding device with OVS 2.6 while MTU
>>> reconfiguration:
>>>
>>> PANIC in rte_mempool_get_ops():
>>> assert "(ops_index >= 0) && (ops_index < RTE_MEMPOOL_MAX_OPS_IDX)" failed
>>>
>>> Cc: <stable@dpdk.org>
>>> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
>>> ---
>>> drivers/net/bonding/rte_eth_bond_pmd.c | 10 ++--------
>>> 1 file changed, 2 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
>>> index b20a272..eb5b6d1 100644
>>> --- a/drivers/net/bonding/rte_eth_bond_pmd.c
>>> +++ b/drivers/net/bonding/rte_eth_bond_pmd.c
>>> @@ -1305,8 +1305,6 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev,
>>> struct bond_rx_queue *bd_rx_q;
>>> struct bond_tx_queue *bd_tx_q;
>>>
>>> - uint16_t old_nb_tx_queues = slave_eth_dev->data->nb_tx_queues;
>>> - uint16_t old_nb_rx_queues = slave_eth_dev->data->nb_rx_queues;
>>> int errval;
>>> uint16_t q_id;
>>>
>>> @@ -1347,9 +1345,7 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev,
>>> }
>>>
>>> /* Setup Rx Queues */
>>> - /* Use existing queues, if any */
>>> - for (q_id = old_nb_rx_queues;
>>> - q_id < bonded_eth_dev->data->nb_rx_queues; q_id++) {
>>> + for (q_id = 0; q_id < bonded_eth_dev->data->nb_rx_queues; q_id++) {
>>> bd_rx_q = (struct bond_rx_queue *)bonded_eth_dev->data->rx_queues[q_id];
>>>
>>> errval = rte_eth_rx_queue_setup(slave_eth_dev->data->port_id, q_id,
>>> @@ -1365,9 +1361,7 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev,
>>> }
>>>
>>> /* Setup Tx Queues */
>>> - /* Use existing queues, if any */
>>> - for (q_id = old_nb_tx_queues;
>>> - q_id < bonded_eth_dev->data->nb_tx_queues; q_id++) {
>>> + for (q_id = 0; q_id < bonded_eth_dev->data->nb_tx_queues; q_id++) {
>>> bd_tx_q = (struct bond_tx_queue *)bonded_eth_dev->data->tx_queues[q_id];
>>>
>>> errval = rte_eth_tx_queue_setup(slave_eth_dev->data->port_id, q_id,
>>> --
>>> 2.7.4
>>>
>>
>>
>>
^ permalink raw reply
* Re: [PATCH v6 1/6] ethdev: add Tx preparation
From: Olivier Matz @ 2016-10-18 14:57 UTC (permalink / raw)
To: Tomasz Kulasek, dev; +Cc: konstantin.ananyev, thomas.monjalon
In-Reply-To: <1476457519-6840-2-git-send-email-tomaszx.kulasek@intel.com>
Hi Tomasz,
I think the principle of tx_prep() is good, it may for instance help to
remove the function virtio_tso_fix_cksum() from the virtio, and maybe
even change the mbuf TSO/cksum API.
I have some questions/comments below, I'm sorry it comes very late.
On 10/14/2016 05:05 PM, Tomasz Kulasek wrote:
> Added API for `rte_eth_tx_prep`
>
> uint16_t rte_eth_tx_prep(uint8_t port_id, uint16_t queue_id,
> struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
>
> Added fields to the `struct rte_eth_desc_lim`:
>
> uint16_t nb_seg_max;
> /**< Max number of segments per whole packet. */
>
> uint16_t nb_mtu_seg_max;
> /**< Max number of segments per one MTU */
Not sure I understand the second one. Is this is case of TSO?
Is it a usual limitation in different network hardware?
Can this info be retrieved/used by the application?
>
> Created `rte_pkt.h` header with common used functions:
>
> int rte_validate_tx_offload(struct rte_mbuf *m)
> to validate general requirements for tx offload in packet such a
> flag completness. In current implementation this function is called
> optionaly when RTE_LIBRTE_ETHDEV_DEBUG is enabled.
>
> int rte_phdr_cksum_fix(struct rte_mbuf *m)
> to fix pseudo header checksum for TSO and non-TSO tcp/udp packets
> before hardware tx checksum offload.
> - for non-TSO tcp/udp packets full pseudo-header checksum is
> counted and set.
> - for TSO the IP payload length is not included.
Why not in rte_net.h?
> [...]
>
> @@ -2816,6 +2825,82 @@ rte_eth_tx_burst(uint8_t port_id, uint16_t queue_id,
> return (*dev->tx_pkt_burst)(dev->data->tx_queues[queue_id], tx_pkts, nb_pkts);
> }
>
> +/**
> + * Process a burst of output packets on a transmit queue of an Ethernet device.
> + *
> + * The rte_eth_tx_prep() function is invoked to prepare output packets to be
> + * transmitted on the output queue *queue_id* of the Ethernet device designated
> + * by its *port_id*.
> + * The *nb_pkts* parameter is the number of packets to be prepared which are
> + * supplied in the *tx_pkts* array of *rte_mbuf* structures, each of them
> + * allocated from a pool created with rte_pktmbuf_pool_create().
> + * For each packet to send, the rte_eth_tx_prep() function performs
> + * the following operations:
> + *
> + * - Check if packet meets devices requirements for tx offloads.
Do you mean hardware requirements?
Can the application be aware of these requirements? I mean capability
flags, or something in dev_infos?
Maybe the comment could be more precise?
> + * - Check limitations about number of segments.
> + *
> + * - Check additional requirements when debug is enabled.
What kind of additional requirements?
> + *
> + * - Update and/or reset required checksums when tx offload is set for packet.
> + *
By reading this, I think it may not be clear for the user about what
should be set in the mbuf. In mbuf API, it is said:
* TCP segmentation offload. To enable this offload feature for a
* packet to be transmitted on hardware supporting TSO:
* - set the PKT_TX_TCP_SEG flag in mbuf->ol_flags (this flag implies
* PKT_TX_TCP_CKSUM)
* - set the flag PKT_TX_IPV4 or PKT_TX_IPV6
* - if it's IPv4, set the PKT_TX_IP_CKSUM flag and write the IP checksum
* to 0 in the packet
* - fill the mbuf offload information: l2_len, l3_len, l4_len, tso_segsz
* - calculate the pseudo header checksum without taking ip_len in account,
* and set it in the TCP header. Refer to rte_ipv4_phdr_cksum() and
* rte_ipv6_phdr_cksum() that can be used as helpers.
If I understand well, using tx_prep(), the user will have to do the
same except writing the IP checksum to 0, and without setting the
TCP pseudo header checksum, right?
> + * The rte_eth_tx_prep() function returns the number of packets ready to be
> + * sent. A return value equal to *nb_pkts* means that all packets are valid and
> + * ready to be sent.
> + *
> + * @param port_id
> + * The port identifier of the Ethernet device.
> + * @param queue_id
> + * The index of the transmit queue through which output packets must be
> + * sent.
> + * The value must be in the range [0, nb_tx_queue - 1] previously supplied
> + * to rte_eth_dev_configure().
> + * @param tx_pkts
> + * The address of an array of *nb_pkts* pointers to *rte_mbuf* structures
> + * which contain the output packets.
> + * @param nb_pkts
> + * The maximum number of packets to process.
> + * @return
> + * The number of packets correct and ready to be sent. The return value can be
> + * less than the value of the *tx_pkts* parameter when some packet doesn't
> + * meet devices requirements with rte_errno set appropriately.
> + */
Can we add the constraint that invalid packets are left untouched?
I think most of the time there will be a software fallback in that
case, so it would be good to ensure that this function does not change
the flags or the packet data.
Another thing that could be interesting for the caller is to know the
reason of the failure. Maybe the different errno types could be detailed
here. For instance:
- EINVAL: offload flags are not correctly set (i.e. would fail whatever
the hardware)
- ENOTSUP: the offload feature is not supported by the hardware
- ...
> +
> +#ifdef RTE_ETHDEV_TX_PREP
> +
> +static inline uint16_t
> +rte_eth_tx_prep(uint8_t port_id, uint16_t queue_id, struct rte_mbuf **tx_pkts,
> + uint16_t nb_pkts)
> +{
> + struct rte_eth_dev *dev = &rte_eth_devices[port_id];
> +
> + if (!dev->tx_pkt_prep)
> + return nb_pkts;
> +
> +#ifdef RTE_LIBRTE_ETHDEV_DEBUG
> + if (queue_id >= dev->data->nb_tx_queues) {
> + RTE_PMD_DEBUG_TRACE("Invalid TX queue_id=%d\n", queue_id);
> + rte_errno = -EINVAL;
> + return 0;
> + }
> +#endif
Why checking the queue_id but not the port_id?
Maybe the API comment should also be modified to say that the port_id
has to be valid, because most ethdev functions do the check.
> +
> + return (*dev->tx_pkt_prep)(dev->data->tx_queues[queue_id],
> + tx_pkts, nb_pkts);
> +}
> +
> +#else
> +
> +static inline uint16_t
> +rte_eth_tx_prep(__rte_unused uint8_t port_id, __rte_unused uint16_t queue_id,
> + __rte_unused struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
> +{
> + return nb_pkts;
> +}
> +
> +#endif
> +
nit: I wonder if the #else part should be inside the function instead
(with the proper RTE_SET_USED()), it would avoid to define the prototype
twice.
> typedef void (*buffer_tx_error_fn)(struct rte_mbuf **unsent, uint16_t count,
> void *userdata);
>
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> index 109e666..cfd6284 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -276,6 +276,15 @@ extern "C" {
> */
> #define PKT_TX_OUTER_IPV4 (1ULL << 59)
>
> +#define PKT_TX_OFFLOAD_MASK ( \
> + PKT_TX_IP_CKSUM | \
> + PKT_TX_L4_MASK | \
> + PKT_TX_OUTER_IP_CKSUM | \
> + PKT_TX_TCP_SEG | \
> + PKT_TX_QINQ_PKT | \
> + PKT_TX_VLAN_PKT | \
> + PKT_TX_TUNNEL_MASK)
> +
Could you add an API comment?
> --- /dev/null
> +++ b/lib/librte_net/rte_pkt.h
>
> [...]
> +/**
> + * Validate general requirements for tx offload in packet.
> + */
The API comment does not have the usual format.
> +static inline int
> +rte_validate_tx_offload(struct rte_mbuf *m)
should be const struct rte_mbuf *m
> +{
> + uint64_t ol_flags = m->ol_flags;
> +
> + /* Does packet set any of available offloads? */
> + if (!(ol_flags & PKT_TX_OFFLOAD_MASK))
> + return 0;
> +
> + /* IP checksum can be counted only for IPv4 packet */
> + if ((ol_flags & PKT_TX_IP_CKSUM) && (ol_flags & PKT_TX_IPV6))
> + return -EINVAL;
> +
> + if (ol_flags & (PKT_TX_L4_MASK | PKT_TX_TCP_SEG))
> + /* IP type not set */
> + if (!(ol_flags & (PKT_TX_IPV4 | PKT_TX_IPV6)))
> + return -EINVAL;
> +
> + if (ol_flags & PKT_TX_TCP_SEG)
> + /* PKT_TX_IP_CKSUM offload not set for IPv4 TSO packet */
> + if ((m->tso_segsz == 0) ||
> + ((ol_flags & PKT_TX_IPV4) && !(ol_flags & PKT_TX_IP_CKSUM)))
> + return -EINVAL;
> +
> + /* PKT_TX_OUTER_IP_CKSUM set for non outer IPv4 packet. */
> + if ((ol_flags & PKT_TX_OUTER_IP_CKSUM) && !(ol_flags & PKT_TX_OUTER_IPV4))
> + return -EINVAL;
> +
> + return 0;
> +}
It looks this function is only used when RTE_LIBRTE_ETHDEV_DEBUG is
set.
I'd say this function should go in rte_mbuf.h, because it's purely
related to mbuf flags, and does not rely on packet data or network
headers.
> +
> +/**
> + * Fix pseudo header checksum for TSO and non-TSO tcp/udp packets before
> + * hardware tx checksum.
> + * For non-TSO tcp/udp packets full pseudo-header checksum is counted and set.
> + * For TSO the IP payload length is not included.
> + */
The API comment should be fixed.
> +static inline int
> +rte_phdr_cksum_fix(struct rte_mbuf *m)
> +{
> + struct ipv4_hdr *ipv4_hdr;
> + struct ipv6_hdr *ipv6_hdr;
> + struct tcp_hdr *tcp_hdr;
> + struct udp_hdr *udp_hdr;
> + uint64_t ol_flags = m->ol_flags;
> + uint64_t inner_l3_offset = m->l2_len;
> +
> + if (ol_flags & PKT_TX_OUTER_IP_CKSUM)
> + inner_l3_offset += m->outer_l2_len + m->outer_l3_len;
> +
> + if ((ol_flags & PKT_TX_UDP_CKSUM) == PKT_TX_UDP_CKSUM) {
> + if (ol_flags & PKT_TX_IPV4) {
> + ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
> + inner_l3_offset);
> +
> + if (ol_flags & PKT_TX_IP_CKSUM)
> + ipv4_hdr->hdr_checksum = 0;
> +
> + udp_hdr = (struct udp_hdr *)((char *)ipv4_hdr + m->l3_len);
> + udp_hdr->dgram_cksum = rte_ipv4_phdr_cksum(ipv4_hdr, ol_flags);
> + } else {
> + ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *,
> + inner_l3_offset);
> + /* non-TSO udp */
> + udp_hdr = rte_pktmbuf_mtod_offset(m, struct udp_hdr *,
> + inner_l3_offset + m->l3_len);
> + udp_hdr->dgram_cksum = rte_ipv6_phdr_cksum(ipv6_hdr, ol_flags);
> + }
> + } else if ((ol_flags & PKT_TX_TCP_CKSUM) ||
> + (ol_flags & PKT_TX_TCP_SEG)) {
> + if (ol_flags & PKT_TX_IPV4) {
> + ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
> + inner_l3_offset);
> +
> + if (ol_flags & PKT_TX_IP_CKSUM)
> + ipv4_hdr->hdr_checksum = 0;
> +
> + /* non-TSO tcp or TSO */
> + tcp_hdr = (struct tcp_hdr *)((char *)ipv4_hdr + m->l3_len);
> + tcp_hdr->cksum = rte_ipv4_phdr_cksum(ipv4_hdr, ol_flags);
> + } else {
> + ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *,
> + inner_l3_offset);
> + /* non-TSO tcp or TSO */
> + tcp_hdr = rte_pktmbuf_mtod_offset(m, struct tcp_hdr *,
> + inner_l3_offset + m->l3_len);
> + tcp_hdr->cksum = rte_ipv6_phdr_cksum(ipv6_hdr, ol_flags);
> + }
> + }
> + return 0;
> +}
> +
> +#endif /* _RTE_PKT_H_ */
>
The function expects that all the network headers are in the first, and
that each of them is contiguous.
Also, I had an interesting remark from Stephen [1] on a similar code.
If the mbuf is a clone, it will modify the data of the direct mbuf,
which should be read-only. Note that it is likely to happen in
a TCP stack, because the packet is kept locally in case it has to
be retransmitted. Cloning a mbuf is more efficient than duplicating
it.
I plan to fix it in virtio code by "uncloning" the headers.
[1] http://dpdk.org/ml/archives/dev/2016-October/048873.html
Regards,
Olivier
^ permalink raw reply
* Re: [PATCH v7 0/7] vhost: optimize mergeable Rx path
From: Maxime Coquelin @ 2016-10-18 14:53 UTC (permalink / raw)
To: Yuanhan Liu, dev; +Cc: Jianbo Liu
In-Reply-To: <1476437678-7102-1-git-send-email-yuanhan.liu@linux.intel.com>
Hi Yuanhan,
On 10/14/2016 11:34 AM, Yuanhan Liu wrote:
> This is a new set of patches to optimize the mergeable Rx code path.
> No refactoring (rewrite) was made this time. It just applies some
> findings from Zhihong (kudos to him!) that could improve the mergeable
> Rx path on the old code.
>
> The two major factors that could improve the performance greatly are:
>
> - copy virtio header together with packet data. This could remove
> the buubbles between the two copy to optimize the cache access.
>
> This is implemented in patch 2 "vhost: optimize cache access"
>
> - shadow used ring update and update them at once
>
> The basic idea is to update used ring in a local buffer and flush
> them to the virtio used ring at once in the end. Again, this is
> for optimizing the cache access.
>
> This is implemented in patch 5 "vhost: shadow used ring update"
>
> The two optimizations could yield 40+% performance in micro testing
> and 20+% in PVP case testing with 64B packet size.
>
> Besides that, there are some tiny optimizations, such as prefetch
> avail ring (patch 6) and retrieve avail head once (patch 7).
>
> Note: the shadow used ring tech could also be applied to the non-mrg
> Rx path (and even the dequeu) path. I didn't do that for two reasons:
>
> - we already update used ring in batch in both path: it's not shadowed
> first though.
>
> - it's a bit too late too make many changes at this stage: RC1 is out.
>
> Please help testing.
I tested the following use-cases without noticing any functional problems:
- Windows Guests (mergeable ON & OFF, indirect disabled): ping other VM
- Linux guests with Kernel driver (mergeable ON & OFF, indirect OFF):
iperf between 2 VMs
- Linux guest with Virtio PMD (mergeable ON & OFF): testpmd txonly on
host, rxonly on guest.
Feel free to add my:
Tested-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Thanks,
Maxime
^ permalink raw reply
* [PATCH] vhost: fix use after free issue
From: Yuanhan Liu @ 2016-10-18 14:38 UTC (permalink / raw)
To: dev; +Cc: John McNamara, Yuanhan Liu
Fix the coverity USE_AFTER_FREE issue.
Fixes: a277c7159876 ("vhost: refactor code structure")
Coverity issue: 137884
Reported-by: John McNamara <john.mcnamara@intel.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
lib/librte_vhost/socket.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index 967cb65..aaa9c27 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -250,8 +250,8 @@ vhost_user_read_cb(int connfd, void *dat, int *remove)
vsocket->connfd = -1;
close(connfd);
*remove = 1;
- free(conn);
vhost_destroy_device(conn->vid);
+ free(conn);
if (vsocket->reconnect)
vhost_user_create_client(vsocket);
--
1.9.0
^ permalink raw reply related
* Re: [PATCH v3] vhost: Only access header if offloading is supported in dequeue path
From: Yuanhan Liu @ 2016-10-18 14:30 UTC (permalink / raw)
To: Maxime Coquelin; +Cc: dev, mst, jianfeng.tan, olivier.matz, stephen
In-Reply-To: <1476432427-2724-1-git-send-email-maxime.coquelin@redhat.com>
On Fri, Oct 14, 2016 at 10:07:07AM +0200, Maxime Coquelin wrote:
> If offloading features are not negotiated, parsing the virtio header
> is not needed.
>
> Micro-benchmark with testpmd shows that the gain is +4% with indirect
> descriptors, +1% when using direct descriptors.
>
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Applied to dpdk-next-virtio.
Thanks.
--yliu
^ permalink raw reply
* Re: [PATCH] drivers: make driver names consistent
From: Yuanhan Liu @ 2016-10-18 14:18 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: Jan Blunck, De Lara Guarch, Pablo, dev, Mcnamara, John
In-Reply-To: <10195497.iZAVVgVpbs@xps13>
On Tue, Oct 18, 2016 at 03:42:54PM +0200, Thomas Monjalon wrote:
> 2016-10-18 21:06, Yuanhan Liu:
> > On Tue, Oct 18, 2016 at 02:50:16PM +0200, Jan Blunck wrote:
> > > >From my understanding this is a massive API breakage. This forces all
> > > existing users of the virtual PMDs to change with zero benefit. Even
> > > if that isn't enough it also makes it impossible to switch between
> > > releases by recompiling.
> > >
> > > Can we please revert these changes and work on some aliasing support
> > > for the PMDs to fix it long term?
> >
> > +1. Aliasing is also something I would suggest before making such renames.
>
> It is a brutal change, yes.
> It was announced in 16.07 release notes though.
Yes, but it still took me a while (by running git bisect) to figure out
what went wrong: I wasn't aware of such note, that I was thinking maybe
something is broken.
Later I also got quite few same complains. It may also took them a while
to know what's happened.
Anyway, my point is, for this kind of change, we should have added the
alias support firstly. If that's been done, then the announcement is not
needed at all?
--yliu
>
> We can try to make this change more progressive by keeping old names
> as aliases for some time.
> Is there a volunteer to work on vdev names aliases,
> with the target of integrating them in RC2 or RC3?
^ permalink raw reply
* Re: [PATCH v2 12/12] virtio: add Tso support
From: Olivier Matz @ 2016-10-18 14:07 UTC (permalink / raw)
To: Stephen Hemminger, Yuanhan Liu
Cc: dev, konstantin.ananyev, sugesh.chandran, bruce.richardson,
jianfeng.tan, helin.zhang, adrien.mazarguil, dprovan, xiao.w.wang
In-Reply-To: <20161013163330.584b05db@xeon-e3>
Hi Stephen,
On 10/14/2016 01:33 AM, Stephen Hemminger wrote:
> On Thu, 13 Oct 2016 16:18:39 +0800
> Yuanhan Liu <yuanhan.liu@linux.intel.com> wrote:
>
>> On Mon, Oct 03, 2016 at 11:00:23AM +0200, Olivier Matz wrote:
>>> +/* When doing TSO, the IP length is not included in the pseudo header
>>> + * checksum of the packet given to the PMD, but for virtio it is
>>> + * expected.
>>> + */
>>> +static void
>>> +virtio_tso_fix_cksum(struct rte_mbuf *m)
>>> +{
>>> + /* common case: header is not fragmented */
>>> + if (likely(rte_pktmbuf_data_len(m) >= m->l2_len + m->l3_len +
>>> + m->l4_len)) {
>> ...
>>> + /* replace it in the packet */
>>> + th->cksum = new_cksum;
>>> + } else {
>> ...
>>> + /* replace it in the packet */
>>> + *rte_pktmbuf_mtod_offset(m, uint8_t *,
>>> + m->l2_len + m->l3_len + 16) = new_cksum.u8[0];
>>> + *rte_pktmbuf_mtod_offset(m, uint8_t *,
>>> + m->l2_len + m->l3_len + 17) = new_cksum.u8[1];
>>> + }
>>
>> The tcp header will always be in the mbuf, right? Otherwise, you can't
>> update the cksum field here. What's the point of introducing the "else
>> clause" then?
>>
>> --yliu
>
> You need to check the reference count before updating any data in mbuf.
>
That's correct, I'll fix that.
Thanks for the comment,
Olivier
^ permalink raw reply
* Re: [PATCH v11 00/24] Introducing rte_driver/rte_device generalization
From: Thomas Monjalon @ 2016-10-18 13:47 UTC (permalink / raw)
To: Neil Horman, Ferruh Yigit, Shreyansh Jain
Cc: dev, viktorin, David Marchand, hemant.agrawal
In-Reply-To: <20161018130424.GA12541@hmsreliant.think-freely.org>
2016-10-18 09:04, Neil Horman:
> On Mon, Oct 17, 2016 at 02:43:12PM +0100, Ferruh Yigit wrote:
> > I caught while running ABI validation script today, I think this patch
> > should increase LIBABIVER of:
> > - lib/librte_cryptodev
> > - lib/librte_eal
> > - lib/librte_ether
> >
> It should, and it in fact should wait a release if it hadn't been documented as
> a comming change.
It was announced in release 16.04:
http://dpdk.org/commit/c7970af
While bumping LIBABIVER, the deprecation notices must be removed,
and the API/ABI changes noted in the release notes, please.
^ permalink raw reply
* Re: [PATCH] drivers: make driver names consistent
From: Thomas Monjalon @ 2016-10-18 13:42 UTC (permalink / raw)
To: Yuanhan Liu, Jan Blunck, De Lara Guarch, Pablo; +Cc: dev, Mcnamara, John
In-Reply-To: <20161018130615.GK16751@yliu-dev.sh.intel.com>
2016-10-18 21:06, Yuanhan Liu:
> On Tue, Oct 18, 2016 at 02:50:16PM +0200, Jan Blunck wrote:
> > >From my understanding this is a massive API breakage. This forces all
> > existing users of the virtual PMDs to change with zero benefit. Even
> > if that isn't enough it also makes it impossible to switch between
> > releases by recompiling.
> >
> > Can we please revert these changes and work on some aliasing support
> > for the PMDs to fix it long term?
>
> +1. Aliasing is also something I would suggest before making such renames.
It is a brutal change, yes.
It was announced in 16.07 release notes though.
We can try to make this change more progressive by keeping old names
as aliases for some time.
Is there a volunteer to work on vdev names aliases,
with the target of integrating them in RC2 or RC3?
^ permalink raw reply
* [PATCH v1] doc: announce API change for ethdev function
From: Bernard Iremonger @ 2016-10-18 13:38 UTC (permalink / raw)
To: dev, john.mcnamara; +Cc: Bernard Iremonger
In-Reply-To: <1476797888-29698-1-git-send-email-bernard.iremonger@intel.com>
The _rte_eth_dev_call_process function will change to return "int"
and a fourth parameter "void* ret_param" will be added. This change
targets release 17.02.
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index d5c1490..1d274d8 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -49,3 +49,7 @@ Deprecation Notices
* mempool: The functions for single/multi producer/consumer are deprecated
and will be removed in 17.02.
It is replaced by ``rte_mempool_generic_get/put`` functions.
+
+* librte_ether: an API change is planned for 17.02 for the function
+ ``_rte_eth_dev_callback_process``. In 17.02 the function will return an ``int``
+ instead of ``void`` and a fourth parameter ``void *ret_param`` will be added.
--
2.10.1
^ permalink raw reply related
* [PATCH v1] doc: announce API and ABI change for librte_ether
From: Bernard Iremonger @ 2016-10-18 13:38 UTC (permalink / raw)
To: dev, john.mcnamara; +Cc: Bernard Iremonger
In 17.02 five rte_eth_dev_set_vf_*** functions will be removed
from librte_ether, renamed and moved to the ixgbe PMD.
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 1d274d8..20e11ac 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -53,3 +53,39 @@ Deprecation Notices
* librte_ether: an API change is planned for 17.02 for the function
``_rte_eth_dev_callback_process``. In 17.02 the function will return an ``int``
instead of ``void`` and a fourth parameter ``void *ret_param`` will be added.
+
+* librte_ether: for 17.02 it is planned to deprecate the following five functions:
+
+ ``rte_eth_dev_set_vf_rxmode``
+
+ ``rte_eth_dev_set_vf_rx``
+
+ ``rte_eth_dev_set_vf_tx``
+
+ ``rte_eth_dev_set_vf_vlan_filter``
+
+ ``rte_eth_set_vf_rate_limit``
+
+ The following fields will be removed from ``struct eth_dev_ops``:
+
+ ``eth_set_vf_rx_mode_t``
+
+ ``eth_set_vf_rx_t``
+
+ ``eth_set_vf_tx_t``
+
+ ``eth_set_vf_vlan_filter_t``
+
+ ``eth_set_vf_rate_limit_t``
+
+ The functions will be renamed to the following, and moved to the ``ixgbe`` PMD.
+
+ ``rte_pmd_ixgbe_set_vf_rxmode``
+
+ ``rte_pmd_ixgbe_set_vf_rx``
+
+ ``rte_pmd_ixgbe_set_vf_tx``
+
+ ``rte_pmd_ixgbe_set_vf_vlan_filter``
+
+ ``rte_pmd_ixgbe_set_vf_rate_limit``
--
2.10.1
^ permalink raw reply related
* Re: [PATCH] examples/ip_pipeline: fix freeBSD build error
From: Dumitrescu, Cristian @ 2016-10-18 13:28 UTC (permalink / raw)
To: Singh, Jasvinder, dev@dpdk.org
In-Reply-To: <1476719337-97327-1-git-send-email-jasvinder.singh@intel.com>
> -----Original Message-----
> From: Singh, Jasvinder
> Sent: Monday, October 17, 2016 4:49 PM
> To: dev@dpdk.org
> Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
> Subject: [PATCH] examples/ip_pipeline: fix freeBSD build error
>
> Error log:
> CC init.o
> examples/ip_pipeline/init.c:38:22: fatal error: linux/if.h: No such file or
> directory
> #include <linux/if.h>
> ^
> Fixes: 3f2c9f3bb6c6 ("examples/ip_pipeline: add TAP port")
>
> Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> ---
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox