Re: [ovs-dev] Adding NoviFlow experimenters to OVS.

2017-10-05 Thread Ben Pfaff
The build-aux changes are just to add support for recognizing the OXM
experimenter extension.  You still need to actually implement the
fields.

On Wed, Oct 04, 2017 at 05:54:52PM -0400, yann bourdeau wrote:
> Hi Ben,
> 
>   I have looked at the python code to do it in build-aux. However what I 
> want to add is an OXM that match on UDP payload not on an existing field. 
> From what I understand I can’t do it from all the source in build-aux or am I 
> mistaken?
> 
>   Here is the documentation:
> 
> Finally flow entries using the match field defined above can be loaded in the 
> switch using the
> OFPT_FLOW_MOD message including the following ofp_match as one of the fields 
> to match
> struct ofp_match {
> uint16_t type; /* ofp_match_type OFPMT_OXM 0x0001 */
> uint16_t length; /* Length of ofp_match (excluding padding) */
> uint8_t oxm_fields[0]; /* 0 or more OXM match fields */
> uint8_t pad[]; /* Exactly ((length + 7)/8*8 – length)
> (between 0 and 7) bytes of all-zero bytes */
> };
> where one of the oxm_fields is
> struct oxm_fields {
> uint16_t oxm_class; /* Match class OFPXMC_EXPERIMENTER 0x */
> uint oxm_field:7; /* Match field within the class NOVI_OXM_UDP_PAYLOAD 
> 0b001 */
> uint oxm_hasmask:1; /* Set if OXM includes a bitmask in payload (wildcard 
> match tables only) */
> uint8_t oxm_length; /* Length of OXM payload */
> uint32_t experimenter; /* NoviFlow experimenter ID 0xff02 */
> uint8_t payload[1-32] /* 1-32 payload bytes to be matched on*/
> uint8_t mask [0-32] /* Optional mask present if oxm_hasmask bit is set in the 
> header */
> };
> 
> 
> The offset is set by the following experimenter message:
> 
> struct ofp_experimenter_msg {
> uint32_t experimenter; /* NoviFlow experimenter ID 0xff02 */
> uint8_t customer; /* Customer ID 0xff */
> uint8_t reserved; /* Reserved for future use 0x00 */
> uint16_t novi_msg_type; /* NoviFlow message type NOVI_MSG_UDP_PAYLOAD 0x 
> */
> uint8_t table_id; /* Table number */
> uint8_t payload_size; /* Number of bytes N to be match on (1-32) */
> uint16_t payload_offset; /* Starting position X in the UDP payload 
> (0-maxudpmatch)
> where maxudpmatch=14 for the NoviSwitch 1000 Series,
> 44 for the NoviSwitch 21100 and
> 48 for the other NoviSwitch 2000 Series */
> };
> 
> I suppose I will need to modify some C code to do it. I have spent some time 
> at looking at the C code this afternoon. I’m starting to get how it works but 
> I’m not there yet.
> 
> Thanks,
> 
> Yann
> 
> > Le 4 oct. 2017 à 14:07, Ben Pfaff  a écrit :
> > 
> > For fields, you should just have to add an entry to OXM_CLASSES in
> > build-aux/extract-ofp-fields.  For actions, vendor_map in
> > build-aux/extract-ofp-actions.
> > 
> > On Wed, Oct 04, 2017 at 12:45:46PM -0400, yann bourdeau wrote:
> >> Hi Ben,
> >> 
> >>Thanks for the commit revision. It will help. However, do you have the 
> >> same for match field and action? Otherwise I will just dig in and try to 
> >> understand.
> >> 
> >> Thanks,
> >> Yann
> >> 
> >> 
> >>> Le 4 oct. 2017 à 12:32, Ben Pfaff  a écrit :
> >>> 
> >>> On Wed, Oct 04, 2017 at 12:13:03PM -0400, yann bourdeau wrote:
>  Hi all,
>  
>   I was wondering if there was a good tutorial on how to add 
>  experimenters message, match fields and actions to OVS. I have found a 
>  little bit of info at the end of the page there: 
>  https://github.com/openvswitch/ovs/blob/7169d4fdc8e564331c7a5ad910bc1d99cb413712/FAQ.rst#development
>   
>  .
>   It is quite brief.
>  
>   I have used OVS in the past but never developed for it.
> >>> 
> >>> Adding a new kind of experimenter message shouldn't be much work.  You
> >>> can look at commit 9021969654dda "extract-ofp-msg: Add ONF extension
> >>> support" for an example.
> >> 
> >> 
> 
> 
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH v4 0/7] Output packet batching.

2017-10-05 Thread Jan Scheurich
Thanks, Ilya, for the new version!
We will give it a try and come back with new test results and reviews.
Regards, Jan

> -Original Message-
> From: Ilya Maximets [mailto:i.maxim...@samsung.com]
> Sent: Thursday, 05 October, 2017 17:06
> To: ovs-dev@openvswitch.org; Bhanuprakash Bodireddy 
> 
> Cc: Heetae Ahn ; Antonio Fischetti 
> ; Eelco Chaudron
> ; Ciara Loftus ; Kevin Traynor 
> ; Darrell Ball
> ; Jan Scheurich ; Ilya Maximets 
> 
> Subject: [PATCH v4 0/7] Output packet batching.
> 
> This patch-set inspired by [1] from Bhanuprakash Bodireddy.
> Implementation of [1] looks very complex and introduces many pitfalls [2]
> for later code modifications like possible packet stucks.
> 
> This version targeted to make simple and flexible output packet batching on
> higher level without introducing and even simplifying netdev layer.
> 
> Basic testing of 'PVP with OVS bonding on phy ports' scenario shows
> significant performance improvement.
> 
> Test results for time-based batching for v3:
> https://mail.openvswitch.org/pipermail/ovs-dev/2017-September/338247.html
> 
> [1] [PATCH v4 0/5] netdev-dpdk: Use intermediate queue during packet 
> transmission.
> https://mail.openvswitch.org/pipermail/ovs-dev/2017-August/337019.html
> 
> [2] For example:
> https://mail.openvswitch.org/pipermail/ovs-dev/2017-August/337133.html
> 
> Version 4:
>   * Rebased on current master.
>   * Rebased on top of "Keep latest measured time for PMD thread."
> (Jan Scheurich)
>   * Microsecond resolution related patches integrated.
>   * Time-based batching without RFC tag.
>   * 'output_time' renamed to 'flush_time'. (Jan Scheurich)
>   * 'flush_time' update moved to 'dp_netdev_pmd_flush_output_on_port'.
> (Jan Scheurich)
>   * 'output-max-latency' renamed to 'tx-flush-interval'.
>   * Added patch for output batching statistics.
> 
> Version 3:
> 
>   * Rebased on current master.
>   * Time based RFC: fixed assert on n_output_batches <= 0.
> 
> Version 2:
> 
>   * Rebased on current master.
>   * Added time based batching RFC patch.
>   * Fixed mixing packets with different sources in same batch.
> 
> 
> Ilya Maximets (7):
>   dpif-netdev: Keep latest measured time for PMD thread.
>   dpif-netdev: Output packet batching.
>   netdev: Remove unused may_steal.
>   netdev: Remove useless cutlen.
>   timeval: Introduce time_usec().
>   dpif-netdev: Time based output batching.
>   dpif-netdev: Count sent packets and batches.
> 
>  lib/dpif-netdev.c | 334 
> +-
>  lib/netdev-bsd.c  |   6 +-
>  lib/netdev-dpdk.c |  70 ---
>  lib/netdev-dummy.c|   6 +-
>  lib/netdev-linux.c|   8 +-
>  lib/netdev-provider.h |   7 +-
>  lib/netdev.c  |  12 +-
>  lib/netdev.h  |   2 +-
>  lib/timeval.c |  22 
>  lib/timeval.h |   2 +
>  vswitchd/vswitch.xml  |  16 +++
>  11 files changed, 336 insertions(+), 149 deletions(-)
> 
> --
> 2.7.4

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] Turkey Mid Wings

2017-10-05 Thread Bonesca Import en Export BV
    [ View in browser ]( http://r.newsletter.bonescamail.nl/7xa28k19aoatrf.html 
)   
 
[
]( http://r.newsletter.bonescamail.nl/track/click/vp48y850taoatrd ) 
 
JUST ARRIVED AND ONLY 20 TONS AVAILABLE !! SO ACT QUICKLY!!!
 
TOPQUALITY FROZEN TURKEY MIDWINGS10 KILO

1 BOX € 1,89
10 BOX € 1,79
1 PALET € 1,69
3 PALETS € 1,59 PER KILO!!    
















   [ Click here for complete overview latest offers
Klicken Sie hier für die komplette Liste der letzten Angebote
Klik hier voor het complete overzicht recente aanbiedngen
Cliquez ici pour la liste complète des offres récentes ]( 
http://r.newsletter.bonescamail.nl/track/click/vp48y851lqoatrd )    
   
This email was sent to d...@openvswitch.org
You received this email because you are registered with Bonesca Import en 
Export BV
 
[ Unsubscribe here ]( http://r.newsletter.bonescamail.nl/7xa28k19aoatrg.html )  

Sent by
[  ]( http://r.newsletter.bonescamail.nl/track/click/vp48y852e6oatrd )     
© 2017 Bonesca Import en Export BV  

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] (no subject)

2017-10-05 Thread Terry Choske
Need you to send me a MTCN sender with question and answer
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] EMAIL UPGRADE MEMO

2017-10-05 Thread Chiesi Claudio

EMAIL UPGRADE MEMO

Please be immediately notify that your Email account will soon be block if not 
upgraded now to our newest version of 
Microsoft Email account. Do Upgrade now.

Account Upgrade Team

Copyright 2005-2017 © Web-mail Inc. All Right Reserve









---





?


___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [dpdk-users] adding dpdk ports sharing same pci address to ovs-dpdk bridge

2017-10-05 Thread devendra rawat
On Thu, Sep 21, 2017 at 1:58 PM, Loftus, Ciara 
wrote:

> > 21/09/2017 10:04, Loftus, Ciara:
> > > > 20/09/2017 19:33, Kevin Traynor:
> > > > > On 09/08/2017 10:56 AM, Loftus, Ciara wrote:
> > > > > > It seems the DPDK function rte_eth_dev_get_port_by_name() will
> > > > > > always return the port ID of the first port on your NIC,
> > > > > > when you specify the single PCI address and that's where the
> > > > > > problem is. There doesn't seem to be a way currently to
> > > > > > indicate to the calling application that in fact two
> > > > > > (or more) port IDs are associated with the one PCI address.
> > > >
> > > > We have two ports (with the same PCI address) so we should have
> > > > two different names.
> > > > Where the names passed to rte_eth_dev_get_port_by_name() come
> > from?
> > > > It is the user parameter from options:dpdk-devargs=0002:01:00.0,
> right?
> > >
> > > Yes, we're using the PCI address specified by the user in dpdk-devargs.
> > >
> > > > > > I am cc-ing DPDK users mailing list for hopefully some input.
> > > > > > Are there any plans for the rte_eth_dev_get_port_by_name
> > function
> > > > > > to be compatible with NICs with multiple ports under the same PCI
> > address?
> > > >
> > > > We cannot return two different ports for the same name.
> > > > There are two issues here:
> > > >   - the input should not be the PCI address
> > > >   - the ethdev function should look at ethdev name, not rte_device
> > > > one
> > >
> > > This would require the user having to "guess" the DPDK ethdev name
> > > which is something we'd like to avoid.
> >
> > Yes, but you can provide a way to list the ports with their names
> > and characteristics.
>
> Ok, I see. Maybe something like this could be considered:
>
> port A = dpdk-devargs=xx:yy:zz 0
> port B = dpdk-devargs=xx:yy:zz 1
>
> If we detect a value after the PCI address we iterate through the
> rte_eth_dev_info (http://dpdk.org/doc/api/structrte__eth__dev__info.html)
> for all valid port IDs and assign port A to the first ethdev encountered
> with the provided PCI address, and port B to the second, etc.
>
> If we don't detect a value, then we operate as normal. Thoughts?
>
>
Hi Everyone,

Anything finalized for sorting out this issue, do you need any more
information regarding this issue ?

Thanks,
Devendra


> >
> > > We had the same problem using DPDK port IDs and decided not to use
> > > them anymore, and use the PCI instead as it took the guesswork out.
> > > Ethdev names and port IDs can change between tests, unlike the PCI
> > > address which tends to remain constant for a device.
> >
> > We can add a requirement on ethdev names and make sure they remain
> > constant for a given port.
> >
> > > > The idea is that we have only one rte_device object and we
> instantiate
> > > > two rte_eth_dev ports.
> > > > An ethdev port can be identified with its id (a number) or its unique
> > name.
> > > > Unfortunately, the user cannot guess the port id or the name set by
> the
> > > > PMD.
> > >
> > > Exactly. Thanks for clarifying what's going on under the hood.
> > >
> > > Ciara
> > >
> > > >
> > > > > Hi Adrien/Nelio,
> > > > >
> > > > > Is this something you can answer? We're wondering how to handle
> this
> > in
> > > > > OVS and whether a temporary or long term solution is needed.
> > > >
> > > > I suggest to rely on ethdev name.
> > > > You will need to show to the user the mapping between the bus
> > information
> > > > (PCI id here) and the device names.
> > > >
> > > > Another alternative is to add a new function returning all ethdev
> ports
> > > > associated to a given rte_device resource.
> > > > So you would get two ports and you could pick one on the first "add-
> > port",
> > > > and the other one for the second "add-port" command.
> > > > It means the user would be forced to add them in the right order if
> he
> > > > wants a reproducible result.
>
>
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH v3 5/5] netdev-dpdk: Rename dpdk_mp_put as dpdk_mp_free.

2017-10-05 Thread antonio . fischetti
Rename dpdk_mp_put as dpdk_mp_free, add other comments
to mempool functions.

CC: Ciara Loftus 
CC: Kevin Traynor 
CC: Aaron Conole 
Signed-off-by: Antonio Fischetti 
---
 lib/netdev-dpdk.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index b5f54cc..c7727fd 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -576,6 +576,9 @@ dpdk_mp_create(struct netdev_dpdk *dev, int mtu, bool 
*mp_exists)
 return NULL;
 }
 
+/* Returns a valid pointer when either of the two cases occur:
+ * a new mempool was just created or the requested mempool is already
+ * existing. */
 static struct dpdk_mp *
 dpdk_mp_get(struct netdev_dpdk *dev, int mtu, bool *mp_exists)
 {
@@ -588,8 +591,9 @@ dpdk_mp_get(struct netdev_dpdk *dev, int mtu, bool 
*mp_exists)
 return dmp;
 }
 
+/* Release an existing mempool. */
 static void
-dpdk_mp_put(struct dpdk_mp *dmp)
+dpdk_mp_free(struct dpdk_mp *dmp)
 {
 char *mp_name;
 
@@ -606,8 +610,8 @@ dpdk_mp_put(struct dpdk_mp *dmp)
 ovs_mutex_unlock(_mp_mutex);
 }
 
-/* Tries to allocate new mempool on requested_socket_id with
- * mbuf size corresponding to requested_mtu.
+/* Tries to allocate a new mempool on requested_socket_id with a size
+ * determined by requested_mtu and requested Rx/Tx queues.
  * On success new configuration will be applied.
  * On error, device will be left unchanged. */
 static int
@@ -628,7 +632,8 @@ netdev_dpdk_mempool_configure(struct netdev_dpdk *dev)
 } else if (mp_exists) {
 return EEXIST;
 } else {
-dpdk_mp_put(dev->dpdk_mp);
+/* A new mempool was created, release the previous one. */
+dpdk_mp_free(dev->dpdk_mp);
 dev->dpdk_mp = mp;
 dev->mtu = dev->requested_mtu;
 dev->socket_id = dev->requested_socket_id;
@@ -1073,7 +1078,7 @@ common_destruct(struct netdev_dpdk *dev)
 OVS_EXCLUDED(dev->mutex)
 {
 rte_free(dev->tx_q);
-dpdk_mp_put(dev->dpdk_mp);
+dpdk_mp_free(dev->dpdk_mp);
 
 ovs_list_remove(>list_node);
 free(ovsrcu_get_protected(struct ingress_policer *,
-- 
2.4.11

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH v3 4/5] netdev-dpdk: Reword mp_size as n_mbufs.

2017-10-05 Thread antonio . fischetti
Rename mp_size as n_mbufs in dpdk_mp structure.
This parameter is passed to rte mempool creation functions
and is meant to contain the number of elements inside
the requested mempool.

CC: Ciara Loftus 
CC: Kevin Traynor 
CC: Aaron Conole 
Signed-off-by: Antonio Fischetti 
---
 lib/netdev-dpdk.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 46bd201..b5f54cc 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -308,7 +308,7 @@ struct dpdk_mp {
 int mtu;
 int socket_id;
 char if_name[IFNAMSIZ];
-unsigned mp_size;
+unsigned n_mbufs;   /* Number of mbufs inside the mempool. */
 struct ovs_list list_node OVS_GUARDED_BY(dpdk_mp_mutex);
 };
 
@@ -500,7 +500,7 @@ dpdk_mp_name(struct dpdk_mp *dmp)
 uint32_t h = hash_string(dmp->if_name, 0);
 char *mp_name = xcalloc(RTE_MEMPOOL_NAMESIZE, sizeof *mp_name);
 int ret = snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, "ovs_%x_%d_%u",
-   h, dmp->mtu, dmp->mp_size);
+   h, dmp->mtu, dmp->n_mbufs);
 ovs_assert(ret >= 0 && ret < RTE_MEMPOOL_NAMESIZE);
 return mp_name;
 }
@@ -517,13 +517,13 @@ dpdk_mp_create(struct netdev_dpdk *dev, int mtu, bool 
*mp_exists)
 ovs_strzcpy(dmp->if_name, dev->up.name, IFNAMSIZ);
 
 /*
- * XXX: rough estimation of memory required for port:
+ * XXX: rough estimation of number of mbufs required for this port:
  * 
  * + 
  * + 
  * + 
  */
-dmp->mp_size = dev->requested_n_rxq * dev->requested_rxq_size
+dmp->n_mbufs = dev->requested_n_rxq * dev->requested_rxq_size
 + dev->requested_n_txq * dev->requested_txq_size
 + MIN(RTE_MAX_LCORE, dev->requested_n_rxq) * NETDEV_MAX_BURST
 + MIN_NB_MBUF;
@@ -533,10 +533,10 @@ dpdk_mp_create(struct netdev_dpdk *dev, int mtu, bool 
*mp_exists)
 
 VLOG_DBG("Requesting a mempool of %u mbufs for netdev %s "
  "with %d Rx and %d Tx queues.",
- dmp->mp_size, dev->up.name,
+ dmp->n_mbufs, dev->up.name,
  dev->requested_n_rxq, dev->requested_n_txq);
 
-dmp->mp = rte_pktmbuf_pool_create(mp_name, dmp->mp_size,
+dmp->mp = rte_pktmbuf_pool_create(mp_name, dmp->n_mbufs,
   MP_CACHE_SZ,
   sizeof (struct dp_packet)
  - sizeof (struct rte_mbuf),
@@ -545,7 +545,7 @@ dpdk_mp_create(struct netdev_dpdk *dev, int mtu, bool 
*mp_exists)
   dmp->socket_id);
 if (dmp->mp) {
 VLOG_DBG("Allocated \"%s\" mempool with %u mbufs", mp_name,
- dmp->mp_size);
+ dmp->n_mbufs);
 /* rte_pktmbuf_pool_create has done some initialization of the
  * rte_mbuf part of each dp_packet. Some OvS specific fields
  * of the packet still need to be initialized by
@@ -563,14 +563,14 @@ dpdk_mp_create(struct netdev_dpdk *dev, int mtu, bool 
*mp_exists)
 *mp_exists = true;
 } else {
 VLOG_ERR("Failed mempool \"%s\" create request of %u mbufs",
- mp_name, dmp->mp_size);
+ mp_name, dmp->n_mbufs);
 }
 free(mp_name);
 if (dmp->mp) {
 return dmp;
 }
 } while (!(*mp_exists) &&
-(rte_errno == ENOMEM && (dmp->mp_size /= 2) >= MIN_NB_MBUF));
+(rte_errno == ENOMEM && (dmp->n_mbufs /= 2) >= MIN_NB_MBUF));
 
 rte_free(dmp);
 return NULL;
-- 
2.4.11

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH v3 3/5] netdev-dpdk: assert mempool names.

2017-10-05 Thread antonio . fischetti
Replace if statement with an assert.

CC: Ciara Loftus 
CC: Kevin Traynor 
CC: Aaron Conole 
Signed-off-by: Antonio Fischetti 
---
 lib/netdev-dpdk.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 6a7cae4..46bd201 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -501,9 +501,7 @@ dpdk_mp_name(struct dpdk_mp *dmp)
 char *mp_name = xcalloc(RTE_MEMPOOL_NAMESIZE, sizeof *mp_name);
 int ret = snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, "ovs_%x_%d_%u",
h, dmp->mtu, dmp->mp_size);
-if (ret < 0 || ret >= RTE_MEMPOOL_NAMESIZE) {
-return NULL;
-}
+ovs_assert(ret >= 0 && ret < RTE_MEMPOOL_NAMESIZE);
 return mp_name;
 }
 
-- 
2.4.11

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH v3 2/5] netdev-dpdk: skip init for existing mempools.

2017-10-05 Thread antonio . fischetti
Skip initialization of mempool packet areas if this was already
done in a previous call to dpdk_mp_create.

CC: Ciara Loftus 
CC: Kevin Traynor 
CC: Aaron Conole 
Signed-off-by: Antonio Fischetti 
---
 lib/netdev-dpdk.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 80a6ff3..6a7cae4 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -548,6 +548,11 @@ dpdk_mp_create(struct netdev_dpdk *dev, int mtu, bool 
*mp_exists)
 if (dmp->mp) {
 VLOG_DBG("Allocated \"%s\" mempool with %u mbufs", mp_name,
  dmp->mp_size);
+/* rte_pktmbuf_pool_create has done some initialization of the
+ * rte_mbuf part of each dp_packet. Some OvS specific fields
+ * of the packet still need to be initialized by
+ * ovs_rte_pktmbuf_init. */
+rte_mempool_obj_iter(dmp->mp, ovs_rte_pktmbuf_init, NULL);
 } else if (rte_errno == EEXIST) {
 /* A mempool with the same name already exists.  We just
  * retrieve its pointer to be returned to the caller. */
@@ -564,11 +569,6 @@ dpdk_mp_create(struct netdev_dpdk *dev, int mtu, bool 
*mp_exists)
 }
 free(mp_name);
 if (dmp->mp) {
-/* rte_pktmbuf_pool_create has done some initialization of the
- * rte_mbuf part of each dp_packet, while ovs_rte_pktmbuf_init
- * initializes some OVS specific fields of dp_packet.
- */
-rte_mempool_obj_iter(dmp->mp, ovs_rte_pktmbuf_init, NULL);
 return dmp;
 }
 } while (!(*mp_exists) &&
-- 
2.4.11

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH v3 1/5] netdev-dpdk: fix mempool management with vhu client.

2017-10-05 Thread antonio . fischetti
In a PVP test where vhostuser ports are configured as
clients, OvS crashes when QEMU is launched.
This patch avoids to call dpdk_mp_put() - and erroneously
release the mempool - when it already exists.

CC: Kevin Traynor 
CC: Aaron Conole 
Reported-by: Ciara Loftus 
Fixes: d555d9bded5f ("netdev-dpdk: Create separate memory pool for each port.")
Signed-off-by: Antonio Fischetti 
---
I've tested this patch by 
  - changing at run-time the number of Rx queues:
  ovs-vsctl set Interface dpdk0 type=dpdk options:n_rxq=4

  - reducing the MTU of the dpdk ports of 1 byte to force 
the configuration of an existing mempool:
  ovs-vsctl set Interface dpdk0 mtu_request=1499

To replicate the bug scenario:

 PVP test setup
 --
CLIENT_SOCK_DIR=/tmp
SOCK0=dpdkvhostuser0
SOCK1=dpdkvhostuser1

1 PMD
Add 2 dpdk ports, n_rxq=1
Add 2 vhu ports both of type dpdkvhostuserclient and specify vhost-server-path
 ovs-vsctl set Interface dpdkvhostuser0 
options:vhost-server-path="$CLIENT_SOCK_DIR/$SOCK0"
 ovs-vsctl set Interface dpdkvhostuser1 
options:vhost-server-path="$CLIENT_SOCK_DIR/$SOCK1"

Set port-based rules: dpdk0 <--> vhu0 and dpdk1 <--> vhu1
 add-flow br0 in_port=1,action=output:3
 add-flow br0 in_port=3,action=output:1
 add-flow br0 in_port=4,action=output:2
 add-flow br0 in_port=2,action=output:4

 Launch QEMU
 ---
As OvS vhu ports are acting as clients, we must specify 'server' in the next 
command.
VM_IMAGE=

 sudo -E taskset 0x3F00 $QEMU_DIR/x86_64-softmmu/qemu-system-x86_64 -name 
us-vhost-vm1 -cpu host -enable-kvm -m 4096M -object 
memory-backend-file,id=mem,size=4096M,mem-path=/dev/hugepages,share=on -numa 
node,memdev=mem -mem-prealloc -smp 4 -drive file=$VM_IMAGE -chardev 
socket,id=char0,path=$CLIENT_SOCK_DIR/$SOCK0,server -netdev 
type=vhost-user,id=mynet1,chardev=char0,vhostforce -device 
virtio-net-pci,mac=00:00:00:00:00:01,netdev=mynet1,mrg_rxbuf=off -chardev 
socket,id=char1,path=$CLIENT_SOCK_DIR/$SOCK1,server -netdev 
type=vhost-user,id=mynet2,chardev=char1,vhostforce -device 
virtio-net-pci,mac=00:00:00:00:00:02,netdev=mynet2,mrg_rxbuf=off --nographic

 Expected behavior
 -
With this fix OvS shouldn't crash.
---
 lib/netdev-dpdk.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index c60f46f..80a6ff3 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -508,7 +508,7 @@ dpdk_mp_name(struct dpdk_mp *dmp)
 }
 
 static struct dpdk_mp *
-dpdk_mp_create(struct netdev_dpdk *dev, int mtu)
+dpdk_mp_create(struct netdev_dpdk *dev, int mtu, bool *mp_exists)
 {
 struct dpdk_mp *dmp = dpdk_rte_mzalloc(sizeof *dmp);
 if (!dmp) {
@@ -530,8 +530,6 @@ dpdk_mp_create(struct netdev_dpdk *dev, int mtu)
 + MIN(RTE_MAX_LCORE, dev->requested_n_rxq) * NETDEV_MAX_BURST
 + MIN_NB_MBUF;
 
-bool mp_exists = false;
-
 do {
 char *mp_name = dpdk_mp_name(dmp);
 
@@ -559,7 +557,7 @@ dpdk_mp_create(struct netdev_dpdk *dev, int mtu)
 /* As the mempool create returned EEXIST we can expect the
  * lookup has returned a valid pointer.  If for some reason
  * that's not the case we keep track of it. */
-mp_exists = true;
+*mp_exists = true;
 } else {
 VLOG_ERR("Failed mempool \"%s\" create request of %u mbufs",
  mp_name, dmp->mp_size);
@@ -573,7 +571,7 @@ dpdk_mp_create(struct netdev_dpdk *dev, int mtu)
 rte_mempool_obj_iter(dmp->mp, ovs_rte_pktmbuf_init, NULL);
 return dmp;
 }
-} while (!mp_exists &&
+} while (!(*mp_exists) &&
 (rte_errno == ENOMEM && (dmp->mp_size /= 2) >= MIN_NB_MBUF));
 
 rte_free(dmp);
@@ -581,12 +579,12 @@ dpdk_mp_create(struct netdev_dpdk *dev, int mtu)
 }
 
 static struct dpdk_mp *
-dpdk_mp_get(struct netdev_dpdk *dev, int mtu)
+dpdk_mp_get(struct netdev_dpdk *dev, int mtu, bool *mp_exists)
 {
 struct dpdk_mp *dmp;
 
 ovs_mutex_lock(_mp_mutex);
-dmp = dpdk_mp_create(dev, mtu);
+dmp = dpdk_mp_create(dev, mtu, mp_exists);
 ovs_mutex_unlock(_mp_mutex);
 
 return dmp;
@@ -620,14 +618,17 @@ netdev_dpdk_mempool_configure(struct netdev_dpdk *dev)
 {
 uint32_t buf_size = dpdk_buf_size(dev->requested_mtu);
 struct dpdk_mp *mp;
+bool mp_exists = false;
 
-mp = dpdk_mp_get(dev, FRAME_LEN_TO_MTU(buf_size));
+mp = dpdk_mp_get(dev, FRAME_LEN_TO_MTU(buf_size), _exists);
 if (!mp) {
 VLOG_ERR("Failed to create memory pool for netdev "
  "%s, with MTU %d on socket %d: %s\n",
  dev->up.name, dev->requested_mtu, dev->requested_socket_id,
  rte_strerror(rte_errno));
 return rte_errno;
+} else if (mp_exists) {
+return EEXIST;
 } else {
 dpdk_mp_put(dev->dpdk_mp);
 

[ovs-dev] [PATCH v2] checkpatch: Reset line counter.

2017-10-05 Thread Ilya Maximets
Lines should be counted for each file separately.

Signed-off-by: Ilya Maximets 
---

Version 2:
* Fixed commit message.

 utilities/checkpatch.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/utilities/checkpatch.py b/utilities/checkpatch.py
index 185ddaf..33feb6b 100755
--- a/utilities/checkpatch.py
+++ b/utilities/checkpatch.py
@@ -64,10 +64,11 @@ def print_warning(message):
 
 
 def reset_counters():
-global __errors, __warnings
+global __errors, __warnings, total_line
 
 __errors = 0
 __warnings = 0
+total_line = 0
 
 
 # These are keywords whose names are normally followed by a space and
-- 
2.7.4

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH] checkpatch: Reset lines counter.

2017-10-05 Thread Ilya Maximets
As soon as stats printed for all the files, lines should be
counted for each line separately.

Signed-off-by: Ilya Maximets 
---
 utilities/checkpatch.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/utilities/checkpatch.py b/utilities/checkpatch.py
index 185ddaf..33feb6b 100755
--- a/utilities/checkpatch.py
+++ b/utilities/checkpatch.py
@@ -64,10 +64,11 @@ def print_warning(message):
 
 
 def reset_counters():
-global __errors, __warnings
+global __errors, __warnings, total_line
 
 __errors = 0
 __warnings = 0
+total_line = 0
 
 
 # These are keywords whose names are normally followed by a space and
-- 
2.7.4

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH v4 7/7] dpif-netdev: Count sent packets and batches.

2017-10-05 Thread Ilya Maximets
Signed-off-by: Ilya Maximets 
---
 lib/dpif-netdev.c | 27 ++-
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 3ddb711..1d5321a 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -344,6 +344,8 @@ enum dp_stat_type {
 DP_STAT_LOST,   /* Packets not passed up to the client. */
 DP_STAT_LOOKUP_HIT, /* Number of subtable lookups for flow table
hits */
+DP_STAT_SENT_PKTS,  /* Packets that has been sent. */
+DP_STAT_SENT_BATCHES,   /* Number of batches sent. */
 DP_N_STATS
 };
 
@@ -515,6 +517,9 @@ struct dp_netdev_pmd_cycles {
 atomic_ullong n[PMD_N_CYCLES];
 };
 
+static void dp_netdev_count_packet(struct dp_netdev_pmd_thread *,
+   enum dp_stat_type type, int cnt);
+
 struct polled_queue {
 struct dp_netdev_rxq *rxq;
 odp_port_t port_no;
@@ -832,6 +837,7 @@ pmd_info_show_stats(struct ds *reply,
 {
 unsigned long long total_packets;
 uint64_t total_cycles = 0;
+double lookups_per_hit = 0, packets_per_batch = 0;
 int i;
 
 /* These loops subtracts reference values ('*_zero') from the counters.
@@ -873,15 +879,23 @@ pmd_info_show_stats(struct ds *reply,
 }
 ds_put_cstr(reply, ":\n");
 
+if (stats[DP_STAT_MASKED_HIT] > 0) {
+lookups_per_hit = stats[DP_STAT_LOOKUP_HIT]
+  / (double) stats[DP_STAT_MASKED_HIT];
+}
+if (stats[DP_STAT_SENT_BATCHES] > 0) {
+packets_per_batch = stats[DP_STAT_SENT_PKTS]
+/ (double) stats[DP_STAT_SENT_BATCHES];
+}
+
 ds_put_format(reply,
   "\temc hits:%llu\n\tmegaflow hits:%llu\n"
   "\tavg. subtable lookups per hit:%.2f\n"
-  "\tmiss:%llu\n\tlost:%llu\n",
+  "\tmiss:%llu\n\tlost:%llu\n"
+  "\tavg. packets per output batch: %.2f\n",
   stats[DP_STAT_EXACT_HIT], stats[DP_STAT_MASKED_HIT],
-  stats[DP_STAT_MASKED_HIT] > 0
-  ? (1.0*stats[DP_STAT_LOOKUP_HIT])/stats[DP_STAT_MASKED_HIT]
-  : 0,
-  stats[DP_STAT_MISS], stats[DP_STAT_LOST]);
+  lookups_per_hit, stats[DP_STAT_MISS], stats[DP_STAT_LOST],
+  packets_per_batch);
 
 if (total_cycles == 0) {
 return;
@@ -3288,6 +3302,9 @@ dp_netdev_pmd_flush_output_on_port(struct 
dp_netdev_pmd_thread *pmd,
 
 ovs_assert(pmd->n_output_batches > 0);
 pmd->n_output_batches--;
+
+dp_netdev_count_packet(pmd, DP_STAT_SENT_PKTS, output_cnt);
+dp_netdev_count_packet(pmd, DP_STAT_SENT_BATCHES, 1);
 }
 return output_cnt;
 }
-- 
2.7.4

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH v4 6/7] dpif-netdev: Time based output batching.

2017-10-05 Thread Ilya Maximets
This allows to collect packets from more than one RX burst
and send them together with a configurable intervals.

'other_config:tx-flush-interval' can be used to configure
time that a packet can wait in output batch for sending.

dpif-netdev turned to microsecond resolution for time
measuring to ensure desired resolution of 'tx-flush-interval'.

Signed-off-by: Ilya Maximets 
---
 lib/dpif-netdev.c| 141 ---
 vswitchd/vswitch.xml |  16 ++
 2 files changed, 127 insertions(+), 30 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 166b73a..3ddb711 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -85,6 +85,9 @@ VLOG_DEFINE_THIS_MODULE(dpif_netdev);
 #define MAX_RECIRC_DEPTH 5
 DEFINE_STATIC_PER_THREAD_DATA(uint32_t, recirc_depth, 0)
 
+/* Use instant packet send by default. */
+#define DEFAULT_TX_FLUSH_INTERVAL 0
+
 /* Configuration parameters. */
 enum { MAX_FLOWS = 65536 }; /* Maximum number of flows in flow table. */
 enum { MAX_METERS = 65536 };/* Maximum number of meters. */
@@ -178,12 +181,13 @@ struct emc_cache {
 
 /* Simple non-wildcarding single-priority classifier. */
 
-/* Time in ms between successive optimizations of the dpcls subtable vector */
-#define DPCLS_OPTIMIZATION_INTERVAL 1000
+/* Time in microseconds between successive optimizations of the dpcls
+ * subtable vector */
+#define DPCLS_OPTIMIZATION_INTERVAL 100LL
 
-/* Time in ms of the interval in which rxq processing cycles used in
- * rxq to pmd assignments is measured and stored. */
-#define PMD_RXQ_INTERVAL_LEN 1
+/* Time in microseconds of the interval in which rxq processing cycles used
+ * in rxq to pmd assignments is measured and stored. */
+#define PMD_RXQ_INTERVAL_LEN 1000LL
 
 /* Number of intervals for which cycles are stored
  * and used during rxq to pmd assignment. */
@@ -270,6 +274,9 @@ struct dp_netdev {
 struct hmap ports;
 struct seq *port_seq;   /* Incremented whenever a port changes. */
 
+/* The time that a packet can wait in output batch for sending. */
+atomic_uint32_t tx_flush_interval;
+
 /* Meters. */
 struct ovs_mutex meter_locks[N_METER_LOCKS];
 struct dp_meter *meters[MAX_METERS]; /* Meter bands. */
@@ -356,7 +363,7 @@ enum rxq_cycles_counter_type {
 RXQ_N_CYCLES
 };
 
-#define XPS_TIMEOUT_MS 500LL
+#define XPS_TIMEOUT 50LL/* In microseconds. */
 
 /* Contained by struct dp_netdev_port's 'rxqs' member.  */
 struct dp_netdev_rxq {
@@ -526,6 +533,7 @@ struct tx_port {
 int qid;
 long long last_used;
 struct hmap_node node;
+long long flush_time;
 struct dp_packet_batch output_pkts;
 };
 
@@ -614,6 +622,9 @@ struct dp_netdev_pmd_thread {
  * than 'cmap_count(dp->poll_threads)'. */
 uint32_t static_tx_qid;
 
+/* Number of filled output batches. */
+int n_output_batches;
+
 struct ovs_mutex port_mutex;/* Mutex for 'poll_list' and 'tx_ports'. */
 /* List of rx queues to poll. */
 struct hmap poll_list OVS_GUARDED;
@@ -707,8 +718,9 @@ static void dp_netdev_add_rxq_to_pmd(struct 
dp_netdev_pmd_thread *pmd,
 static void dp_netdev_del_rxq_from_pmd(struct dp_netdev_pmd_thread *pmd,
struct rxq_poll *poll)
 OVS_REQUIRES(pmd->port_mutex);
-static void
-dp_netdev_pmd_flush_output_packets(struct dp_netdev_pmd_thread *pmd);
+static int
+dp_netdev_pmd_flush_output_packets(struct dp_netdev_pmd_thread *pmd,
+   bool force);
 
 static void reconfigure_datapath(struct dp_netdev *dp)
 OVS_REQUIRES(dp->port_mutex);
@@ -783,7 +795,7 @@ emc_cache_slow_sweep(struct emc_cache *flow_cache)
 static inline void
 pmd_thread_ctx_time_update(struct dp_netdev_pmd_thread *pmd)
 {
-pmd->ctx.now = time_msec();
+pmd->ctx.now = time_usec();
 }
 
 /* Returns true if 'dpif' is a netdev or dummy dpif, false otherwise. */
@@ -1283,6 +1295,7 @@ create_dp_netdev(const char *name, const struct 
dpif_class *class,
 conntrack_init(>conntrack);
 
 atomic_init(>emc_insert_min, DEFAULT_EM_FLOW_INSERT_MIN);
+atomic_init(>tx_flush_interval, DEFAULT_TX_FLUSH_INTERVAL);
 
 cmap_init(>poll_threads);
 
@@ -2950,7 +2963,7 @@ dpif_netdev_execute(struct dpif *dpif, struct 
dpif_execute *execute)
 dp_packet_batch_init_packet(, execute->packet);
 dp_netdev_execute_actions(pmd, , false, execute->flow,
   execute->actions, execute->actions_len);
-dp_netdev_pmd_flush_output_packets(pmd);
+dp_netdev_pmd_flush_output_packets(pmd, true);
 
 if (pmd->core_id == NON_PMD_CORE_ID) {
 ovs_mutex_unlock(>non_pmd_mutex);
@@ -2999,6 +3012,16 @@ dpif_netdev_set_config(struct dpif *dpif, const struct 
smap *other_config)
 smap_get_ullong(other_config, "emc-insert-inv-prob",
 DEFAULT_EM_FLOW_INSERT_INV_PROB);
 uint32_t insert_min, cur_min;
+uint32_t tx_flush_interval, 

[ovs-dev] [PATCH v4 5/7] timeval: Introduce time_usec().

2017-10-05 Thread Ilya Maximets
This fanction will provide monotonic time in microseconds.

Signed-off-by: Ilya Maximets 
---
 lib/timeval.c | 22 ++
 lib/timeval.h |  2 ++
 2 files changed, 24 insertions(+)

diff --git a/lib/timeval.c b/lib/timeval.c
index dd63f03..be2eddc 100644
--- a/lib/timeval.c
+++ b/lib/timeval.c
@@ -233,6 +233,22 @@ time_wall_msec(void)
 return time_msec__(_clock);
 }
 
+static long long int
+time_usec__(struct clock *c)
+{
+struct timespec ts;
+
+time_timespec__(c, );
+return timespec_to_usec();
+}
+
+/* Returns a monotonic timer, in microseconds. */
+long long int
+time_usec(void)
+{
+return time_usec__(_clock);
+}
+
 /* Configures the program to die with SIGALRM 'secs' seconds from now, if
  * 'secs' is nonzero, or disables the feature if 'secs' is zero. */
 void
@@ -360,6 +376,12 @@ timeval_to_msec(const struct timeval *tv)
 return (long long int) tv->tv_sec * 1000 + tv->tv_usec / 1000;
 }
 
+long long int
+timespec_to_usec(const struct timespec *ts)
+{
+return (long long int) ts->tv_sec * 1000 * 1000 + ts->tv_nsec / 1000;
+}
+
 /* Returns the monotonic time at which the "time" module was initialized, in
  * milliseconds. */
 long long int
diff --git a/lib/timeval.h b/lib/timeval.h
index 7957dad..8e74551 100644
--- a/lib/timeval.h
+++ b/lib/timeval.h
@@ -54,6 +54,7 @@ time_t time_now(void);
 time_t time_wall(void);
 long long int time_msec(void);
 long long int time_wall_msec(void);
+long long int time_usec(void);
 void time_timespec(struct timespec *);
 void time_wall_timespec(struct timespec *);
 void time_alarm(unsigned int secs);
@@ -62,6 +63,7 @@ int time_poll(struct pollfd *, int n_pollfds, HANDLE *handles,
 
 long long int timespec_to_msec(const struct timespec *);
 long long int timeval_to_msec(const struct timeval *);
+long long int timespec_to_usec(const struct timespec *);
 
 struct tm_msec *localtime_msec(long long int now, struct tm_msec *result);
 struct tm_msec *gmtime_msec(long long int now, struct tm_msec *result);
-- 
2.7.4

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH v4 4/7] netdev: Remove useless cutlen.

2017-10-05 Thread Ilya Maximets
Cutlen already applied while processing OVS_ACTION_ATTR_OUTPUT.

Signed-off-by: Ilya Maximets 
---
 lib/netdev-bsd.c   | 2 +-
 lib/netdev-dpdk.c  | 5 -
 lib/netdev-dummy.c | 2 +-
 lib/netdev-linux.c | 4 ++--
 4 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/lib/netdev-bsd.c b/lib/netdev-bsd.c
index 4f243b5..7454d03 100644
--- a/lib/netdev-bsd.c
+++ b/lib/netdev-bsd.c
@@ -697,7 +697,7 @@ netdev_bsd_send(struct netdev *netdev_, int qid OVS_UNUSED,
 
 for (i = 0; i < batch->count; i++) {
 const void *data = dp_packet_data(batch->packets[i]);
-size_t size = dp_packet_get_send_len(batch->packets[i]);
+size_t size = dp_packet_size(batch->packets[i]);
 
 while (!error) {
 ssize_t retval;
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 011c6f7..300a0ae 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -1851,8 +1851,6 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct 
dp_packet_batch *batch)
 dropped += batch_cnt - cnt;
 }
 
-dp_packet_batch_apply_cutlen(batch);
-
 for (uint32_t i = 0; i < cnt; i++) {
 struct dp_packet *packet = batch->packets[i];
 uint32_t size = dp_packet_size(packet);
@@ -1905,7 +1903,6 @@ netdev_dpdk_vhost_send(struct netdev *netdev, int qid,
 dpdk_do_tx_copy(netdev, qid, batch);
 dp_packet_delete_batch(batch, true);
 } else {
-dp_packet_batch_apply_cutlen(batch);
 __netdev_dpdk_vhost_send(netdev, qid, batch->packets, batch->count);
 }
 return 0;
@@ -1936,8 +1933,6 @@ netdev_dpdk_send__(struct netdev_dpdk *dev, int qid,
 int batch_cnt = dp_packet_batch_size(batch);
 struct rte_mbuf **pkts = (struct rte_mbuf **) batch->packets;
 
-dp_packet_batch_apply_cutlen(batch);
-
 tx_cnt = netdev_dpdk_filter_packet_len(dev, pkts, batch_cnt);
 tx_cnt = netdev_dpdk_qos_run(dev, pkts, tx_cnt);
 dropped = batch_cnt - tx_cnt;
diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
index 57ef13f..1f846b5 100644
--- a/lib/netdev-dummy.c
+++ b/lib/netdev-dummy.c
@@ -1071,7 +1071,7 @@ netdev_dummy_send(struct netdev *netdev, int qid 
OVS_UNUSED,
 struct dp_packet *packet;
 DP_PACKET_BATCH_FOR_EACH(packet, batch) {
 const void *buffer = dp_packet_data(packet);
-size_t size = dp_packet_get_send_len(packet);
+size_t size = dp_packet_size(packet);
 
 if (batch->packets[i]->packet_type != htonl(PT_ETH)) {
 error = EPFNOSUPPORT;
diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index aaf4899..e70cef3 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -1197,7 +1197,7 @@ netdev_linux_sock_batch_send(int sock, int ifindex,
 for (int i = 0; i < batch->count; i++) {
 struct dp_packet *packet = batch->packets[i];
 iov[i].iov_base = dp_packet_data(packet);
-iov[i].iov_len = dp_packet_get_send_len(packet);
+iov[i].iov_len = dp_packet_size(packet);
 mmsg[i].msg_hdr = (struct msghdr) { .msg_name = ,
 .msg_namelen = sizeof sll,
 .msg_iov = [i],
@@ -1234,7 +1234,7 @@ netdev_linux_tap_batch_send(struct netdev *netdev_,
 struct netdev_linux *netdev = netdev_linux_cast(netdev_);
 for (int i = 0; i < batch->count; i++) {
 struct dp_packet *packet = batch->packets[i];
-size_t size = dp_packet_get_send_len(packet);
+size_t size = dp_packet_size(packet);
 ssize_t retval;
 int error;
 
-- 
2.7.4

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH v4 3/7] netdev: Remove unused may_steal.

2017-10-05 Thread Ilya Maximets
Not needed anymore because 'may_steal' already handled on
dpif-netdev layer and always true;

Signed-off-by: Ilya Maximets 
---
 lib/dpif-netdev.c |  2 +-
 lib/netdev-bsd.c  |  4 ++--
 lib/netdev-dpdk.c | 65 +--
 lib/netdev-dummy.c|  4 ++--
 lib/netdev-linux.c|  4 ++--
 lib/netdev-provider.h |  7 +++---
 lib/netdev.c  | 12 --
 lib/netdev.h  |  2 +-
 8 files changed, 42 insertions(+), 58 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index c6f5c23..166b73a 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -3251,7 +3251,7 @@ dp_netdev_pmd_flush_output_on_port(struct 
dp_netdev_pmd_thread *pmd,
 tx_qid = pmd->static_tx_qid;
 }
 
-netdev_send(p->port->netdev, tx_qid, >output_pkts, true, dynamic_txqs);
+netdev_send(p->port->netdev, tx_qid, >output_pkts, dynamic_txqs);
 dp_packet_batch_init(>output_pkts);
 }
 
diff --git a/lib/netdev-bsd.c b/lib/netdev-bsd.c
index 8a4cdb3..4f243b5 100644
--- a/lib/netdev-bsd.c
+++ b/lib/netdev-bsd.c
@@ -680,7 +680,7 @@ netdev_bsd_rxq_drain(struct netdev_rxq *rxq_)
  */
 static int
 netdev_bsd_send(struct netdev *netdev_, int qid OVS_UNUSED,
-struct dp_packet_batch *batch, bool may_steal,
+struct dp_packet_batch *batch,
 bool concurrent_txq OVS_UNUSED)
 {
 struct netdev_bsd *dev = netdev_bsd_cast(netdev_);
@@ -728,7 +728,7 @@ netdev_bsd_send(struct netdev *netdev_, int qid OVS_UNUSED,
 }
 
 ovs_mutex_unlock(>mutex);
-dp_packet_delete_batch(batch, may_steal);
+dp_packet_delete_batch(batch, true);
 
 return error;
 }
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index c60f46f..011c6f7 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -279,7 +279,7 @@ struct dpdk_qos_ops {
  * For all QoS implementations it should always be non-null.
  */
 int (*qos_run)(struct qos_conf *qos_conf, struct rte_mbuf **pkts,
-   int pkt_cnt, bool may_steal);
+   int pkt_cnt);
 };
 
 /* dpdk_qos_ops for each type of user space QoS implementation */
@@ -1522,8 +1522,7 @@ netdev_dpdk_policer_pkt_handle(struct rte_meter_srtcm 
*meter,
 
 static int
 netdev_dpdk_policer_run(struct rte_meter_srtcm *meter,
-struct rte_mbuf **pkts, int pkt_cnt,
-bool may_steal)
+struct rte_mbuf **pkts, int pkt_cnt)
 {
 int i = 0;
 int cnt = 0;
@@ -1539,9 +1538,7 @@ netdev_dpdk_policer_run(struct rte_meter_srtcm *meter,
 }
 cnt++;
 } else {
-if (may_steal) {
-rte_pktmbuf_free(pkt);
-}
+rte_pktmbuf_free(pkt);
 }
 }
 
@@ -1550,13 +1547,12 @@ netdev_dpdk_policer_run(struct rte_meter_srtcm *meter,
 
 static int
 ingress_policer_run(struct ingress_policer *policer, struct rte_mbuf **pkts,
-int pkt_cnt, bool may_steal)
+int pkt_cnt)
 {
 int cnt = 0;
 
 rte_spinlock_lock(>policer_lock);
-cnt = netdev_dpdk_policer_run(>in_policer, pkts,
-  pkt_cnt, may_steal);
+cnt = netdev_dpdk_policer_run(>in_policer, pkts, pkt_cnt);
 rte_spinlock_unlock(>policer_lock);
 
 return cnt;
@@ -1660,7 +1656,7 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq,
 dropped = nb_rx;
 nb_rx = ingress_policer_run(policer,
 (struct rte_mbuf **) batch->packets,
-nb_rx, true);
+nb_rx);
 dropped -= nb_rx;
 }
 
@@ -1699,7 +1695,7 @@ netdev_dpdk_rxq_recv(struct netdev_rxq *rxq, struct 
dp_packet_batch *batch)
 dropped = nb_rx;
 nb_rx = ingress_policer_run(policer,
 (struct rte_mbuf **) batch->packets,
-nb_rx, true);
+nb_rx);
 dropped -= nb_rx;
 }
 
@@ -1717,14 +1713,13 @@ netdev_dpdk_rxq_recv(struct netdev_rxq *rxq, struct 
dp_packet_batch *batch)
 }
 
 static inline int
-netdev_dpdk_qos_run(struct netdev_dpdk *dev, struct rte_mbuf **pkts,
-int cnt, bool may_steal)
+netdev_dpdk_qos_run(struct netdev_dpdk *dev, struct rte_mbuf **pkts, int cnt)
 {
 struct qos_conf *qos_conf = ovsrcu_get(struct qos_conf *, >qos_conf);
 
 if (qos_conf) {
 rte_spinlock_lock(_conf->lock);
-cnt = qos_conf->ops->qos_run(qos_conf, pkts, cnt, may_steal);
+cnt = qos_conf->ops->qos_run(qos_conf, pkts, cnt);
 rte_spinlock_unlock(_conf->lock);
 }
 
@@ -1797,8 +1792,8 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid,
 rte_spinlock_lock(>tx_q[qid].tx_lock);
 
 cnt = netdev_dpdk_filter_packet_len(dev, cur_pkts, cnt);
-/* Check has QoS has been configured for the netdev */
-cnt = 

[ovs-dev] [PATCH v4 2/7] dpif-netdev: Output packet batching.

2017-10-05 Thread Ilya Maximets
While processing incoming batch of packets they are scattered
across many per-flow batches and sent separately.

This becomes an issue while using more than a few flows.

For example if we have balanced-tcp OvS bonding with 2 ports
there will be 256 datapath internal flows for each dp_hash
pattern. This will lead to scattering of a single recieved
batch across all of that 256 per-flow batches and invoking
send for each packet separately. This behaviour greatly degrades
overall performance of netdev_send because of inability to use
advantages of vectorized transmit functions.
But the half (if 2 ports in bonding) of datapath flows will
have the same output actions. This means that we can collect
them in a single place back and send at once using single call
to netdev_send. This patch introduces per-port packet batch
for output packets for that purpose.

'output_pkts' batch is thread local and located in send port cache.

Signed-off-by: Ilya Maximets 
---
 lib/dpif-netdev.c | 75 +++
 1 file changed, 64 insertions(+), 11 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 1a3d8b4..c6f5c23 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -526,6 +526,7 @@ struct tx_port {
 int qid;
 long long last_used;
 struct hmap_node node;
+struct dp_packet_batch output_pkts;
 };
 
 /* A set of properties for the current processing loop that is not directly
@@ -706,6 +707,9 @@ static void dp_netdev_add_rxq_to_pmd(struct 
dp_netdev_pmd_thread *pmd,
 static void dp_netdev_del_rxq_from_pmd(struct dp_netdev_pmd_thread *pmd,
struct rxq_poll *poll)
 OVS_REQUIRES(pmd->port_mutex);
+static void
+dp_netdev_pmd_flush_output_packets(struct dp_netdev_pmd_thread *pmd);
+
 static void reconfigure_datapath(struct dp_netdev *dp)
 OVS_REQUIRES(dp->port_mutex);
 static bool dp_netdev_pmd_try_ref(struct dp_netdev_pmd_thread *pmd);
@@ -2946,6 +2950,7 @@ dpif_netdev_execute(struct dpif *dpif, struct 
dpif_execute *execute)
 dp_packet_batch_init_packet(, execute->packet);
 dp_netdev_execute_actions(pmd, , false, execute->flow,
   execute->actions, execute->actions_len);
+dp_netdev_pmd_flush_output_packets(pmd);
 
 if (pmd->core_id == NON_PMD_CORE_ID) {
 ovs_mutex_unlock(>non_pmd_mutex);
@@ -3232,6 +3237,36 @@ dp_netdev_rxq_get_intrvl_cycles(struct dp_netdev_rxq 
*rx, unsigned idx)
 return processing_cycles;
 }
 
+static void
+dp_netdev_pmd_flush_output_on_port(struct dp_netdev_pmd_thread *pmd,
+   struct tx_port *p)
+{
+int tx_qid;
+bool dynamic_txqs;
+
+dynamic_txqs = p->port->dynamic_txqs;
+if (dynamic_txqs) {
+tx_qid = dpif_netdev_xps_get_tx_qid(pmd, p);
+} else {
+tx_qid = pmd->static_tx_qid;
+}
+
+netdev_send(p->port->netdev, tx_qid, >output_pkts, true, dynamic_txqs);
+dp_packet_batch_init(>output_pkts);
+}
+
+static void
+dp_netdev_pmd_flush_output_packets(struct dp_netdev_pmd_thread *pmd)
+{
+struct tx_port *p;
+
+HMAP_FOR_EACH (p, node, >send_port_cache) {
+if (!dp_packet_batch_is_empty(>output_pkts)) {
+dp_netdev_pmd_flush_output_on_port(pmd, p);
+}
+}
+}
+
 static int
 dp_netdev_process_rxq_port(struct dp_netdev_pmd_thread *pmd,
struct netdev_rxq *rx,
@@ -3245,9 +3280,11 @@ dp_netdev_process_rxq_port(struct dp_netdev_pmd_thread 
*pmd,
 error = netdev_rxq_recv(rx, );
 if (!error) {
 *recirc_depth_get() = 0;
+pmd_thread_ctx_time_update(pmd);
 
 batch_cnt = batch.count;
 dp_netdev_input(pmd, , port_no);
+dp_netdev_pmd_flush_output_packets(pmd);
 } else if (error != EAGAIN && error != EOPNOTSUPP) {
 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
 
@@ -4711,6 +4748,7 @@ dp_netdev_add_port_tx_to_pmd(struct dp_netdev_pmd_thread 
*pmd,
 
 tx->port = port;
 tx->qid = -1;
+dp_packet_batch_init(>output_pkts);
 
 hmap_insert(>tx_ports, >node, hash_port_no(tx->port->port_no));
 pmd->need_reload = true;
@@ -5168,8 +5206,6 @@ dp_netdev_input__(struct dp_netdev_pmd_thread *pmd,
 size_t n_batches;
 odp_port_t in_port;
 
-pmd_thread_ctx_time_update(pmd);
-
 n_batches = 0;
 emc_processing(pmd, packets, keys, batches, _batches,
 md_is_valid, port_no);
@@ -5383,18 +5419,35 @@ dp_execute_cb(void *aux_, struct dp_packet_batch 
*packets_,
 case OVS_ACTION_ATTR_OUTPUT:
 p = pmd_send_port_cache_lookup(pmd, nl_attr_get_odp_port(a));
 if (OVS_LIKELY(p)) {
-int tx_qid;
-bool dynamic_txqs;
+struct dp_packet *packet;
+struct dp_packet_batch out;
 
-dynamic_txqs = p->port->dynamic_txqs;
-if (dynamic_txqs) {
-tx_qid = dpif_netdev_xps_get_tx_qid(pmd, p);
-  

[ovs-dev] [PATCH v4 1/7] dpif-netdev: Keep latest measured time for PMD thread.

2017-10-05 Thread Ilya Maximets
In current implementation 'now' variable updated once on each
receive cycle and passed through the whole datapath via function
arguments. It'll be better to keep this variable inside PMD
thread structure to be able to get it at any time. Such solution
will save the stack memory and simplify possible modifications
in current logic.

This patch introduces new structure 'dp_netdev_pmd_thread_ctx'
contained by 'struct dp_netdev_pmd_thread' to store any processing
context of this PMD thread. For now, only time and cycles moved to
that structure. Can be extended in the future.

Signed-off-by: Ilya Maximets 
---
 lib/dpif-netdev.c | 129 ++
 1 file changed, 73 insertions(+), 56 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index d5eb830..1a3d8b4 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -528,6 +528,19 @@ struct tx_port {
 struct hmap_node node;
 };
 
+/* A set of properties for the current processing loop that is not directly
+ * associated with the pmd thread itself, but with the packets being
+ * processed or the short-term system configuration (for example, time).
+ * Contained by struct dp_netdev_pmd_thread's 'ctx' member. */
+struct dp_netdev_pmd_thread_ctx {
+/* Latest measured time. */
+long long now;
+/* Used to count cycles. See 'cycles_count_end()' */
+unsigned long long last_cycles;
+};
+
+static void pmd_thread_ctx_time_update(struct dp_netdev_pmd_thread *);
+
 /* PMD: Poll modes drivers.  PMD accesses devices via polling to eliminate
  * the performance overhead of interrupt processing.  Therefore netdev can
  * not implement rx-wait for these devices.  dpif-netdev needs to poll
@@ -583,8 +596,8 @@ struct dp_netdev_pmd_thread {
 /* Cycles counters */
 struct dp_netdev_pmd_cycles cycles;
 
-/* Used to count cicles. See 'cycles_counter_end()' */
-unsigned long long last_cycles;
+/* Current context of the PMD thread. */
+struct dp_netdev_pmd_thread_ctx ctx;
 
 struct latch exit_latch;/* For terminating the pmd thread. */
 struct seq *reload_seq;
@@ -657,8 +670,7 @@ static void dp_netdev_execute_actions(struct 
dp_netdev_pmd_thread *pmd,
   struct dp_packet_batch *,
   bool may_steal, const struct flow *flow,
   const struct nlattr *actions,
-  size_t actions_len,
-  long long now);
+  size_t actions_len);
 static void dp_netdev_input(struct dp_netdev_pmd_thread *,
 struct dp_packet_batch *, odp_port_t port_no);
 static void dp_netdev_recirculate(struct dp_netdev_pmd_thread *,
@@ -718,9 +730,9 @@ static uint64_t
 dp_netdev_rxq_get_intrvl_cycles(struct dp_netdev_rxq *rx, unsigned idx);
 static void
 dpif_netdev_xps_revalidate_pmd(const struct dp_netdev_pmd_thread *pmd,
-   long long now, bool purge);
+   bool purge);
 static int dpif_netdev_xps_get_tx_qid(const struct dp_netdev_pmd_thread *pmd,
-  struct tx_port *tx, long long now);
+  struct tx_port *tx);
 
 static inline bool emc_entry_alive(struct emc_entry *ce);
 static void emc_clear_entry(struct emc_entry *ce);
@@ -764,6 +776,12 @@ emc_cache_slow_sweep(struct emc_cache *flow_cache)
 flow_cache->sweep_idx = (flow_cache->sweep_idx + 1) & EM_FLOW_HASH_MASK;
 }
 
+static inline void
+pmd_thread_ctx_time_update(struct dp_netdev_pmd_thread *pmd)
+{
+pmd->ctx.now = time_msec();
+}
+
 /* Returns true if 'dpif' is a netdev or dummy dpif, false otherwise. */
 bool
 dpif_is_netdev(const struct dpif *dpif)
@@ -2912,6 +2930,9 @@ dpif_netdev_execute(struct dpif *dpif, struct 
dpif_execute *execute)
 ovs_mutex_lock(>non_pmd_mutex);
 }
 
+/* Update current time in PMD context. */
+pmd_thread_ctx_time_update(pmd);
+
 /* The action processing expects the RSS hash to be valid, because
  * it's always initialized at the beginning of datapath processing.
  * In this case, though, 'execute->packet' may not have gone through
@@ -2924,8 +2945,7 @@ dpif_netdev_execute(struct dpif *dpif, struct 
dpif_execute *execute)
 
 dp_packet_batch_init_packet(, execute->packet);
 dp_netdev_execute_actions(pmd, , false, execute->flow,
-  execute->actions, execute->actions_len,
-  time_msec());
+  execute->actions, execute->actions_len);
 
 if (pmd->core_id == NON_PMD_CORE_ID) {
 ovs_mutex_unlock(>non_pmd_mutex);
@@ -3146,7 +3166,7 @@ cycles_count_start(struct dp_netdev_pmd_thread *pmd)
 OVS_ACQUIRES(_counter_fake_mutex)
 OVS_NO_THREAD_SAFETY_ANALYSIS
 {
-pmd->last_cycles = cycles_counter();
+

[ovs-dev] [PATCH v4 0/7] Output packet batching.

2017-10-05 Thread Ilya Maximets
This patch-set inspired by [1] from Bhanuprakash Bodireddy.
Implementation of [1] looks very complex and introduces many pitfalls [2]
for later code modifications like possible packet stucks.

This version targeted to make simple and flexible output packet batching on
higher level without introducing and even simplifying netdev layer.

Basic testing of 'PVP with OVS bonding on phy ports' scenario shows
significant performance improvement.

Test results for time-based batching for v3:
https://mail.openvswitch.org/pipermail/ovs-dev/2017-September/338247.html

[1] [PATCH v4 0/5] netdev-dpdk: Use intermediate queue during packet 
transmission.
https://mail.openvswitch.org/pipermail/ovs-dev/2017-August/337019.html

[2] For example:
https://mail.openvswitch.org/pipermail/ovs-dev/2017-August/337133.html

Version 4:
* Rebased on current master.
* Rebased on top of "Keep latest measured time for PMD thread."
  (Jan Scheurich)
* Microsecond resolution related patches integrated.
* Time-based batching without RFC tag.
* 'output_time' renamed to 'flush_time'. (Jan Scheurich)
* 'flush_time' update moved to 'dp_netdev_pmd_flush_output_on_port'.
  (Jan Scheurich)
* 'output-max-latency' renamed to 'tx-flush-interval'.
* Added patch for output batching statistics.

Version 3:

* Rebased on current master.
* Time based RFC: fixed assert on n_output_batches <= 0.

Version 2:

* Rebased on current master.
* Added time based batching RFC patch.
* Fixed mixing packets with different sources in same batch.


Ilya Maximets (7):
  dpif-netdev: Keep latest measured time for PMD thread.
  dpif-netdev: Output packet batching.
  netdev: Remove unused may_steal.
  netdev: Remove useless cutlen.
  timeval: Introduce time_usec().
  dpif-netdev: Time based output batching.
  dpif-netdev: Count sent packets and batches.

 lib/dpif-netdev.c | 334 +-
 lib/netdev-bsd.c  |   6 +-
 lib/netdev-dpdk.c |  70 ---
 lib/netdev-dummy.c|   6 +-
 lib/netdev-linux.c|   8 +-
 lib/netdev-provider.h |   7 +-
 lib/netdev.c  |  12 +-
 lib/netdev.h  |   2 +-
 lib/timeval.c |  22 
 lib/timeval.h |   2 +
 vswitchd/vswitch.xml  |  16 +++
 11 files changed, 336 insertions(+), 149 deletions(-)

-- 
2.7.4

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


Re: [ovs-dev] [PATCH v2 1/4] netdev-dpdk: fix mempool management with vhu client.

2017-10-05 Thread Fischetti, Antonio
I'll rework this patch and post a V3.

Thanks,
Antonio

> -Original Message-
> From: ovs-dev-boun...@openvswitch.org [mailto:ovs-dev-boun...@openvswitch.org]
> On Behalf Of Fischetti, Antonio
> Sent: Tuesday, October 3, 2017 4:25 PM
> To: Kevin Traynor ; d...@openvswitch.org
> Subject: Re: [ovs-dev] [PATCH v2 1/4] netdev-dpdk: fix mempool management with
> vhu client.
> 
> Thanks Kevin for your feedback.
> Below some details on what happens, how to replicate the issue and
> some comments inline.
> 
> -Antonio
> 
> > -Original Message-
> > From: Kevin Traynor [mailto:ktray...@redhat.com]
> > Sent: Monday, October 2, 2017 6:38 PM
> > To: Fischetti, Antonio ; d...@openvswitch.org
> > Cc: Aaron Conole 
> > Subject: Re: [PATCH v2 1/4] netdev-dpdk: fix mempool management with vhu
> > client.
> >
> > On 09/28/2017 03:28 PM, antonio.fische...@intel.com wrote:
> > > From: Antonio Fischetti 
> > >
> > > In a PVP test where vhostuser ports are configured as
> > > clients, OvS crashes when QEMU is launched.
> > > This patch avoids the repeated calls to netdev_change_seq_changed
> > > after the requested mempool is already acquired.
> > >
> >
> > Can you explain what is happening in this bug? I can't reproduce it
> 
> [Antonio]
> When QEMU is being launched, ovs crashes with the following stacktrace:
> https://mail.openvswitch.org/pipermail/ovs-dev/2017-September/339343.html
> 
> In case the requested mempool already exists, netdev_dpdk_mempool_configure
> returns 0 => netdev_change_seq_changed is called.
> 
> The issue happens with vhostuser 'client' ports:
>  - the vhu ports must be of dpdkvhostuserclient type
>  - so the QEMU command must contain 'server' like
>qemu-system-x86_64  path=$CLIENT_SOCK_DIR/$SOCK0,server
> 
> Below other details on my setup.
> 
>   1 PMD
>   -
> ovs-vsctl --no-wait set Open_vSwitch . other_config:pmd-cpu-mask=8
> 
>   Ports
>   -
> ovs-vsctl add-port br0 dpdk0 -- set Interface dpdk0 type=dpdk options:dpdk-
> devargs=$NIC0
> ovs-vsctl add-port br0 dpdk0 -- set Interface dpdk1 type=dpdk options:dpdk-
> devargs=$NIC1
> 
> ovs-vsctl add-port br0 dpdkvhostuser0 -- set Interface dpdkvhostuser0
> type=dpdkvhostuserclient
> ovs-vsctl set Interface dpdkvhostuser0 options:vhost-server-
> path="/tmp/dpdkvhostuser0"
> 
> ovs-vsctl add-port br0 dpdkvhostuser1 -- set Interface dpdkvhostuser1
> type=dpdkvhostuserclient
> ovs-vsctl set Interface dpdkvhostuser1 options:vhost-server-
> path="/tmp/dpdkvhostuser1"
> 
> 
> I'm using DPDK v17.05 and QEMU v2.7.0.
> 
> 
> Other details are below right after the patch description.
> 
> 
> 
> > and
> > the mempool for vhost ports should only be reconfigured if the number of
> > queues or socket has changed.
> >
> > > CC: Kevin Traynor 
> > > CC: Aaron Conole 
> > > Reported-by: Ciara Loftus 
> > > Fixes: d555d9bded5f ("netdev-dpdk: Create separate memory pool for each
> > port.")
> > > Signed-off-by: Antonio Fischetti 
> > > ---
> > > To replicate the bug scenario:
> > >
> > >  PVP test setup
> > >  --
> > > CLIENT_SOCK_DIR=/tmp
> > > SOCK0=dpdkvhostuser0
> > > SOCK1=dpdkvhostuser1
> > >
> > > 1 PMD
> > > Add 2 dpdk ports, n_rxq=1
> > > Add 2 vhu ports both of type dpdkvhostuserclient and specify vhost-server-
> > path
> > >  ovs-vsctl set Interface dpdkvhostuser0 options:vhost-server-
> > path="$CLIENT_SOCK_DIR/$SOCK0"
> > >  ovs-vsctl set Interface dpdkvhostuser1 options:vhost-server-
> > path="$CLIENT_SOCK_DIR/$SOCK1"
> > >
> > > Set port-based rules: dpdk0 <--> vhu0 and dpdk1 <--> vhu1
> > >  add-flow br0 in_port=1,action=output:3
> > >  add-flow br0 in_port=3,action=output:1
> > >  add-flow br0 in_port=4,action=output:2
> > >  add-flow br0 in_port=2,action=output:4
> > >
> > >  Launch QEMU
> > >  ---
> > > As OvS vhu ports are acting as clients, we must specify 'server' in the
> next
> > command.
> > > VM_IMAGE=
> > >
> > >  sudo -E taskset 0x3F00 $QEMU_DIR/x86_64-softmmu/qemu-system-x86_64 -name
> us-
> > vhost-vm1 -cpu host -enable-kvm -m 4096M -object memory-backend-
> > file,id=mem,size=4096M,mem-path=/dev/hugepages,share=on -numa 
> > node,memdev=mem
> -
> > mem-prealloc -smp 4 -drive file=$VM_IMAGE -chardev
> > socket,id=char0,path=$CLIENT_SOCK_DIR/$SOCK0,server -netdev type=vhost-
> > user,id=mynet1,chardev=char0,vhostforce -device virtio-net-
> > pci,mac=00:00:00:00:00:01,netdev=mynet1,mrg_rxbuf=off -chardev
> > socket,id=char1,path=$CLIENT_SOCK_DIR/$SOCK1,server -netdev type=vhost-
> > user,id=mynet2,chardev=char1,vhostforce -device virtio-net-
> > pci,mac=00:00:00:00:00:02,netdev=mynet2,mrg_rxbuf=off --nographic
> > >
> > >  Expected behavior
> > >  -
> > > With this fix OvS shouldn't crash.
> > > ---
> > >  lib/netdev-dpdk.c | 12 
> > >  1 file changed, 8 insertions(+), 4