[dpdk-dev] [PATCH 2/5] cxgbe: add cxgbe poll mode driver.

2015-05-26 Thread Rahul Lakkireddy
On Tue, May 26, 2015 at 10:24:37 -0700, Stephen Hemminger wrote:
> On Tue, 26 May 2015 22:32:07 +0530
> Rahul Lakkireddy  wrote:
> 
> > On Sat, May 23, 2015 at 11:27:56 +0530, Rahul Lakkireddy wrote:
> > > On Fri, May 22, 2015 at 09:42:50 -0700, Stephen Hemminger wrote:
> > > > On Fri, 22 May 2015 18:54:20 +0530
> > > > Rahul Lakkireddy  wrote:
> > > > 
[...]

> > > > 
> > > > This is not Linux kernel.
> > > > Please don't create wrappers for all the stuff in Linux to port your 
> > > > driver.
> > > 
> > > We actually referred several PMD's compat file including - enic_compat.h,
> > > i40e_osdep.h, ixgbe_osdep.h, fm10k_osdep.h, etc.
> > > 
> > > Most of the types above are already defined by many of existing PMD's 
> > > compat
> > > file.  Can we at-least keep those which are already defined by several 
> > > PMD's
> > > compat file?
> > 
> > Just to give a background - since we are new to dpdk community, we studied 
> > the
> > already merged PMD's compat files as reference to understand how things are
> > done for driver submission. And so, we wrote cxgbe compat file along similar
> > lines. However, if above wrappers are not acceptable then, we will 
> > definitely
> > remove them in V2.
> > 
> > Just trying to get a clarification so that we don't repeat the same mistake 
> > in
> > V2 submission. Reviews from you and dpdk community are more than welcome and
> > appreciated.
> 
> Does this driver share source code with other platforms?

Yes. The h/w specific code is common to Linux and FBSD.
And we will be enabling FBSD support soon after this PMD gets merged and we are
able to carry out and complete testing on FBSD.


> If it does then the compatibility wrappers make sense and reduce the
> maintenance effort.
> If the driver is a standalone port to DPDK, then it makes sense to complete
> the effort and use standard DPDK coding practices (stdint, stdbool, etc).
> 
> The other drivers in DPDK do things based on that. Many of the hardware
> drivers share code with BSD. Others like the virtual drivers were written
> or ported completely from scratch.
>

Thank you for your guidance.



[dpdk-dev] [PATCH 2/5] cxgbe: add cxgbe poll mode driver.

2015-05-26 Thread Thomas Monjalon
2015-05-23 11:23, Rahul Lakkireddy:
> We need to rebase anyway since PMDs now seem to have moved to
> drivers/net directory.

Yes. And the subdirectory should probably be renamed base/.

It would be nice to introduce the PMD features in separate patches
as it was done for fm10k.

Thanks


[dpdk-dev] [PATCH 2/5] cxgbe: add cxgbe poll mode driver.

2015-05-26 Thread Rahul Lakkireddy
On Sat, May 23, 2015 at 11:27:56 +0530, Rahul Lakkireddy wrote:
> On Fri, May 22, 2015 at 09:42:50 -0700, Stephen Hemminger wrote:
> > On Fri, 22 May 2015 18:54:20 +0530
> > Rahul Lakkireddy  wrote:
> > 
> > > +#define pr_err(y, args...) dev_err(0, y, ##args)
> > > +#define pr_warn(y, args...) dev_warn(0, y, ##args)
> > > +#define pr_info(y, args...) dev_info(0, y, ##args)
> > > +#define BUG() pr_err("BUG at %s:%d", __func__, __LINE__)
> > > +
> > > +#define ASSERT(x) do {\
> > > + if (!(x)) \
> > > + rte_panic("CXGBE: x"); \
> > > +} while (0)
> > > +#define BUG_ON(x) ASSERT(!(x))
> > > +
> > > +#ifndef WARN_ON
> > > +#define WARN_ON(x) do { \
> > > + int ret = !!(x); \
> > > + if (unlikely(ret)) \
> > > + pr_warn("WARN_ON: \"" #x "\" at %s:%d\n", __func__, __LINE__); \
> > > +} while (0)
> > > +#endif
> > > +
> > > +#define __iomem
> > > +
> > > +#ifndef BIT
> > > +#define BIT(n) (1 << (n))
> > > +#endif
> > > +
> > > +#define L1_CACHE_SHIFT  6
> > > +#define L1_CACHE_BYTES  BIT(L1_CACHE_SHIFT)
> > > +
> > > +#define PAGE_SHIFT  12
> > > +#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
> > > +#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
> > > +
> > > +#define VLAN_HLEN 4
> > > +
> > > +#define rmb() rte_rmb() /* dpdk rte provided rmb */
> > > +#define wmb() rte_wmb() /* dpdk rte provided wmb */
> > > +
> > > +typedef uint8_t   u8;
> > > +typedef int8_ts8;
> > > +typedef uint16_t  u16;
> > > +typedef uint32_t  u32;
> > > +typedef int32_t   s32;
> > > +typedef uint64_t  u64;
> > > +typedef int   bool;
> > > +typedef uint64_t  dma_addr_t;
> > > +
> > > +#ifndef __le16
> > > +#define __le16   uint16_t
> > > +#endif
> > > +#ifndef __le32
> > > +#define __le32   uint32_t
> > > +#endif
> > > +#ifndef __le64
> > > +#define __le64   uint64_t
> > > +#endif
> > > +#ifndef __be16
> > > +#define __be16   uint16_t
> > > +#endif
> > > +#ifndef __be32
> > > +#define __be32   uint32_t
> > > +#endif
> > > +#ifndef __be64
> > > +#define __be64   uint64_t
> > > +#endif
> > > +#ifndef __u8
> > > +#define __u8 uint8_t
> > > +#endif
> > > +#ifndef __u16
> > > +#define __u16uint16_t
> > > +#endif
> > > +#ifndef __u32
> > > +#define __u32uint32_t
> > > +#endif
> > > +#ifndef __u64
> > > +#define __u64uint64_t
> > > +#endif
> > > +
> > > +#define FALSE0
> > > +#define TRUE 1
> > > +#define false0
> > > +#define true 1
> > > +
> > > +#define min(a, b) RTE_MIN(a, b)
> > > +#define max(a, b) RTE_MAX(a, b)
> > 
> > This is not Linux kernel.
> > Please don't create wrappers for all the stuff in Linux to port your driver.
> 
> We actually referred several PMD's compat file including - enic_compat.h,
> i40e_osdep.h, ixgbe_osdep.h, fm10k_osdep.h, etc.
> 
> Most of the types above are already defined by many of existing PMD's compat
> file.  Can we at-least keep those which are already defined by several PMD's
> compat file?

Just to give a background - since we are new to dpdk community, we studied the
already merged PMD's compat files as reference to understand how things are
done for driver submission. And so, we wrote cxgbe compat file along similar
lines. However, if above wrappers are not acceptable then, we will definitely
remove them in V2.

Just trying to get a clarification so that we don't repeat the same mistake in
V2 submission. Reviews from you and dpdk community are more than welcome and
appreciated.


Thanks,
Rahul.


[dpdk-dev] [PATCH v3] pipeline: add statistics for librte_pipeline ports and tables

2015-05-26 Thread Dumitrescu, Cristian


> -Original Message-
> From: Stephen Hemminger [mailto:stephen at networkplumber.org]
> Sent: Tuesday, May 26, 2015 10:48 PM
> To: Dumitrescu, Cristian
> Cc: Gajdzica, MaciejX T; dev at dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v3] pipeline: add statistics for 
> librte_pipeline
> ports and tables
> 
> On Tue, 26 May 2015 21:35:22 +
> "Dumitrescu, Cristian"  wrote:
> 
> >
> >
> > > -Original Message-
> > > From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Stephen
> > > Hemminger
> > > Sent: Tuesday, May 26, 2015 3:57 PM
> > > To: Gajdzica, MaciejX T
> > > Cc: dev at dpdk.org
> > > Subject: Re: [dpdk-dev] [PATCH v3] pipeline: add statistics for
> librte_pipeline
> > > ports and tables
> > >
> > > On Tue, 26 May 2015 15:39:18 +0200
> > > Maciej Gajdzica  wrote:
> > >
> > > > +#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
> > > > +#define RTE_PIPELINE_STATS_ADD(counter, val) \
> > > > +   ({ (counter) += (val); })
> > > > +
> > > > +#define RTE_PIPELINE_STATS_ADD_M(counter, mask) \
> > > > +   ({ (counter) += __builtin_popcountll(mask); })
> > > > +#else
> > > > +#define RTE_PIPELINE_STATS_ADD(counter, val)
> > > > +#define RTE_PIPELINE_STATS_ADD_M(counter, mask)
> > > > +#endif
> > >
> > > This is worse idea than the previous one.
> > > I want statistics done on a per lcore basis, and always available
> > > because real users on production system want statistics (but they
> > > don't want log spam).
> >
> > Stephen,
> >
> > Thomas and myself converged towards this solution, Thomas asked if
> anybody objects, you did not (http://www.dpdk.org/ml/archives/dev/2015-
> May/018099.html) . You say this idea is bad, but what exactly is your
> objection? Do you have an alternative proposal?
> 
> Yes. Always keep statistics.
> 
> We use functions like this internally.
> 
> struct xxx_stats {
>   uint64_t mib[XXX_MIB_MAX];
> };
> extern struct xxx_stats xxx_stats[RTE_MAX_LCORE];
> 
> #define XXXSTAT_INC(type) xxxstats[rte_lcore_id()].mibs[type]++
> 
> 

This can only be applied if stats are always enabled. I know this is your 
preferred choice, but other people have the requirement to be able to have the 
stats collection configurable, and we should also accommodate the needs of 
those people. Your code snippet does not provide a solution for this problem.

> > You already mentioned in the previous thread you would like to have per
> lcore statistics. I was kindly asking you to describe your idea, but you did 
> not
> do this yet (http://www.dpdk.org/ml/archives/dev/2015-May/017956.html ).
> Can you please describe it? Each port instance has its own statistics 
> counters.
> Each lcore can run one or more pipeline instances, therefore each lcore
> typically runs several port instances of the same or different type (each port
> instance with its own statistics), so how is "per lcore stats" requirement
> applicable here?
> 
> I thought you were familiar with technique of having per-cpu structures and
> variables
> widely used in Linux kernel to prevent cache thrashing. Although you call it
> false sharing,
> it isn't false., it happens when same counter ping-pongs between multiple
> threads for
> no added benefit.

The "per lcore stats" is applicable to stats structures that are accessed by 
more than one lcore. In our case, each port instance is handled by a single 
lcore, so it is never the case that two lcores would access the stats of the 
same port instance. So, we can safely say that port stats are "per lcore" 
already.

> 
> 
> > You also reiterate that you would like to have the stats always enabled. You
> can definitely do this, it is one of the available choices, but why not also
> accommodate the users that want to pick the opposite choice? Why force
> apps to spend cycles on stats if the app either does not want these counters
> (library counters not relevant for that app, maybe the app is only interested
> in maintaining some other stats that it implements itself) or do not want
> them anymore (maybe they only needed them during debug phase), etc?
> Jay asked this question, and I did my best in my reply to describe our
> motivation (http://www.dpdk.org/ml/archives/dev/2015-May/017992.html).
> Maybe you missed that post, it would be good to get your reply on this one
> too.
> 
> I want to see DPDK get out of the config madness.
> This is real code, not an Intel benchmark special.

You seem to make this assumption that our real reason for having the stats 
collection configurable is to get good benchmark results by disabling the 
stats. This cannot be a real reason, as a complete benchmark reports always 
specifies if stats were enabled or not. Easy to check.

By stating this, you implicitly acknowledge that stats collection consumes CPU 
cycles that might be significant for the overall app performance, right? So why 
waste CPU cycles in the case when the app does not need those counters?

The message I am trying to get across to you is that there are multiple _real_ 
reasons w

[dpdk-dev] [PATCH v2 2/2] Filling speed capability bitmaps in the PMDs

2015-05-26 Thread Marc Sune
Added speed capabilities to all pmds supporting physical NICs:

* e1000
* ixgbe
* i40
* mlx4
* fm10k

Signed-off-by: Marc Sune 
---
 drivers/net/e1000/em_ethdev.c|  6 ++
 drivers/net/e1000/igb_ethdev.c   |  6 ++
 drivers/net/fm10k/fm10k_ethdev.c |  3 +++
 drivers/net/i40e/i40e_ethdev.c   |  9 +
 drivers/net/ixgbe/ixgbe_ethdev.c | 10 ++
 drivers/net/mlx4/mlx4.c  |  6 ++
 6 files changed, 40 insertions(+)

diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index d28030e..8e25cfa 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -883,6 +883,12 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)

dev_info->max_rx_queues = 1;
dev_info->max_tx_queues = 1;
+
+   dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
+   ETH_SPEED_CAP_10M_FD |
+   ETH_SPEED_CAP_100M_HD |
+   ETH_SPEED_CAP_100M_FD |
+   ETH_SPEED_CAP_1G;
 }

 /* return 0 means link status changed, -1 means not changed */
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index e4b370d..424ad6f 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1398,6 +1398,12 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
},
.txq_flags = 0,
};
+
+   dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
+   ETH_SPEED_CAP_10M_FD |
+   ETH_SPEED_CAP_100M_HD |
+   ETH_SPEED_CAP_100M_FD |
+   ETH_SPEED_CAP_1G;
 }

 static void
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 275c19c..e97b857 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -791,6 +791,9 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
ETH_TXQ_FLAGS_NOOFFLOADS,
};

+   dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_2_5G |
+   ETH_SPEED_CAP_10G | ETH_SPEED_CAP_25G |
+   ETH_SPEED_CAP_40G | ETH_SPEED_CAP_100G;
 }

 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index fb64027..5e9db6b 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1519,6 +1519,7 @@ static void
 i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+   struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct i40e_vsi *vsi = pf->main_vsi;

dev_info->max_rx_queues = vsi->nb_qps;
@@ -1574,6 +1575,14 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
dev_info->max_rx_queues += dev_info->vmdq_queue_num;
dev_info->max_tx_queues += dev_info->vmdq_queue_num;
}
+
+   if (i40e_is_40G_device(hw->device_id))
+   /* For XL710 */
+   dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+   else
+   /* For X710 */
+   dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
+
 }

 static int
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 0d9f9b2..78b13a8 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2054,6 +2054,16 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
};
dev_info->reta_size = ETH_RSS_RETA_SIZE_128;
dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
+
+   dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+
+   if (hw->mac.type == ixgbe_mac_X540 ||
+   hw->mac.type == ixgbe_mac_X540_vf ||
+   hw->mac.type == ixgbe_mac_X550 ||
+   hw->mac.type == ixgbe_mac_X550_vf)
+
+   dev_info->speed_capa |= ETH_SPEED_CAP_100M_FD |
+   ETH_SPEED_CAP_100M_HD;
 }

 static void
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index f915bc1..d4442fb 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -3482,6 +3482,12 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *info)
info->max_rx_queues = max;
info->max_tx_queues = max;
info->max_mac_addrs = elemof(priv->mac);
+
+   info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_20G |
+   ETH_SPEED_CAP_25G | ETH_SPEED_CAP_40G |
+   ETH_SPEED_CAP_50G | ETH_SPEED_CAP_56G |
+   ETH_SPEED_CAP_100G;
+
  

[dpdk-dev] [PATCH v2 1/2] Added ETH_SPEED_CAP bitmap in rte_eth_dev_info

2015-05-26 Thread Marc Sune
Added constants and bitmap to struct rte_eth_dev_info to be used by PMDs.

Signed-off-by: Marc Sune 
---
 lib/librte_ether/rte_ethdev.h | 24 
 1 file changed, 24 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 16dbe00..f57676b 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -900,6 +900,29 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_UDP_TSO 0x0040
 #define DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM 0x0080 /**< Used for tunneling 
packet. */

+/**
+ * Device supported speeds
+ */
+#define ETH_SPEED_CAP_NOT_PHY  (0)  /*< No phy media > */
+#define ETH_SPEED_CAP_10M_HD   (1 << 0)  /*< 10 Mbps half-duplex> */
+#define ETH_SPEED_CAP_10M_FD   (1 << 1)  /*< 10 Mbps full-duplex> */
+#define ETH_SPEED_CAP_100M_HD  (1 << 2)  /*< 100 Mbps half-duplex> */
+#define ETH_SPEED_CAP_100M_FD  (1 << 3)  /*< 100 Mbps full-duplex> */
+#define ETH_SPEED_CAP_1G   (1 << 4)  /*< 1 Gbps > */
+#define ETH_SPEED_CAP_2_5G (1 << 5)  /*< 2.5 Gbps > */
+#define ETH_SPEED_CAP_5G   (1 << 6)  /*< 5 Gbps > */
+#define ETH_SPEED_CAP_10G  (1 << 7)  /*< 10 Mbps > */
+#define ETH_SPEED_CAP_20G  (1 << 8)  /*< 20 Gbps > */
+#define ETH_SPEED_CAP_25G  (1 << 9)  /*< 25 Gbps > */
+#define ETH_SPEED_CAP_40G  (1 << 10)  /*< 40 Gbps > */
+#define ETH_SPEED_CAP_50G  (1 << 11)  /*< 50 Gbps > */
+#define ETH_SPEED_CAP_56G  (1 << 12)  /*< 56 Gbps > */
+#define ETH_SPEED_CAP_100G (1 << 13)  /*< 100 Gbps > */
+
+
+/**
+ * Ethernet device information
+ */
 struct rte_eth_dev_info {
struct rte_pci_device *pci_dev; /**< Device PCI information. */
const char *driver_name; /**< Device Driver name. */
@@ -925,6 +948,7 @@ struct rte_eth_dev_info {
uint16_t vmdq_queue_base; /**< First queue ID for VMDQ pools. */
uint16_t vmdq_queue_num;  /**< Queue number for VMDQ pools. */
uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
+   uint32_t speed_capa;  /**< Supported speeds bitmap (ETH_SPEED_CAP_). */
 };

 /** Maximum name length for extended statistics counters */
-- 
2.1.4



[dpdk-dev] [PATCH v2 0/2] ethdev: add port speed capability bitmap

2015-05-26 Thread Marc Sune
The current rte_eth_dev_info abstraction does not provide any mechanism to
get the supported speed(s) of an ethdev.

For some drivers (e.g. ixgbe), an educated guess can be done based on the
driver's name (driver_name in rte_eth_dev_info), see:

http://dpdk.org/ml/archives/dev/2013-August/000412.html

However, i) doing string comparisons is annoying, and can silently
break existing applications if PMDs change their names ii) it does not
provide all the supported capabilities of the ethdev iii) for some drivers it
is impossible determine correctly the (max) speed by the application
(e.g. in i40, distinguish between XL710 and X710).

This small patch adds speed_capa bitmap in rte_eth_dev_info, which is filled
by the PMDs according to the physical device capabilities.

v2: rebase, converted speed_capa into 32 bits bitmap, fixed alignment
(checkpatch).

Marc Sune (2):
  Added ETH_SPEED_CAP bitmap in rte_eth_dev_info
  Filling speed capability bitmaps in the PMDs

 drivers/net/e1000/em_ethdev.c|  6 ++
 drivers/net/e1000/igb_ethdev.c   |  6 ++
 drivers/net/fm10k/fm10k_ethdev.c |  3 +++
 drivers/net/i40e/i40e_ethdev.c   |  9 +
 drivers/net/ixgbe/ixgbe_ethdev.c | 10 ++
 drivers/net/mlx4/mlx4.c  |  6 ++
 lib/librte_ether/rte_ethdev.h| 24 
 7 files changed, 64 insertions(+)

-- 
2.1.4



[dpdk-dev] [PATCH v3 01/10] table: added structure for storing table stats

2015-05-26 Thread Dumitrescu, Cristian


> -Original Message-
> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Stephen
> Hemminger
> Sent: Tuesday, May 26, 2015 3:58 PM
> To: Gajdzica, MaciejX T
> Cc: dev at dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v3 01/10] table: added structure for storing
> table stats
> 
> On Tue, 26 May 2015 14:39:38 +0200
> Maciej Gajdzica  wrote:
> 
> > +
> >  /** Lookup table interface defining the lookup table operation */
> >  struct rte_table_ops {
> > rte_table_op_create f_create;   /**< Create */
> > @@ -194,6 +218,7 @@ struct rte_table_ops {
> > rte_table_op_entry_add f_add;   /**< Entry add */
> > rte_table_op_entry_delete f_delete; /**< Entry delete */
> > rte_table_op_lookup f_lookup;   /**< Lookup */
> > +   rte_table_op_stats_read f_stats;/**< Stats */
> >  };
> 
> Another good idea, which is an ABI change.

This is simply adding a new API function, this is not changing any function 
prototype. There is no change required in the map file of this library. Is 
there anything we should have done and we did not do?



[dpdk-dev] [PATCH v3] pipeline: add statistics for librte_pipeline ports and tables

2015-05-26 Thread Dumitrescu, Cristian


> -Original Message-
> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Stephen
> Hemminger
> Sent: Tuesday, May 26, 2015 3:57 PM
> To: Gajdzica, MaciejX T
> Cc: dev at dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v3] pipeline: add statistics for 
> librte_pipeline
> ports and tables
> 
> On Tue, 26 May 2015 15:39:18 +0200
> Maciej Gajdzica  wrote:
> 
> > +#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
> > +#define RTE_PIPELINE_STATS_ADD(counter, val) \
> > +   ({ (counter) += (val); })
> > +
> > +#define RTE_PIPELINE_STATS_ADD_M(counter, mask) \
> > +   ({ (counter) += __builtin_popcountll(mask); })
> > +#else
> > +#define RTE_PIPELINE_STATS_ADD(counter, val)
> > +#define RTE_PIPELINE_STATS_ADD_M(counter, mask)
> > +#endif
> 
> This is worse idea than the previous one.
> I want statistics done on a per lcore basis, and always available
> because real users on production system want statistics (but they
> don't want log spam).

Stephen,

Thomas and myself converged towards this solution, Thomas asked if anybody 
objects, you did not (http://www.dpdk.org/ml/archives/dev/2015-May/018099.html) 
. You say this idea is bad, but what exactly is your objection? Do you have an 
alternative proposal?

You already mentioned in the previous thread you would like to have per lcore 
statistics. I was kindly asking you to describe your idea, but you did not do 
this yet (http://www.dpdk.org/ml/archives/dev/2015-May/017956.html ). Can you 
please describe it? Each port instance has its own statistics counters. Each 
lcore can run one or more pipeline instances, therefore each lcore typically 
runs several port instances of the same or different type (each port instance 
with its own statistics), so how is "per lcore stats" requirement applicable 
here?

You also reiterate that you would like to have the stats always enabled. You 
can definitely do this, it is one of the available choices, but why not also 
accommodate the users that want to pick the opposite choice? Why force apps to 
spend cycles on stats if the app either does not want these counters (library 
counters not relevant for that app, maybe the app is only interested in 
maintaining some other stats that it implements itself) or do not want them 
anymore (maybe they only needed them during debug phase), etc? Jay asked this 
question, and I did my best in my reply to describe our motivation 
(http://www.dpdk.org/ml/archives/dev/2015-May/017992.html). Maybe you missed 
that post, it would be good to get your reply on this one too.

Thanks,
Cristian



[dpdk-dev] [RFC PATCH 1/2] Added ETH_SPEED_CAP bitmap in rte_eth_dev_info

2015-05-26 Thread Marc Sune


On 26/05/15 17:03, Stephen Hemminger wrote:
> On Tue, 12 May 2015 01:45:45 +0200
> Marc Sune  wrote:
>
>> +/**
>> + * Ethernet device information
>> + */
>>   struct rte_eth_dev_info {
>>  struct rte_pci_device *pci_dev; /**< Device PCI information. */
>>  const char *driver_name; /**< Device Driver name. */
>> @@ -924,6 +947,7 @@ struct rte_eth_dev_info {
>>  uint16_t vmdq_queue_base; /**< First queue ID for VMDQ pools. */
>>  uint16_t vmdq_queue_num;  /**< Queue number for VMDQ pools. */
>>  uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
>> +uint16_t speed_capa;  /**< Supported speeds bitmap. */
>>   };
>>   
> Since you are changing size of key structure, this is an ABI change.

Yes. This means target would be 2.2?

I will send the new version anyway to further discuss, and will rebase 
again once necessary.

Marc


[dpdk-dev] [PATCH 5/5] app/testpmd: add test cases for qinq stripping and insertion

2015-05-26 Thread Helin Zhang
If double vlan is detected, its stripped flag and vlan tags can be
printed on rxonly mode. Test command of 'tx_vlan set' is expanded
to set both single and double vlan tags on TX side for each packets
to be sent out.

Signed-off-by: Helin Zhang 
---
 app/test-pmd/cmdline.c | 78 +-
 app/test-pmd/config.c  | 21 +-
 app/test-pmd/flowgen.c |  4 ++-
 app/test-pmd/macfwd.c  |  3 ++
 app/test-pmd/macswap.c |  3 ++
 app/test-pmd/rxonly.c  |  3 ++
 app/test-pmd/testpmd.h |  6 +++-
 app/test-pmd/txonly.c  |  8 --
 8 files changed, 114 insertions(+), 12 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index f01db2a..db2e73e 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -304,9 +304,9 @@ static void cmd_help_long_parsed(void *parsed_result,
"rx_vxlan_port rm (udp_port) (port_id)\n"
"Remove an UDP port for VXLAN packet filter on a 
port\n\n"

-   "tx_vlan set vlan_id (port_id)\n"
-   "Set hardware insertion of VLAN ID in packets sent"
-   " on a port.\n\n"
+   "tx_vlan set (port_id) vlan_id[, vlan_id_outer]\n"
+   "Set hardware insertion of VLAN IDs (single or 
double VLAN "
+   "depends on the number of VLAN IDs) in packets sent on 
a port.\n\n"

"tx_vlan set pvid port_id vlan_id (on|off)\n"
"Set port based TX VLAN insertion.\n\n"
@@ -2799,8 +2799,8 @@ cmdline_parse_inst_t cmd_rx_vlan_filter = {
 struct cmd_tx_vlan_set_result {
cmdline_fixed_string_t tx_vlan;
cmdline_fixed_string_t set;
-   uint16_t vlan_id;
uint8_t port_id;
+   uint16_t vlan_id;
 };

 static void
@@ -2809,6 +2809,13 @@ cmd_tx_vlan_set_parsed(void *parsed_result,
   __attribute__((unused)) void *data)
 {
struct cmd_tx_vlan_set_result *res = parsed_result;
+   int vlan_offload = rte_eth_dev_get_vlan_offload(res->port_id);
+
+   if (vlan_offload & ETH_VLAN_EXTEND_OFFLOAD) {
+   printf("Error, as QinQ has been enabled.\n");
+   return;
+   }
+
tx_vlan_set(res->port_id, res->vlan_id);
 }

@@ -2828,13 +2835,69 @@ cmdline_parse_token_num_t cmd_tx_vlan_set_portid =
 cmdline_parse_inst_t cmd_tx_vlan_set = {
.f = cmd_tx_vlan_set_parsed,
.data = NULL,
-   .help_str = "enable hardware insertion of a VLAN header with a given "
-   "TAG Identifier in packets sent on a port",
+   .help_str = "enable hardware insertion of a single VLAN header "
+   "with a given TAG Identifier in packets sent on a port",
.tokens = {
(void *)&cmd_tx_vlan_set_tx_vlan,
(void *)&cmd_tx_vlan_set_set,
-   (void *)&cmd_tx_vlan_set_vlanid,
(void *)&cmd_tx_vlan_set_portid,
+   (void *)&cmd_tx_vlan_set_vlanid,
+   NULL,
+   },
+};
+
+/* *** ENABLE HARDWARE INSERTION OF Double VLAN HEADER IN TX PACKETS *** */
+struct cmd_tx_vlan_set_qinq_result {
+   cmdline_fixed_string_t tx_vlan;
+   cmdline_fixed_string_t set;
+   uint8_t port_id;
+   uint16_t vlan_id;
+   uint16_t vlan_id_outer;
+};
+
+static void
+cmd_tx_vlan_set_qinq_parsed(void *parsed_result,
+   __attribute__((unused)) struct cmdline *cl,
+   __attribute__((unused)) void *data)
+{
+   struct cmd_tx_vlan_set_qinq_result *res = parsed_result;
+   int vlan_offload = rte_eth_dev_get_vlan_offload(res->port_id);
+
+   if (!(vlan_offload & ETH_VLAN_EXTEND_OFFLOAD)) {
+   printf("Error, as QinQ hasn't been enabled.\n");
+   return;
+   }
+
+   tx_qinq_set(res->port_id, res->vlan_id, res->vlan_id_outer);
+}
+
+cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_tx_vlan =
+   TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+   tx_vlan, "tx_vlan");
+cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_set =
+   TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+   set, "set");
+cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_portid =
+   TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+   port_id, UINT8);
+cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid =
+   TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+   vlan_id, UINT16);
+cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid_outer =
+   TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+   vlan_id_outer, UINT16);
+
+cmdline_parse_inst_t cmd_tx_vlan_set_qinq = {
+   .f = cmd_tx_vlan_set_qinq_parsed,
+   .data = NULL,
+   .help_str = "enable hardware insertion of double VLAN header "
+   "with given TAG Identifiers in packets sent on a port",
+   .toke

[dpdk-dev] [PATCH 4/5] i40evf: add supported offload capability flags

2015-05-26 Thread Helin Zhang
Add checksum offload capability flags which have already been
supported for a long time.

Signed-off-by: Helin Zhang 
---
 drivers/net/i40e/i40e_ethdev_vf.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev_vf.c 
b/drivers/net/i40e/i40e_ethdev_vf.c
index 1a4d088..12d7917 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1645,10 +1645,17 @@ i40evf_dev_info_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
dev_info->rx_offload_capa =
DEV_RX_OFFLOAD_VLAN_STRIP |
-   DEV_RX_OFFLOAD_QINQ_STRIP;
+   DEV_RX_OFFLOAD_QINQ_STRIP |
+   DEV_RX_OFFLOAD_IPV4_CKSUM |
+   DEV_RX_OFFLOAD_UDP_CKSUM |
+   DEV_RX_OFFLOAD_TCP_CKSUM;
dev_info->tx_offload_capa =
DEV_TX_OFFLOAD_VLAN_INSERT |
-   DEV_TX_OFFLOAD_QINQ_INSERT;
+   DEV_TX_OFFLOAD_QINQ_INSERT |
+   DEV_TX_OFFLOAD_IPV4_CKSUM |
+   DEV_TX_OFFLOAD_UDP_CKSUM |
+   DEV_TX_OFFLOAD_TCP_CKSUM |
+   DEV_TX_OFFLOAD_SCTP_CKSUM;

dev_info->default_rxconf = (struct rte_eth_rxconf) {
.rx_thresh = {
-- 
1.9.3



[dpdk-dev] [PATCH 3/5] i40e: support double vlan stripping and insertion

2015-05-26 Thread Helin Zhang
It configures specific registers to enable double vlan stripping
on RX side and insertion on TX side.
The RX descriptors will be parsed, the vlan tags and flags will be
saved to corresponding mbuf fields if vlan tag is detected.
The TX descriptors will be configured according to the
configurations in mbufs, to trigger the hardware insertion of
double vlan tags for each packets sent out.

Signed-off-by: Helin Zhang 
---
 drivers/net/i40e/i40e_ethdev.c| 52 +
 drivers/net/i40e/i40e_ethdev_vf.c |  6 +++
 drivers/net/i40e/i40e_rxtx.c  | 81 +--
 lib/librte_ether/rte_ethdev.h | 28 +++---
 4 files changed, 125 insertions(+), 42 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index fb64027..e841623 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -211,6 +211,7 @@ static int i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
void *arg);
 static void i40e_configure_registers(struct i40e_hw *hw);
 static void i40e_hw_init(struct i40e_hw *hw);
+static int i40e_config_qinq(struct i40e_hw *hw, struct i40e_vsi *vsi);

 static const struct rte_pci_id pci_id_i40e_map[] = {
 #define RTE_PCI_DEV_ID_DECL_I40E(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
@@ -1529,11 +1530,13 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
dev_info->max_vfs = dev->pci_dev->max_vfs;
dev_info->rx_offload_capa =
DEV_RX_OFFLOAD_VLAN_STRIP |
+   DEV_RX_OFFLOAD_QINQ_STRIP |
DEV_RX_OFFLOAD_IPV4_CKSUM |
DEV_RX_OFFLOAD_UDP_CKSUM |
DEV_RX_OFFLOAD_TCP_CKSUM;
dev_info->tx_offload_capa =
DEV_TX_OFFLOAD_VLAN_INSERT |
+   DEV_TX_OFFLOAD_QINQ_INSERT |
DEV_TX_OFFLOAD_IPV4_CKSUM |
DEV_TX_OFFLOAD_UDP_CKSUM |
DEV_TX_OFFLOAD_TCP_CKSUM |
@@ -3056,6 +3059,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
 * macvlan filter which is expected and cannot be removed.
 */
i40e_update_default_filter_setting(vsi);
+   i40e_config_qinq(hw, vsi);
} else if (type == I40E_VSI_SRIOV) {
memset(&ctxt, 0, sizeof(ctxt));
/**
@@ -3096,6 +3100,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 * Since VSI is not created yet, only configure parameter,
 * will add vsi below.
 */
+
+   i40e_config_qinq(hw, vsi);
} else if (type == I40E_VSI_VMDQ2) {
memset(&ctxt, 0, sizeof(ctxt));
/*
@@ -5697,3 +5703,49 @@ i40e_configure_registers(struct i40e_hw *hw)
"0x%"PRIx32, reg_table[i].val, reg_table[i].addr);
}
 }
+
+#define I40E_VSI_TSR(_i)(0x00050800 + ((_i) * 4))
+#define I40E_VSI_TSR_QINQ_CONFIG0xc030
+#define I40E_VSI_L2TAGSTXVALID(_i)  (0x00042800 + ((_i) * 4))
+#define I40E_VSI_L2TAGSTXVALID_QINQ 0xab
+static int
+i40e_config_qinq(struct i40e_hw *hw, struct i40e_vsi *vsi)
+{
+   uint32_t reg;
+   int ret;
+
+   if (vsi->vsi_id >= I40E_MAX_NUM_VSIS) {
+   PMD_DRV_LOG(ERR, "VSI ID exceeds the maximum");
+   return -EINVAL;
+   }
+
+   /* Configure for double VLAN RX stripping */
+   reg = I40E_READ_REG(hw, I40E_VSI_TSR(vsi->vsi_id));
+   if ((reg & I40E_VSI_TSR_QINQ_CONFIG) != I40E_VSI_TSR_QINQ_CONFIG) {
+   reg |= I40E_VSI_TSR_QINQ_CONFIG;
+   ret = i40e_aq_debug_write_register(hw,
+  I40E_VSI_TSR(vsi->vsi_id),
+  reg, NULL);
+   if (ret < 0) {
+   PMD_DRV_LOG(ERR, "Failed to update VSI_TSR[%d]",
+   vsi->vsi_id);
+   return I40E_ERR_CONFIG;
+   }
+   }
+
+   /* Configure for double VLAN TX insertion */
+   reg = I40E_READ_REG(hw, I40E_VSI_L2TAGSTXVALID(vsi->vsi_id));
+   if ((reg & 0xff) != I40E_VSI_L2TAGSTXVALID_QINQ) {
+   reg = I40E_VSI_L2TAGSTXVALID_QINQ;
+   ret = i40e_aq_debug_write_register(hw,
+  I40E_VSI_L2TAGSTXVALID(
+  vsi->vsi_id), reg, NULL);
+   if (ret < 0) {
+   PMD_DRV_LOG(ERR, "Failed to update "
+   "VSI_L2TAGSTXVALID[%d]", vsi->vsi_id);
+   return I40E_ERR_CONFIG;
+   }
+   }
+
+   return 0;
+}
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c 
b/drivers/net/i40e/i40e_ethdev_vf.c
index 9f92a2f..1a4d088 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1643,6 +1643,12 @@ i40evf_dev_info_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_

[dpdk-dev] [PATCH 2/5] mbuf: use the reserved 16 bits for double vlan

2015-05-26 Thread Helin Zhang
Use the reserved 16 bits in rte_mbuf structure for the outer vlan,
also add QinQ offloading flags for both RX and TX sides.

Signed-off-by: Helin Zhang 
---
 lib/librte_mbuf/rte_mbuf.h | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index ab6de67..4551df9 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -101,11 +101,17 @@ extern "C" {
 #define PKT_RX_TUNNEL_IPV6_HDR (1ULL << 12) /**< RX tunnel packet with IPv6 
header. */
 #define PKT_RX_FDIR_ID   (1ULL << 13) /**< FD id reported if FDIR match. */
 #define PKT_RX_FDIR_FLX  (1ULL << 14) /**< Flexible bytes reported if FDIR 
match. */
+#define PKT_RX_QINQ_PKT (1ULL << 15)  /**< RX packet with double VLAN 
stripped. */
 /* add new RX flags here */

 /* add new TX flags here */

 /**
+ * Second VLAN insertion (QinQ) flag.
+ */
+#define PKT_TX_QINQ_PKT(1ULL << 49)   /**< TX packet with double VLAN 
inserted. */
+
+/**
  * 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
@@ -279,7 +285,7 @@ struct rte_mbuf {
uint16_t data_len;/**< Amount of data in segment buffer. */
uint32_t pkt_len; /**< Total pkt len: sum of all segments. */
uint16_t vlan_tci;/**< VLAN Tag Control Identifier (CPU order) 
*/
-   uint16_t reserved;
+   uint16_t vlan_tci_outer;  /**< Outer VLAN Tag Control Identifier (CPU 
order) */
union {
uint32_t rss; /**< RSS hash result if RSS enabled */
struct {
@@ -777,6 +783,7 @@ static inline void rte_pktmbuf_reset(struct rte_mbuf *m)
m->pkt_len = 0;
m->tx_offload = 0;
m->vlan_tci = 0;
+   m->vlan_tci_outer = 0;
m->nb_segs = 1;
m->port = 0xff;

@@ -849,6 +856,7 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, 
struct rte_mbuf *m)
mi->data_len = m->data_len;
mi->port = m->port;
mi->vlan_tci = m->vlan_tci;
+   mi->vlan_tci_outer = m->vlan_tci_outer;
mi->tx_offload = m->tx_offload;
mi->hash = m->hash;

-- 
1.9.3



[dpdk-dev] [PATCH 1/5] ixgbe: remove a discarded source line

2015-05-26 Thread Helin Zhang
Little endian to CPU order conversion had been added for reading
vlan tag from RX descriptor, while its original source line was
forgotten to delete. That's a discarded source line and should be
deleted.

Signed-off-by: Helin Zhang 
---
 drivers/net/ixgbe/ixgbe_rxtx.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 4f9ab22..041c544 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -981,7 +981,6 @@ ixgbe_rx_scan_hw_ring(struct ixgbe_rx_queue *rxq)
pkt_len = (uint16_t)(rxdp[j].wb.upper.length - 
rxq->crc_len);
mb->data_len = pkt_len;
mb->pkt_len = pkt_len;
-   mb->vlan_tci = rxdp[j].wb.upper.vlan;
mb->vlan_tci = rte_le_to_cpu_16(rxdp[j].wb.upper.vlan);

/* convert descriptor fields to rte mbuf flags */
-- 
1.9.3



[dpdk-dev] [PATCH 0/5] support i40e QinQ stripping and insertion

2015-05-26 Thread Helin Zhang
As i40e hardware can be reconfigured to support QinQ stripping and
insertion, this patch set is to enable that together with using the
reserved 16 bits in 'struct rte_mbuf' for the second vlan tag.
Corresponding command is added in testpmd for testing.

Note that no need to rework vPMD, as nothings used in it changed.

Helin Zhang (5):
  ixgbe: remove a discarded source line
  mbuf: use the reserved 16 bits for double vlan
  i40e: support double vlan stripping and insertion
  i40evf: add supported offload capability flags
  app/testpmd: add test cases for qinq stripping and insertion

 app/test-pmd/cmdline.c| 78 +
 app/test-pmd/config.c | 21 +-
 app/test-pmd/flowgen.c|  4 +-
 app/test-pmd/macfwd.c |  3 ++
 app/test-pmd/macswap.c|  3 ++
 app/test-pmd/rxonly.c |  3 ++
 app/test-pmd/testpmd.h|  6 ++-
 app/test-pmd/txonly.c |  8 +++-
 drivers/net/i40e/i40e_ethdev.c| 52 +
 drivers/net/i40e/i40e_ethdev_vf.c | 13 +++
 drivers/net/i40e/i40e_rxtx.c  | 81 +--
 drivers/net/ixgbe/ixgbe_rxtx.c|  1 -
 lib/librte_ether/rte_ethdev.h | 28 +++---
 lib/librte_mbuf/rte_mbuf.h| 10 -
 14 files changed, 255 insertions(+), 56 deletions(-)

-- 
1.9.3



[dpdk-dev] Build only rte_mempool

2015-05-26 Thread Dax Rawal
Hi,
I am a new to DPDK and am interested in using  just the rte_mempool and not
the rest of it. I have these question if this is possible.

-What else has to be build (apart from rte_mempool) as a mandatory minimum
?
-What is the init function for rte_mempool ?
-Any guideline as to how to integrate and build rte_mempool along with
other application ?

Thanks,
-Dax


[dpdk-dev] [PATCH 2/5] mbuf: use the reserved 16 bits for double vlan

2015-05-26 Thread Ananyev, Konstantin


> -Original Message-
> From: Stephen Hemminger [mailto:stephen at networkplumber.org]
> Sent: Tuesday, May 26, 2015 4:35 PM
> To: Ananyev, Konstantin
> Cc: Zhang, Helin; dev at dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 2/5] mbuf: use the reserved 16 bits for double 
> vlan
> 
> On Tue, 26 May 2015 15:02:51 +
> "Ananyev, Konstantin"  wrote:
> 
> > Hi Stephen,
> >
> > > -Original Message-
> > > From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Stephen Hemminger
> > > Sent: Tuesday, May 26, 2015 3:55 PM
> > > To: Zhang, Helin
> > > Cc: dev at dpdk.org
> > > Subject: Re: [dpdk-dev] [PATCH 2/5] mbuf: use the reserved 16 bits for 
> > > double vlan
> > >
> > > On Tue, 26 May 2015 16:36:37 +0800
> > > Helin Zhang  wrote:
> > >
> > > > Use the reserved 16 bits in rte_mbuf structure for the outer vlan,
> > > > also add QinQ offloading flags for both RX and TX sides.
> > > >
> > > > Signed-off-by: Helin Zhang 
> > >
> > > Yet another change that is much needed, but breaks ABI compatibility.
> >
> > Why do you think it breaks ABI compatibility?
> > As I can see, it uses field that was reserved.
> > Konstantin
> 
> Because an application maybe assuming something or reusing the reserved 
> fields.

But properly behaving application, shouldn't do that right?
And for misbehaving ones, why should we care about them?

> Yes, it would be dumb of application to do that but from absolute ABI point
> of view it is a change.

So, in theory,  even adding a new field to the end of rte_mbuf is an ABI 
breakage?
Konstantin



[dpdk-dev] [PATCH v3] pipeline: add statistics for librte_pipeline ports and tables

2015-05-26 Thread Maciej Gajdzica
This patch adds statistics collection for librte_pipeline.
Those statistics ale disabled by default during build time.

Signed-off-by: Pawel Wodkowski 
---
 lib/librte_pipeline/rte_pipeline.c |  185 +---
 lib/librte_pipeline/rte_pipeline.h |   98 +++
 2 files changed, 272 insertions(+), 11 deletions(-)

diff --git a/lib/librte_pipeline/rte_pipeline.c 
b/lib/librte_pipeline/rte_pipeline.c
index 36d92c9..3ef36ad 100644
--- a/lib/librte_pipeline/rte_pipeline.c
+++ b/lib/librte_pipeline/rte_pipeline.c
@@ -48,6 +48,17 @@

 #define RTE_TABLE_INVALID UINT32_MAX

+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+#define RTE_PIPELINE_STATS_ADD(counter, val) \
+   ({ (counter) += (val); })
+
+#define RTE_PIPELINE_STATS_ADD_M(counter, mask) \
+   ({ (counter) += __builtin_popcountll(mask); })
+#else
+#define RTE_PIPELINE_STATS_ADD(counter, val)
+#define RTE_PIPELINE_STATS_ADD_M(counter, mask)
+#endif
+
 struct rte_port_in {
/* Input parameters */
struct rte_port_in_ops ops;
@@ -63,6 +74,8 @@ struct rte_port_in {

/* List of enabled ports */
struct rte_port_in *next;
+
+   uint64_t n_pkts_dropped_by_ah;
 };

 struct rte_port_out {
@@ -74,6 +87,8 @@ struct rte_port_out {

/* Handle to low-level port */
void *h_port;
+
+   uint64_t n_pkts_dropped_by_ah;
 };

 struct rte_table {
@@ -90,6 +105,12 @@ struct rte_table {

/* Handle to the low-level table object */
void *h_table;
+
+   /* Stats for this table. */
+   uint64_t n_pkts_dropped_by_lkp_hit_ah;
+   uint64_t n_pkts_dropped_by_lkp_miss_ah;
+   uint64_t n_pkts_dropped_lkp_hit;
+   uint64_t n_pkts_dropped_lkp_miss;
 };

 #define RTE_PIPELINE_MAX_NAME_SZ   124
@@ -1040,6 +1061,8 @@ rte_pipeline_action_handler_port_bulk(struct rte_pipeline 
*p,

port_out->f_action_bulk(p->pkts, &pkts_mask, port_out->arg_ah);
p->action_mask0[RTE_PIPELINE_ACTION_DROP] |= pkts_mask ^  mask;
+   RTE_PIPELINE_STATS_ADD_M(port_out->n_pkts_dropped_by_ah,
+   pkts_mask ^  mask);
}

/* Output port TX */
@@ -1071,6 +1094,9 @@ rte_pipeline_action_handler_port(struct rte_pipeline *p, 
uint64_t pkts_mask)
p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
(pkt_mask ^ 1LLU) << i;

+   
RTE_PIPELINE_STATS_ADD(port_out->n_pkts_dropped_by_ah,
+   pkt_mask ^ 1LLU);
+
/* Output port TX */
if (pkt_mask != 0)
port_out->ops.f_tx(port_out->h_port,
@@ -1104,6 +1130,9 @@ rte_pipeline_action_handler_port(struct rte_pipeline *p, 
uint64_t pkts_mask)
p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
(pkt_mask ^ 1LLU) << i;

+   
RTE_PIPELINE_STATS_ADD(port_out->n_pkts_dropped_by_ah,
+   pkt_mask ^ 1LLU);
+
/* Output port TX */
if (pkt_mask != 0)
port_out->ops.f_tx(port_out->h_port,
@@ -1140,6 +1169,9 @@ rte_pipeline_action_handler_port_meta(struct rte_pipeline 
*p,
p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
(pkt_mask ^ 1LLU) << i;

+   
RTE_PIPELINE_STATS_ADD(port_out->n_pkts_dropped_by_ah,
+   pkt_mask ^ 1ULL);
+
/* Output port TX */
if (pkt_mask != 0)
port_out->ops.f_tx(port_out->h_port,
@@ -1174,6 +1206,9 @@ rte_pipeline_action_handler_port_meta(struct rte_pipeline 
*p,
p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
(pkt_mask ^ 1LLU) << i;

+   
RTE_PIPELINE_STATS_ADD(port_out->n_pkts_dropped_by_ah,
+   pkt_mask ^ 1ULL);
+
/* Output port TX */
if (pkt_mask != 0)
port_out->ops.f_tx(port_out->h_port,
@@ -1232,10 +1267,10 @@ rte_pipeline_run(struct rte_pipeline *p)
if (port_in->f_action != NULL) {
uint64_t mask = pkts_mask;

-   port_in->f_action(p->pkts, n_pkts, &pkts_mask,
-   port_in->arg_ah);
-   p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
-   pkts_mask ^ mask;
+   port_in->f_action(p->pkts, n_pkts, &pkts_mask, 
port_in->

[dpdk-dev] [PATCH v3 01/10] table: added structure for storing table stats

2015-05-26 Thread Chris Wright
* Maciej Gajdzica (maciejx.t.gajdzica at intel.com) wrote:
> @@ -187,6 +193,24 @@ typedef int (*rte_table_op_lookup)(
>   uint64_t *lookup_hit_mask,
>   void **entries);
>  
> +/**
> + * Lookup table stats read
> + *
> + * @param port

Parameter is actually called table

> + *   Handle to lookup table instance
> + * @param stats
> + *   Handle to table stats struct to copy data
> + * @param clear
> + *   Flag indicating that stats should be cleared after read
> + *
> + * @return
> + *   Error code or 0 on success.
> + */
> +typedef int (*rte_table_op_stats_read)(
> + void *table,
> + struct rte_table_stats *stats,
> + int clear);


[dpdk-dev] [PATCH 2/5] mbuf: use the reserved 16 bits for double vlan

2015-05-26 Thread Ananyev, Konstantin
Hi Stephen,

> -Original Message-
> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Stephen Hemminger
> Sent: Tuesday, May 26, 2015 3:55 PM
> To: Zhang, Helin
> Cc: dev at dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 2/5] mbuf: use the reserved 16 bits for double 
> vlan
> 
> On Tue, 26 May 2015 16:36:37 +0800
> Helin Zhang  wrote:
> 
> > Use the reserved 16 bits in rte_mbuf structure for the outer vlan,
> > also add QinQ offloading flags for both RX and TX sides.
> >
> > Signed-off-by: Helin Zhang 
> 
> Yet another change that is much needed, but breaks ABI compatibility.

Why do you think it breaks ABI compatibility?
As I can see, it uses field that was reserved.
Konstantin


[dpdk-dev] [PATCH 2/5] mbuf: use the reserved 16 bits for double vlan

2015-05-26 Thread Zhang, Helin
Hi Stephen

> -Original Message-
> From: Stephen Hemminger [mailto:stephen at networkplumber.org]
> Sent: Tuesday, May 26, 2015 10:55 PM
> To: Zhang, Helin
> Cc: dev at dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 2/5] mbuf: use the reserved 16 bits for
> double vlan
> 
> On Tue, 26 May 2015 16:36:37 +0800
> Helin Zhang  wrote:
> 
> > Use the reserved 16 bits in rte_mbuf structure for the outer vlan,
> > also add QinQ offloading flags for both RX and TX sides.
> >
> > Signed-off-by: Helin Zhang 
> 
> Yet another change that is much needed, but breaks ABI compatibility.
Even just use the reserved 16 bits? It seems yes.
Would it be acceptable to use the original name of 'reserved' for the outer 
vlan?
And then announce the name change, and rename it one release after?

Regards,
Helin


[dpdk-dev] [PATCH v3 01/10] table: added structure for storing table stats

2015-05-26 Thread Stephen Hemminger
On Tue, 26 May 2015 21:40:42 +
"Dumitrescu, Cristian"  wrote:

> 
> 
> > -Original Message-
> > From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Stephen
> > Hemminger
> > Sent: Tuesday, May 26, 2015 3:58 PM
> > To: Gajdzica, MaciejX T
> > Cc: dev at dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v3 01/10] table: added structure for storing
> > table stats
> > 
> > On Tue, 26 May 2015 14:39:38 +0200
> > Maciej Gajdzica  wrote:
> > 
> > > +
> > >  /** Lookup table interface defining the lookup table operation */
> > >  struct rte_table_ops {
> > >   rte_table_op_create f_create;   /**< Create */
> > > @@ -194,6 +218,7 @@ struct rte_table_ops {
> > >   rte_table_op_entry_add f_add;   /**< Entry add */
> > >   rte_table_op_entry_delete f_delete; /**< Entry delete */
> > >   rte_table_op_lookup f_lookup;   /**< Lookup */
> > > + rte_table_op_stats_read f_stats;/**< Stats */
> > >  };
> > 
> > Another good idea, which is an ABI change.
> 
> This is simply adding a new API function, this is not changing any function 
> prototype. There is no change required in the map file of this library. Is 
> there anything we should have done and we did not do?
> 

But if I built an external set of code which had rte_table_ops (don't worry I 
haven't)
and that binary ran with the new definition, the core code it table would 
reference
outside the (old version) of rte_table_ops structure and find garbage.


[dpdk-dev] [PATCH v3] pipeline: add statistics for librte_pipeline ports and tables

2015-05-26 Thread Stephen Hemminger
On Tue, 26 May 2015 21:35:22 +
"Dumitrescu, Cristian"  wrote:

> 
> 
> > -Original Message-
> > From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Stephen
> > Hemminger
> > Sent: Tuesday, May 26, 2015 3:57 PM
> > To: Gajdzica, MaciejX T
> > Cc: dev at dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v3] pipeline: add statistics for 
> > librte_pipeline
> > ports and tables
> > 
> > On Tue, 26 May 2015 15:39:18 +0200
> > Maciej Gajdzica  wrote:
> > 
> > > +#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
> > > +#define RTE_PIPELINE_STATS_ADD(counter, val) \
> > > + ({ (counter) += (val); })
> > > +
> > > +#define RTE_PIPELINE_STATS_ADD_M(counter, mask) \
> > > + ({ (counter) += __builtin_popcountll(mask); })
> > > +#else
> > > +#define RTE_PIPELINE_STATS_ADD(counter, val)
> > > +#define RTE_PIPELINE_STATS_ADD_M(counter, mask)
> > > +#endif
> > 
> > This is worse idea than the previous one.
> > I want statistics done on a per lcore basis, and always available
> > because real users on production system want statistics (but they
> > don't want log spam).
> 
> Stephen,
> 
> Thomas and myself converged towards this solution, Thomas asked if anybody 
> objects, you did not 
> (http://www.dpdk.org/ml/archives/dev/2015-May/018099.html) . You say this 
> idea is bad, but what exactly is your objection? Do you have an alternative 
> proposal?

Yes. Always keep statistics.

We use functions like this internally.

struct xxx_stats {
uint64_t mib[XXX_MIB_MAX];
};
extern struct xxx_stats xxx_stats[RTE_MAX_LCORE];

#define XXXSTAT_INC(type)   xxxstats[rte_lcore_id()].mibs[type]++


> You already mentioned in the previous thread you would like to have per lcore 
> statistics. I was kindly asking you to describe your idea, but you did not do 
> this yet (http://www.dpdk.org/ml/archives/dev/2015-May/017956.html ). Can you 
> please describe it? Each port instance has its own statistics counters. Each 
> lcore can run one or more pipeline instances, therefore each lcore typically 
> runs several port instances of the same or different type (each port instance 
> with its own statistics), so how is "per lcore stats" requirement applicable 
> here?

I thought you were familiar with technique of having per-cpu structures and 
variables
widely used in Linux kernel to prevent cache thrashing. Although you call it 
false sharing,
it isn't false., it happens when same counter ping-pongs between multiple 
threads for
no added benefit.


> You also reiterate that you would like to have the stats always enabled. You 
> can definitely do this, it is one of the available choices, but why not also 
> accommodate the users that want to pick the opposite choice? Why force apps 
> to spend cycles on stats if the app either does not want these counters 
> (library counters not relevant for that app, maybe the app is only interested 
> in maintaining some other stats that it implements itself) or do not want 
> them anymore (maybe they only needed them during debug phase), etc? Jay asked 
> this question, and I did my best in my reply to describe our motivation 
> (http://www.dpdk.org/ml/archives/dev/2015-May/017992.html). Maybe you missed 
> that post, it would be good to get your reply on this one too.

I want to see DPDK get out of the config madness.
This is real code, not an Intel benchmark special.



[dpdk-dev] [PATCH v3 10/10] table: added lpm table stats

2015-05-26 Thread Maciej Gajdzica
Added lpm table statistics.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_table/rte_table_lpm.c |   34 ++
 1 file changed, 34 insertions(+)

diff --git a/lib/librte_table/rte_table_lpm.c b/lib/librte_table/rte_table_lpm.c
index 64c684d..ab304ea 100644
--- a/lib/librte_table/rte_table_lpm.c
+++ b/lib/librte_table/rte_table_lpm.c
@@ -46,7 +46,23 @@

 #define RTE_TABLE_LPM_MAX_NEXT_HOPS256

+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_TABLE_LPM_STATS_PKTS_IN_ADD(table, val) \
+   table->stats.n_pkts_in += val
+#define RTE_TABLE_LPM_STATS_PKTS_LOOKUP_MISS(table, val) \
+   table->stats.n_pkts_lookup_miss += val
+
+#else
+
+#define RTE_TABLE_LPM_STATS_PKTS_IN_ADD(table, val)
+#define RTE_TABLE_LPM_STATS_PKTS_LOOKUP_MISS(table, val)
+
+#endif
+
 struct rte_table_lpm {
+   struct rte_table_stats stats;
+
/* Input parameters */
uint32_t entry_size;
uint32_t entry_unique_size;
@@ -313,6 +329,9 @@ rte_table_lpm_lookup(
uint64_t pkts_out_mask = 0;
uint32_t i;

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_LPM_STATS_PKTS_IN_ADD(lpm, n_pkts_in);
+
pkts_out_mask = 0;
for (i = 0; i < (uint32_t)(RTE_PORT_IN_BURST_SIZE_MAX -
__builtin_clzll(pkts_mask)); i++) {
@@ -335,6 +354,20 @@ rte_table_lpm_lookup(
}

*lookup_hit_mask = pkts_out_mask;
+   RTE_TABLE_LPM_STATS_PKTS_LOOKUP_MISS(lpm, n_pkts_in - 
__builtin_popcountll(pkts_out_mask));
+   return 0;
+}
+
+static int
+rte_table_lpm_stats_read(void *table, struct rte_table_stats *stats, int clear)
+{
+   struct rte_table_lpm *t = (struct rte_table_lpm *) table;
+
+   if (stats != NULL)
+   memcpy(stats, &t->stats, sizeof(t->stats));
+
+   if (clear)
+   memset(&t->stats, 0, sizeof(t->stats));

return 0;
 }
@@ -345,4 +378,5 @@ struct rte_table_ops rte_table_lpm_ops = {
.f_add = rte_table_lpm_entry_add,
.f_delete = rte_table_lpm_entry_delete,
.f_lookup = rte_table_lpm_lookup,
+   .f_stats = rte_table_lpm_stats_read,
 };
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 09/10] table: added lpm_ipv6 table stats

2015-05-26 Thread Maciej Gajdzica
Added lpm ipv6 table statistics.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_table/rte_table_lpm_ipv6.c |   34 +
 1 file changed, 34 insertions(+)

diff --git a/lib/librte_table/rte_table_lpm_ipv6.c 
b/lib/librte_table/rte_table_lpm_ipv6.c
index ce4ddc0..62a4c56 100644
--- a/lib/librte_table/rte_table_lpm_ipv6.c
+++ b/lib/librte_table/rte_table_lpm_ipv6.c
@@ -46,7 +46,23 @@

 #define RTE_TABLE_LPM_MAX_NEXT_HOPS256

+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_TABLE_LPM_IPV6_STATS_PKTS_IN_ADD(table, val) \
+   table->stats.n_pkts_in += val
+#define RTE_TABLE_LPM_IPV6_STATS_PKTS_LOOKUP_MISS(table, val) \
+   table->stats.n_pkts_lookup_miss += val
+
+#else
+
+#define RTE_TABLE_LPM_IPV6_STATS_PKTS_IN_ADD(table, val)
+#define RTE_TABLE_LPM_IPV6_STATS_PKTS_LOOKUP_MISS(table, val)
+
+#endif
+
 struct rte_table_lpm_ipv6 {
+   struct rte_table_stats stats;
+
/* Input parameters */
uint32_t entry_size;
uint32_t entry_unique_size;
@@ -327,6 +343,9 @@ rte_table_lpm_ipv6_lookup(
uint64_t pkts_out_mask = 0;
uint32_t i;

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_LPM_IPV6_STATS_PKTS_IN_ADD(lpm, n_pkts_in);
+
pkts_out_mask = 0;
for (i = 0; i < (uint32_t)(RTE_PORT_IN_BURST_SIZE_MAX -
__builtin_clzll(pkts_mask)); i++) {
@@ -349,6 +368,20 @@ rte_table_lpm_ipv6_lookup(
}

*lookup_hit_mask = pkts_out_mask;
+   RTE_TABLE_LPM_IPV6_STATS_PKTS_LOOKUP_MISS(lpm, n_pkts_in - 
__builtin_popcountll(pkts_out_mask));
+   return 0;
+}
+
+static int
+rte_table_lpm_ipv6_stats_read(void *table, struct rte_table_stats *stats, int 
clear)
+{
+   struct rte_table_lpm_ipv6 *t = (struct rte_table_lpm_ipv6 *) table;
+
+   if (stats != NULL)
+   memcpy(stats, &t->stats, sizeof(t->stats));
+
+   if (clear)
+   memset(&t->stats, 0, sizeof(t->stats));

return 0;
 }
@@ -359,4 +392,5 @@ struct rte_table_ops rte_table_lpm_ipv6_ops = {
.f_add = rte_table_lpm_ipv6_entry_add,
.f_delete = rte_table_lpm_ipv6_entry_delete,
.f_lookup = rte_table_lpm_ipv6_lookup,
+   .f_stats = rte_table_lpm_ipv6_stats_read,
 };
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 08/10] table: added hash_lru table stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for hash_lru table.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_table/rte_table_hash_lru.c |   44 +
 1 file changed, 44 insertions(+)

diff --git a/lib/librte_table/rte_table_hash_lru.c 
b/lib/librte_table/rte_table_hash_lru.c
index c9a8afd..30ed19f 100644
--- a/lib/librte_table/rte_table_hash_lru.c
+++ b/lib/librte_table/rte_table_hash_lru.c
@@ -45,6 +45,20 @@

 #define KEYS_PER_BUCKET4

+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_TABLE_HASH_LRU_STATS_PKTS_IN_ADD(table, val) \
+   table->stats.n_pkts_in += val
+#define RTE_TABLE_HASH_LRU_STATS_PKTS_LOOKUP_MISS(table, val) \
+   table->stats.n_pkts_lookup_miss += val
+
+#else
+
+#define RTE_TABLE_HASH_LRU_STATS_PKTS_IN_ADD(table, val)
+#define RTE_TABLE_HASH_LRU_STATS_PKTS_LOOKUP_MISS(table, val)
+
+#endif
+
 struct bucket {
union {
struct bucket *next;
@@ -63,6 +77,8 @@ struct grinder {
 };

 struct rte_table_hash {
+   struct rte_table_stats stats;
+
/* Input parameters */
uint32_t key_size;
uint32_t entry_size;
@@ -368,6 +384,9 @@ static int rte_table_hash_lru_lookup_unoptimized(
struct rte_table_hash *t = (struct rte_table_hash *) table;
uint64_t pkts_mask_out = 0;

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_HASH_LRU_STATS_PKTS_IN_ADD(t, n_pkts_in);
+
for ( ; pkts_mask; ) {
struct bucket *bkt;
struct rte_mbuf *pkt;
@@ -412,6 +431,7 @@ static int rte_table_hash_lru_lookup_unoptimized(
}

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_LRU_STATS_PKTS_LOOKUP_MISS(t, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return 0;
 }

@@ -804,6 +824,9 @@ static int rte_table_hash_lru_lookup(
uint64_t pkts_mask_out = 0, pkts_mask_match_many = 0;
int status = 0;

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_HASH_LRU_STATS_PKTS_IN_ADD(t, n_pkts_in);
+
/* Cannot run the pipeline with less than 7 packets */
if (__builtin_popcountll(pkts_mask) < 7)
return rte_table_hash_lru_lookup_unoptimized(table, pkts,
@@ -916,6 +939,7 @@ static int rte_table_hash_lru_lookup(
}

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_LRU_STATS_PKTS_LOOKUP_MISS(t, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return status;
 }

@@ -933,6 +957,9 @@ static int rte_table_hash_lru_lookup_dosig(
uint64_t pkts_mask_out = 0, pkts_mask_match_many = 0;
int status = 0;

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_HASH_LRU_STATS_PKTS_IN_ADD(t, n_pkts_in);
+
/* Cannot run the pipeline with less than 7 packets */
if (__builtin_popcountll(pkts_mask) < 7)
return rte_table_hash_lru_lookup_unoptimized(table, pkts,
@@ -1045,15 +1072,31 @@ static int rte_table_hash_lru_lookup_dosig(
}

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_LRU_STATS_PKTS_LOOKUP_MISS(t, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return status;
 }

+static int
+rte_table_hash_lru_stats_read(void *table, struct rte_table_stats *stats, int 
clear)
+{
+   struct rte_table_hash *t = (struct rte_table_hash *) table;
+
+   if (stats != NULL)
+   memcpy(stats, &t->stats, sizeof(t->stats));
+
+   if (clear)
+   memset(&t->stats, 0, sizeof(t->stats));
+
+   return 0;
+}
+
 struct rte_table_ops rte_table_hash_lru_ops = {
.f_create = rte_table_hash_lru_create,
.f_free = rte_table_hash_lru_free,
.f_add = rte_table_hash_lru_entry_add,
.f_delete = rte_table_hash_lru_entry_delete,
.f_lookup = rte_table_hash_lru_lookup,
+   .f_stats = rte_table_hash_lru_stats_read,
 };

 struct rte_table_ops rte_table_hash_lru_dosig_ops = {
@@ -1062,4 +1105,5 @@ struct rte_table_ops rte_table_hash_lru_dosig_ops = {
.f_add = rte_table_hash_lru_entry_add,
.f_delete = rte_table_hash_lru_entry_delete,
.f_lookup = rte_table_hash_lru_lookup_dosig,
+   .f_stats = rte_table_hash_lru_stats_read,
 };
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 07/10] table: added hash_key8 table stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for hash key8 table.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_table/rte_table_hash_key8.c |   52 
 1 file changed, 52 insertions(+)

diff --git a/lib/librte_table/rte_table_hash_key8.c 
b/lib/librte_table/rte_table_hash_key8.c
index 6803eb2..9e480c9 100644
--- a/lib/librte_table/rte_table_hash_key8.c
+++ b/lib/librte_table/rte_table_hash_key8.c
@@ -44,6 +44,20 @@

 #define RTE_TABLE_HASH_KEY_SIZE
8

+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_TABLE_HASH_KEY8_STATS_PKTS_IN_ADD(table, val) \
+   table->stats.n_pkts_in += val
+#define RTE_TABLE_HASH_KEY8_STATS_PKTS_LOOKUP_MISS(table, val) \
+   table->stats.n_pkts_lookup_miss += val
+
+#else
+
+#define RTE_TABLE_HASH_KEY8_STATS_PKTS_IN_ADD(table, val)
+#define RTE_TABLE_HASH_KEY8_STATS_PKTS_LOOKUP_MISS(table, val)
+
+#endif
+
 struct rte_bucket_4_8 {
/* Cache line 0 */
uint64_t signature;
@@ -58,6 +72,8 @@ struct rte_bucket_4_8 {
 };

 struct rte_table_hash {
+   struct rte_table_stats stats;
+
/* Input parameters */
uint32_t n_buckets;
uint32_t n_entries_per_bucket;
@@ -846,6 +862,9 @@ rte_table_hash_lookup_key8_lru(
pkt11_index, pkt20_index, pkt21_index;
uint64_t pkts_mask_out = 0;

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_HASH_KEY8_STATS_PKTS_IN_ADD(f, n_pkts_in);
+
/* Cannot run the pipeline with less than 5 packets */
if (__builtin_popcountll(pkts_mask) < 5) {
for ( ; pkts_mask; ) {
@@ -860,6 +879,7 @@ rte_table_hash_lookup_key8_lru(
}

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_KEY8_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return 0;
}

@@ -949,6 +969,7 @@ rte_table_hash_lookup_key8_lru(
bucket20, bucket21, pkts_mask_out, entries, f);

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_KEY8_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return 0;
 } /* rte_table_hash_lookup_key8_lru() */

@@ -967,6 +988,9 @@ rte_table_hash_lookup_key8_lru_dosig(
uint32_t pkt11_index, pkt20_index, pkt21_index;
uint64_t pkts_mask_out = 0;

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_HASH_KEY8_STATS_PKTS_IN_ADD(f, n_pkts_in);
+
/* Cannot run the pipeline with less than 5 packets */
if (__builtin_popcountll(pkts_mask) < 5) {
for ( ; pkts_mask; ) {
@@ -981,6 +1005,7 @@ rte_table_hash_lookup_key8_lru_dosig(
}

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_KEY8_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return 0;
}

@@ -1070,6 +1095,7 @@ rte_table_hash_lookup_key8_lru_dosig(
bucket20, bucket21, pkts_mask_out, entries, f);

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_KEY8_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return 0;
 } /* rte_table_hash_lookup_key8_lru_dosig() */

@@ -1090,6 +1116,9 @@ rte_table_hash_lookup_key8_ext(
struct rte_bucket_4_8 *buckets[RTE_PORT_IN_BURST_SIZE_MAX];
uint64_t *keys[RTE_PORT_IN_BURST_SIZE_MAX];

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_HASH_KEY8_STATS_PKTS_IN_ADD(f, n_pkts_in);
+
/* Cannot run the pipeline with less than 5 packets */
if (__builtin_popcountll(pkts_mask) < 5) {
for ( ; pkts_mask; ) {
@@ -1216,6 +1245,7 @@ grind_next_buckets:
}

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_KEY8_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return 0;
 } /* rte_table_hash_lookup_key8_ext() */

@@ -1236,6 +1266,9 @@ rte_table_hash_lookup_key8_ext_dosig(
struct rte_bucket_4_8 *buckets[RTE_PORT_IN_BURST_SIZE_MAX];
uint64_t *keys[RTE_PORT_IN_BURST_SIZE_MAX];

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_HASH_KEY8_STATS_PKTS_IN_ADD(f, n_pkts_in);
+
/* Cannot run the pipeline with less than 5 packets */
if (__builtin_popcountll(pkts_mask) < 5) {
for ( ; pkts_mask; ) {
@@ -1362,15 +1395,31 @@ grind_next_buckets:
}

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_KEY8_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return 0;
 } /* rte_table_hash_lookup_key8_dosig_ext() */

+static int
+rte_table_hash_key8_stats_read(void *table, struct rte_table_stats *stats, int 
clear)
+{
+   struct rte_table_hash *t = (struct rte_table_hash *) table;
+
+   if (stats != NULL)
+   memcpy(stats, &t->stats

[dpdk-dev] [PATCH v3 06/10] table: added hash_key32 table stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for hash key32 table.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_table/rte_table_hash_key32.c |   41 +++
 1 file changed, 41 insertions(+)

diff --git a/lib/librte_table/rte_table_hash_key32.c 
b/lib/librte_table/rte_table_hash_key32.c
index 6790594..da08edc 100644
--- a/lib/librte_table/rte_table_hash_key32.c
+++ b/lib/librte_table/rte_table_hash_key32.c
@@ -46,6 +46,20 @@

 #define RTE_BUCKET_ENTRY_VALID 0x1LLU

+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_TABLE_HASH_KEY32_STATS_PKTS_IN_ADD(table, val) \
+   table->stats.n_pkts_in += val
+#define RTE_TABLE_HASH_KEY32_STATS_PKTS_LOOKUP_MISS(table, val) \
+   table->stats.n_pkts_lookup_miss += val
+
+#else
+
+#define RTE_TABLE_HASH_KEY32_STATS_PKTS_IN_ADD(table, val)
+#define RTE_TABLE_HASH_KEY32_STATS_PKTS_LOOKUP_MISS(table, val)
+
+#endif
+
 struct rte_bucket_4_32 {
/* Cache line 0 */
uint64_t signature[4 + 1];
@@ -61,6 +75,8 @@ struct rte_bucket_4_32 {
 };

 struct rte_table_hash {
+   struct rte_table_stats stats;
+
/* Input parameters */
uint32_t n_buckets;
uint32_t n_entries_per_bucket;
@@ -850,6 +866,9 @@ rte_table_hash_lookup_key32_lru(
uint32_t pkt11_index, pkt20_index, pkt21_index;
uint64_t pkts_mask_out = 0;

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_HASH_KEY32_STATS_PKTS_IN_ADD(f, n_pkts_in);
+
/* Cannot run the pipeline with less than 5 packets */
if (__builtin_popcountll(pkts_mask) < 5) {
for ( ; pkts_mask; ) {
@@ -864,6 +883,7 @@ rte_table_hash_lookup_key32_lru(
}

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_KEY32_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return 0;
}

@@ -954,6 +974,7 @@ rte_table_hash_lookup_key32_lru(
mbuf20, mbuf21, bucket20, bucket21, pkts_mask_out, entries, f);

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_KEY32_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return 0;
 } /* rte_table_hash_lookup_key32_lru() */

@@ -974,6 +995,9 @@ rte_table_hash_lookup_key32_ext(
struct rte_bucket_4_32 *buckets[RTE_PORT_IN_BURST_SIZE_MAX];
uint64_t *keys[RTE_PORT_IN_BURST_SIZE_MAX];

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_HASH_KEY32_STATS_PKTS_IN_ADD(f, n_pkts_in);
+
/* Cannot run the pipeline with less than 5 packets */
if (__builtin_popcountll(pkts_mask) < 5) {
for ( ; pkts_mask; ) {
@@ -1100,15 +1124,31 @@ grind_next_buckets:
}

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_KEY32_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return 0;
 } /* rte_table_hash_lookup_key32_ext() */

+static int
+rte_table_hash_key32_stats_read(void *table, struct rte_table_stats *stats, 
int clear)
+{
+   struct rte_table_hash *t = (struct rte_table_hash *) table;
+
+   if (stats != NULL)
+   memcpy(stats, &t->stats, sizeof(t->stats));
+
+   if (clear)
+   memset(&t->stats, 0, sizeof(t->stats));
+
+   return 0;
+}
+
 struct rte_table_ops rte_table_hash_key32_lru_ops = {
.f_create = rte_table_hash_create_key32_lru,
.f_free = rte_table_hash_free_key32_lru,
.f_add = rte_table_hash_entry_add_key32_lru,
.f_delete = rte_table_hash_entry_delete_key32_lru,
.f_lookup = rte_table_hash_lookup_key32_lru,
+   .f_stats = rte_table_hash_key32_stats_read,
 };

 struct rte_table_ops rte_table_hash_key32_ext_ops = {
@@ -1117,4 +1157,5 @@ struct rte_table_ops rte_table_hash_key32_ext_ops = {
.f_add = rte_table_hash_entry_add_key32_ext,
.f_delete = rte_table_hash_entry_delete_key32_ext,
.f_lookup = rte_table_hash_lookup_key32_ext,
+   .f_stats =rte_table_hash_key32_stats_read,
 };
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 05/10] table: added hash_key16 table stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for hash key16 table.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_table/rte_table_hash_key16.c |   41 +++
 1 file changed, 41 insertions(+)

diff --git a/lib/librte_table/rte_table_hash_key16.c 
b/lib/librte_table/rte_table_hash_key16.c
index f87ea0e..24334e8 100644
--- a/lib/librte_table/rte_table_hash_key16.c
+++ b/lib/librte_table/rte_table_hash_key16.c
@@ -46,6 +46,20 @@

 #define RTE_BUCKET_ENTRY_VALID 0x1LLU

+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_TABLE_HASH_KEY16_STATS_PKTS_IN_ADD(table, val) \
+   table->stats.n_pkts_in += val
+#define RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(table, val) \
+   table->stats.n_pkts_lookup_miss += val
+
+#else
+
+#define RTE_TABLE_HASH_KEY16_STATS_PKTS_IN_ADD(table, val)
+#define RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(table, val)
+
+#endif
+
 struct rte_bucket_4_16 {
/* Cache line 0 */
uint64_t signature[4 + 1];
@@ -61,6 +75,8 @@ struct rte_bucket_4_16 {
 };

 struct rte_table_hash {
+   struct rte_table_stats stats;
+
/* Input parameters */
uint32_t n_buckets;
uint32_t n_entries_per_bucket;
@@ -831,6 +847,9 @@ rte_table_hash_lookup_key16_lru(
uint32_t pkt11_index, pkt20_index, pkt21_index;
uint64_t pkts_mask_out = 0;

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_HASH_KEY16_STATS_PKTS_IN_ADD(f, n_pkts_in);
+
/* Cannot run the pipeline with less than 5 packets */
if (__builtin_popcountll(pkts_mask) < 5) {
for ( ; pkts_mask; ) {
@@ -845,6 +864,7 @@ rte_table_hash_lookup_key16_lru(
}

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return 0;
}

@@ -934,6 +954,7 @@ rte_table_hash_lookup_key16_lru(
bucket20, bucket21, pkts_mask_out, entries, f);

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return 0;
 } /* rte_table_hash_lookup_key16_lru() */

@@ -954,6 +975,9 @@ rte_table_hash_lookup_key16_ext(
struct rte_bucket_4_16 *buckets[RTE_PORT_IN_BURST_SIZE_MAX];
uint64_t *keys[RTE_PORT_IN_BURST_SIZE_MAX];

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_HASH_KEY16_STATS_PKTS_IN_ADD(f, n_pkts_in);
+
/* Cannot run the pipeline with less than 5 packets */
if (__builtin_popcountll(pkts_mask) < 5) {
for ( ; pkts_mask; ) {
@@ -1080,15 +1104,31 @@ grind_next_buckets:
}

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return 0;
 } /* rte_table_hash_lookup_key16_ext() */

+static int
+rte_table_hash_key16_stats_read(void *table, struct rte_table_stats *stats, 
int clear)
+{
+   struct rte_table_hash *t = (struct rte_table_hash *) table;
+
+   if (stats != NULL)
+   memcpy(stats, &t->stats, sizeof(t->stats));
+
+   if (clear)
+   memset(&t->stats, 0, sizeof(t->stats));
+
+   return 0;
+}
+
 struct rte_table_ops rte_table_hash_key16_lru_ops = {
.f_create = rte_table_hash_create_key16_lru,
.f_free = rte_table_hash_free_key16_lru,
.f_add = rte_table_hash_entry_add_key16_lru,
.f_delete = rte_table_hash_entry_delete_key16_lru,
.f_lookup = rte_table_hash_lookup_key16_lru,
+   .f_stats = rte_table_hash_key16_stats_read,
 };

 struct rte_table_ops rte_table_hash_key16_ext_ops = {
@@ -1097,4 +1137,5 @@ struct rte_table_ops rte_table_hash_key16_ext_ops = {
.f_add = rte_table_hash_entry_add_key16_ext,
.f_delete = rte_table_hash_entry_delete_key16_ext,
.f_lookup = rte_table_hash_lookup_key16_ext,
+   .f_stats = rte_table_hash_key16_stats_read,
 };
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 04/10] table: added hash_ext table stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for hash ext table.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_table/rte_table_hash_ext.c |   44 +
 1 file changed, 44 insertions(+)

diff --git a/lib/librte_table/rte_table_hash_ext.c 
b/lib/librte_table/rte_table_hash_ext.c
index 66e416b..7217155 100644
--- a/lib/librte_table/rte_table_hash_ext.c
+++ b/lib/librte_table/rte_table_hash_ext.c
@@ -74,6 +74,20 @@ do   
\
(bucket)->next = (bucket2)->next;   \
 while (0)

+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_TABLE_HASH_EXT_STATS_PKTS_IN_ADD(table, val) \
+   table->stats.n_pkts_in += val
+#define RTE_TABLE_HASH_EXT_STATS_PKTS_LOOKUP_MISS(table, val) \
+   table->stats.n_pkts_lookup_miss += val
+
+#else
+
+#define RTE_TABLE_HASH_EXT_STATS_PKTS_IN_ADD(table, val)
+#define RTE_TABLE_HASH_EXT_STATS_PKTS_LOOKUP_MISS(table, val)
+
+#endif
+
 struct grinder {
struct bucket *bkt;
uint64_t sig;
@@ -82,6 +96,8 @@ struct grinder {
 };

 struct rte_table_hash {
+   struct rte_table_stats stats;
+
/* Input parameters */
uint32_t key_size;
uint32_t entry_size;
@@ -440,6 +456,9 @@ static int rte_table_hash_ext_lookup_unoptimized(
struct rte_table_hash *t = (struct rte_table_hash *) table;
uint64_t pkts_mask_out = 0;

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_HASH_EXT_STATS_PKTS_IN_ADD(t, n_pkts_in);
+
for ( ; pkts_mask; ) {
struct bucket *bkt0, *bkt;
struct rte_mbuf *pkt;
@@ -484,6 +503,7 @@ static int rte_table_hash_ext_lookup_unoptimized(
}

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_EXT_STATS_PKTS_LOOKUP_MISS(t, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return 0;
 }

@@ -861,6 +881,9 @@ static int rte_table_hash_ext_lookup(
uint64_t pkts_mask_out = 0, pkts_mask_match_many = 0;
int status = 0;

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_HASH_EXT_STATS_PKTS_IN_ADD(t, n_pkts_in);
+
/* Cannot run the pipeline with less than 7 packets */
if (__builtin_popcountll(pkts_mask) < 7)
return rte_table_hash_ext_lookup_unoptimized(table, pkts,
@@ -973,6 +996,7 @@ static int rte_table_hash_ext_lookup(
}

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_EXT_STATS_PKTS_LOOKUP_MISS(t, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return status;
 }

@@ -990,6 +1014,9 @@ static int rte_table_hash_ext_lookup_dosig(
uint64_t pkts_mask_out = 0, pkts_mask_match_many = 0;
int status = 0;

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_HASH_EXT_STATS_PKTS_IN_ADD(t, n_pkts_in);
+
/* Cannot run the pipeline with less than 7 packets */
if (__builtin_popcountll(pkts_mask) < 7)
return rte_table_hash_ext_lookup_unoptimized(table, pkts,
@@ -1102,15 +1129,31 @@ static int rte_table_hash_ext_lookup_dosig(
}

*lookup_hit_mask = pkts_mask_out;
+   RTE_TABLE_HASH_EXT_STATS_PKTS_LOOKUP_MISS(t, n_pkts_in - 
__builtin_popcountll(pkts_mask_out));
return status;
 }

+static int
+rte_table_hash_ext_stats_read(void *table, struct rte_table_stats *stats, int 
clear)
+{
+   struct rte_table_hash *t = (struct rte_table_hash *) table;
+
+   if (stats != NULL)
+   memcpy(stats, &t->stats, sizeof(t->stats));
+
+   if (clear)
+   memset(&t->stats, 0, sizeof(t->stats));
+
+   return 0;
+}
+
 struct rte_table_ops rte_table_hash_ext_ops = {
.f_create = rte_table_hash_ext_create,
.f_free = rte_table_hash_ext_free,
.f_add = rte_table_hash_ext_entry_add,
.f_delete = rte_table_hash_ext_entry_delete,
.f_lookup = rte_table_hash_ext_lookup,
+   .f_stats = rte_table_hash_ext_stats_read,
 };

 struct rte_table_ops rte_table_hash_ext_dosig_ops  = {
@@ -1119,4 +1162,5 @@ struct rte_table_ops rte_table_hash_ext_dosig_ops  = {
.f_add = rte_table_hash_ext_entry_add,
.f_delete = rte_table_hash_ext_entry_delete,
.f_lookup = rte_table_hash_ext_lookup_dosig,
+   .f_stats = rte_table_hash_ext_stats_read,
 };
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 03/10] table: added array table stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for array table.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_table/rte_table_array.c |   34 +-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/lib/librte_table/rte_table_array.c 
b/lib/librte_table/rte_table_array.c
index c031070..a44e544 100644
--- a/lib/librte_table/rte_table_array.c
+++ b/lib/librte_table/rte_table_array.c
@@ -42,7 +42,23 @@

 #include "rte_table_array.h"

+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_TABLE_ARRAY_STATS_PKTS_IN_ADD(table, val) \
+   table->stats.n_pkts_in += val
+#define RTE_TABLE_ARRAY_STATS_PKTS_LOOKUP_MISS(table, val) \
+   table->stats.n_pkts_lookup_miss += val
+
+#else
+
+#define RTE_TABLE_ARRAY_STATS_PKTS_IN_ADD(table, val)
+#define RTE_TABLE_ARRAY_STATS_PKTS_LOOKUP_MISS(table, val)
+
+#endif
+
 struct rte_table_array {
+   struct rte_table_stats stats;
+
/* Input parameters */
uint32_t entry_size;
uint32_t n_entries;
@@ -164,7 +180,8 @@ rte_table_array_lookup(
void **entries)
 {
struct rte_table_array *t = (struct rte_table_array *) table;
-
+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_ARRAY_STATS_PKTS_IN_ADD(t, n_pkts_in);
*lookup_hit_mask = pkts_mask;

if ((pkts_mask & (pkts_mask + 1)) == 0) {
@@ -196,10 +213,25 @@ rte_table_array_lookup(
return 0;
 }

+static int
+rte_table_array_stats_read(void *table, struct rte_table_stats *stats, int 
clear)
+{
+   struct rte_table_array *array = (struct rte_table_array *) table;
+
+   if (stats != NULL)
+   memcpy(stats, &array->stats, sizeof(array->stats));
+
+   if (clear)
+   memset(&array->stats, 0, sizeof(array->stats));
+
+   return 0;
+}
+
 struct rte_table_ops rte_table_array_ops = {
.f_create = rte_table_array_create,
.f_free = rte_table_array_free,
.f_add = rte_table_array_entry_add,
.f_delete = NULL,
.f_lookup = rte_table_array_lookup,
+   .f_stats = rte_table_array_stats_read,
 };
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 02/10] table: added acl table stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for ACL table.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_table/rte_table_acl.c |   35 +++
 1 file changed, 35 insertions(+)

diff --git a/lib/librte_table/rte_table_acl.c b/lib/librte_table/rte_table_acl.c
index 4416311..c67622a 100644
--- a/lib/librte_table/rte_table_acl.c
+++ b/lib/librte_table/rte_table_acl.c
@@ -43,7 +43,23 @@
 #include "rte_table_acl.h"
 #include 

+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_TABLE_ACL_STATS_PKTS_IN_ADD(table, val) \
+   table->stats.n_pkts_in += val
+#define RTE_TABLE_ACL_STATS_PKTS_LOOKUP_MISS(table, val) \
+   table->stats.n_pkts_lookup_miss += val
+
+#else
+
+#define RTE_TABLE_ACL_STATS_PKTS_IN_ADD(table, val)
+#define RTE_TABLE_ACL_STATS_PKTS_LOOKUP_MISS(table, val)
+
+#endif
+
 struct rte_table_acl {
+   struct rte_table_stats stats;
+
/* Low-level ACL table */
char name[2][RTE_ACL_NAMESIZE];
struct rte_acl_param acl_params; /* for creating low level acl table */
@@ -441,6 +457,9 @@ rte_table_acl_lookup(
uint64_t pkts_out_mask;
uint32_t n_pkts, i, j;

+   __rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+   RTE_TABLE_ACL_STATS_PKTS_IN_ADD(acl, n_pkts_in);
+
/* Input conversion */
for (i = 0, j = 0; i < (uint32_t)(RTE_PORT_IN_BURST_SIZE_MAX -
__builtin_clzll(pkts_mask)); i++) {
@@ -478,6 +497,21 @@ rte_table_acl_lookup(
}

*lookup_hit_mask = pkts_out_mask;
+   RTE_TABLE_ACL_STATS_PKTS_LOOKUP_MISS(acl, n_pkts_in - 
__builtin_popcountll(pkts_out_mask));
+
+   return 0;
+}
+
+static int
+rte_table_acl_stats_read(void *table, struct rte_table_stats *stats, int clear)
+{
+   struct rte_table_acl *acl = (struct rte_table_acl *) table;
+
+   if (stats != NULL)
+   memcpy(stats, &acl->stats, sizeof(acl->stats));
+
+   if (clear)
+   memset(&acl->stats, 0, sizeof(acl->stats));

return 0;
 }
@@ -488,4 +522,5 @@ struct rte_table_ops rte_table_acl_ops = {
.f_add = rte_table_acl_entry_add,
.f_delete = rte_table_acl_entry_delete,
.f_lookup = rte_table_acl_lookup,
+   .f_stats = rte_table_acl_stats_read,
 };
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 01/10] table: added structure for storing table stats

2015-05-26 Thread Maciej Gajdzica
Added common structure for table statistics.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_table/rte_table.h |   25 +
 1 file changed, 25 insertions(+)

diff --git a/lib/librte_table/rte_table.h b/lib/librte_table/rte_table.h
index 6e51fe6..1732fbf 100644
--- a/lib/librte_table/rte_table.h
+++ b/lib/librte_table/rte_table.h
@@ -59,6 +59,12 @@ extern "C" {

 struct rte_mbuf;

+/** Lookup table statistics */
+struct rte_table_stats {
+   uint64_t n_pkts_in;
+   uint64_t n_pkts_lookup_miss;
+};
+
 /**
  * Lookup table create
  *
@@ -187,6 +193,24 @@ typedef int (*rte_table_op_lookup)(
uint64_t *lookup_hit_mask,
void **entries);

+/**
+ * Lookup table stats read
+ *
+ * @param port
+ *   Handle to lookup table instance
+ * @param stats
+ *   Handle to table stats struct to copy data
+ * @param clear
+ *   Flag indicating that stats should be cleared after read
+ *
+ * @return
+ *   Error code or 0 on success.
+ */
+typedef int (*rte_table_op_stats_read)(
+   void *table,
+   struct rte_table_stats *stats,
+   int clear);
+
 /** Lookup table interface defining the lookup table operation */
 struct rte_table_ops {
rte_table_op_create f_create;   /**< Create */
@@ -194,6 +218,7 @@ struct rte_table_ops {
rte_table_op_entry_add f_add;   /**< Entry add */
rte_table_op_entry_delete f_delete; /**< Entry delete */
rte_table_op_lookup f_lookup;   /**< Lookup */
+   rte_table_op_stats_read f_stats;/**< Stats */
 };

 #ifdef __cplusplus
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 00/10] table: added table statistics

2015-05-26 Thread Maciej Gajdzica
Added statistics for every type of table. By default all table statistics
are disabled, user must activate them in config file.

Changes in v2:
- added missing signoffs

Changes in v3:
- removed new config options to enable/disable stats
- using RTE_LOG_LEVEL instead

Maciej Gajdzica (10):
  table: added structure for storing table stats
  table: added acl table stats
  table: added array table stats
  table: added hash_ext table stats
  table: added hash_key16 table stats
  table: added hash_key32 table stats
  table: added hash_key8 table stats
  table: added hash_lru table stats
  table: added lpm_ipv6 table stats
  table: added lpm table stats

 lib/librte_table/rte_table.h|   25 +++
 lib/librte_table/rte_table_acl.c|   35 +
 lib/librte_table/rte_table_array.c  |   34 +++-
 lib/librte_table/rte_table_hash_ext.c   |   44 ++
 lib/librte_table/rte_table_hash_key16.c |   41 
 lib/librte_table/rte_table_hash_key32.c |   41 
 lib/librte_table/rte_table_hash_key8.c  |   52 +++
 lib/librte_table/rte_table_hash_lru.c   |   44 ++
 lib/librte_table/rte_table_lpm.c|   34 
 lib/librte_table/rte_table_lpm_ipv6.c   |   34 
 10 files changed, 383 insertions(+), 1 deletion(-)

-- 
1.7.9.5



[dpdk-dev] [PATCH v3] pipeline: add statistics for librte_pipeline ports and tables

2015-05-26 Thread Dumitrescu, Cristian


> -Original Message-
> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Maciej Gajdzica
> Sent: Tuesday, May 26, 2015 2:39 PM
> To: dev at dpdk.org
> Subject: [dpdk-dev] [PATCH v3] pipeline: add statistics for librte_pipeline
> ports and tables
> 
> This patch adds statistics collection for librte_pipeline.
> Those statistics ale disabled by default during build time.
> 
> Signed-off-by: Pawel Wodkowski 
> ---
>  lib/librte_pipeline/rte_pipeline.c |  185
> +---
>  lib/librte_pipeline/rte_pipeline.h |   98 +++
>  2 files changed, 272 insertions(+), 11 deletions(-)
> 
> diff --git a/lib/librte_pipeline/rte_pipeline.c
> b/lib/librte_pipeline/rte_pipeline.c
> index 36d92c9..3ef36ad 100644
> --- a/lib/librte_pipeline/rte_pipeline.c
> +++ b/lib/librte_pipeline/rte_pipeline.c
> @@ -48,6 +48,17 @@
> 
>  #define RTE_TABLE_INVALID UINT32_MAX
> 
> +#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
> +#define RTE_PIPELINE_STATS_ADD(counter, val) \
> + ({ (counter) += (val); })
> +
> +#define RTE_PIPELINE_STATS_ADD_M(counter, mask) \
> + ({ (counter) += __builtin_popcountll(mask); })
> +#else
> +#define RTE_PIPELINE_STATS_ADD(counter, val)
> +#define RTE_PIPELINE_STATS_ADD_M(counter, mask)
> +#endif
> +
>  struct rte_port_in {
>   /* Input parameters */
>   struct rte_port_in_ops ops;
> @@ -63,6 +74,8 @@ struct rte_port_in {
> 
>   /* List of enabled ports */
>   struct rte_port_in *next;
> +
> + uint64_t n_pkts_dropped_by_ah;
>  };
> 
>  struct rte_port_out {
> @@ -74,6 +87,8 @@ struct rte_port_out {
> 
>   /* Handle to low-level port */
>   void *h_port;
> +
> + uint64_t n_pkts_dropped_by_ah;
>  };
> 
>  struct rte_table {
> @@ -90,6 +105,12 @@ struct rte_table {
> 
>   /* Handle to the low-level table object */
>   void *h_table;
> +
> + /* Stats for this table. */
> + uint64_t n_pkts_dropped_by_lkp_hit_ah;
> + uint64_t n_pkts_dropped_by_lkp_miss_ah;
> + uint64_t n_pkts_dropped_lkp_hit;
> + uint64_t n_pkts_dropped_lkp_miss;
>  };
> 
>  #define RTE_PIPELINE_MAX_NAME_SZ   124
> @@ -1040,6 +1061,8 @@ rte_pipeline_action_handler_port_bulk(struct
> rte_pipeline *p,
> 
>   port_out->f_action_bulk(p->pkts, &pkts_mask, port_out-
> >arg_ah);
>   p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
> pkts_mask ^  mask;
> + RTE_PIPELINE_STATS_ADD_M(port_out-
> >n_pkts_dropped_by_ah,
> + pkts_mask ^  mask);
>   }
> 
>   /* Output port TX */
> @@ -1071,6 +1094,9 @@ rte_pipeline_action_handler_port(struct
> rte_pipeline *p, uint64_t pkts_mask)
>   p-
> >action_mask0[RTE_PIPELINE_ACTION_DROP] |=
>   (pkt_mask ^ 1LLU) << i;
> 
> + RTE_PIPELINE_STATS_ADD(port_out-
> >n_pkts_dropped_by_ah,
> + pkt_mask ^ 1LLU);
> +
>   /* Output port TX */
>   if (pkt_mask != 0)
>   port_out->ops.f_tx(port_out-
> >h_port,
> @@ -1104,6 +1130,9 @@ rte_pipeline_action_handler_port(struct
> rte_pipeline *p, uint64_t pkts_mask)
>   p-
> >action_mask0[RTE_PIPELINE_ACTION_DROP] |=
>   (pkt_mask ^ 1LLU) << i;
> 
> + RTE_PIPELINE_STATS_ADD(port_out-
> >n_pkts_dropped_by_ah,
> + pkt_mask ^ 1LLU);
> +
>   /* Output port TX */
>   if (pkt_mask != 0)
>   port_out->ops.f_tx(port_out-
> >h_port,
> @@ -1140,6 +1169,9 @@ rte_pipeline_action_handler_port_meta(struct
> rte_pipeline *p,
>   p-
> >action_mask0[RTE_PIPELINE_ACTION_DROP] |=
>   (pkt_mask ^ 1LLU) << i;
> 
> + RTE_PIPELINE_STATS_ADD(port_out-
> >n_pkts_dropped_by_ah,
> + pkt_mask ^ 1ULL);
> +
>   /* Output port TX */
>   if (pkt_mask != 0)
>   port_out->ops.f_tx(port_out-
> >h_port,
> @@ -1174,6 +1206,9 @@ rte_pipeline_action_handler_port_meta(struct
> rte_pipeline *p,
>   p-
> >action_mask0[RTE_PIPELINE_ACTION_DROP] |=
>   (pkt_mask ^ 1LLU) << i;
> 
> + RTE_PIPELINE_STATS_ADD(port_out-
> >n_pkts_dropped_by_ah,
> + pkt_mask ^ 1ULL);
> +
>   /* Output port TX */
>   if (pkt_mask != 0)
>   port_out->ops.f_tx(port_out-
> >h_port,
> @@ -1232,10 +1267,10 @@ rte_pipeline_run(struct rte_

[dpdk-dev] [PATCH v3 00/10] table: added table statistics

2015-05-26 Thread Dumitrescu, Cristian


> -Original Message-
> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Maciej Gajdzica
> Sent: Tuesday, May 26, 2015 1:40 PM
> To: dev at dpdk.org
> Subject: [dpdk-dev] [PATCH v3 00/10] table: added table statistics
> 
> Added statistics for every type of table. By default all table statistics
> are disabled, user must activate them in config file.
> 
> Changes in v2:
>   - added missing signoffs
> 
> Changes in v3:
>   - removed new config options to enable/disable stats
>   - using RTE_LOG_LEVEL instead
> 
> Maciej Gajdzica (10):
>   table: added structure for storing table stats
>   table: added acl table stats
>   table: added array table stats
>   table: added hash_ext table stats
>   table: added hash_key16 table stats
>   table: added hash_key32 table stats
>   table: added hash_key8 table stats
>   table: added hash_lru table stats
>   table: added lpm_ipv6 table stats
>   table: added lpm table stats
> 
>  lib/librte_table/rte_table.h|   25 +++
>  lib/librte_table/rte_table_acl.c|   35 +
>  lib/librte_table/rte_table_array.c  |   34 +++-
>  lib/librte_table/rte_table_hash_ext.c   |   44
> ++
>  lib/librte_table/rte_table_hash_key16.c |   41
> 
>  lib/librte_table/rte_table_hash_key32.c |   41
> 
>  lib/librte_table/rte_table_hash_key8.c  |   52
> +++
>  lib/librte_table/rte_table_hash_lru.c   |   44
> ++
>  lib/librte_table/rte_table_lpm.c|   34 
>  lib/librte_table/rte_table_lpm_ipv6.c   |   34 
>  10 files changed, 383 insertions(+), 1 deletion(-)
> 
> --
> 1.7.9.5

Acked-by: Cristian Dumitrescu 



[dpdk-dev] [PATCH v3 13/13] port: added port_sink stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for sink port.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_port/rte_port_source_sink.c |   63 ++--
 1 file changed, 59 insertions(+), 4 deletions(-)

diff --git a/lib/librte_port/rte_port_source_sink.c 
b/lib/librte_port/rte_port_source_sink.c
index c36adb9..ee727dd 100644
--- a/lib/librte_port/rte_port_source_sink.c
+++ b/lib/librte_port/rte_port_source_sink.c
@@ -133,28 +133,64 @@ rte_port_source_stats_read(void *port,
 /*
  * Port SINK
  */
+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_PORT_SINK_STATS_PKTS_IN_ADD(port, val) \
+   port->stats.n_pkts_in += val
+#define RTE_PORT_SINK_STATS_PKTS_DROP_ADD(port, val) \
+   port->stats.n_pkts_drop += val
+
+#else
+
+#define RTE_PORT_SINK_STATS_PKTS_IN_ADD(port, val)
+#define RTE_PORT_SINK_STATS_PKTS_DROP_ADD(port, val)
+
+#endif
+
+struct rte_port_sink {
+   struct rte_port_out_stats stats;
+};
+
 static void *
-rte_port_sink_create(__rte_unused void *params, __rte_unused int socket_id)
+rte_port_sink_create(__rte_unused void *params, int socket_id)
 {
-   return (void *) 1;
+   struct rte_port_sink *port;
+
+   /* Memory allocation */
+   port = rte_zmalloc_socket("PORT", sizeof(*port),
+   RTE_CACHE_LINE_SIZE, socket_id);
+   if (port == NULL) {
+   RTE_LOG(ERR, PORT, "%s: Failed to allocate port\n", __func__);
+   return NULL;
+   }
+
+   return port;
 }

 static int
-rte_port_sink_tx(__rte_unused void *port, struct rte_mbuf *pkt)
+rte_port_sink_tx(void *port, struct rte_mbuf *pkt)
 {
+   __rte_unused struct rte_port_sink *p = (struct rte_port_sink *) port;
+
+   RTE_PORT_SINK_STATS_PKTS_IN_ADD(p, 1);
rte_pktmbuf_free(pkt);
+   RTE_PORT_SINK_STATS_PKTS_DROP_ADD(p, 1);

return 0;
 }

 static int
-rte_port_sink_tx_bulk(__rte_unused void *port, struct rte_mbuf **pkts,
+rte_port_sink_tx_bulk(void *port, struct rte_mbuf **pkts,
uint64_t pkts_mask)
 {
+   __rte_unused struct rte_port_sink *p = (struct rte_port_sink *) port;
+
if ((pkts_mask & (pkts_mask + 1)) == 0) {
uint64_t n_pkts = __builtin_popcountll(pkts_mask);
uint32_t i;

+   RTE_PORT_SINK_STATS_PKTS_IN_ADD(p, n_pkts);
+   RTE_PORT_SINK_STATS_PKTS_DROP_ADD(p, n_pkts);
for (i = 0; i < n_pkts; i++) {
struct rte_mbuf *pkt = pkts[i];

@@ -166,6 +202,8 @@ rte_port_sink_tx_bulk(__rte_unused void *port, struct 
rte_mbuf **pkts,
uint64_t pkt_mask = 1LLU << pkt_index;
struct rte_mbuf *pkt = pkts[pkt_index];

+   RTE_PORT_SINK_STATS_PKTS_IN_ADD(p, 1);
+   RTE_PORT_SINK_STATS_PKTS_DROP_ADD(p, 1);
rte_pktmbuf_free(pkt);
pkts_mask &= ~pkt_mask;
}
@@ -174,6 +212,22 @@ rte_port_sink_tx_bulk(__rte_unused void *port, struct 
rte_mbuf **pkts,
return 0;
 }

+static int
+rte_port_sink_stats_read(void *port, struct rte_port_out_stats *stats,
+   int clear)
+{
+   struct rte_port_sink *p =
+   (struct rte_port_sink *) port;
+
+   if (stats != NULL)
+   memcpy(stats, &p->stats, sizeof(p->stats));
+
+   if (clear)
+   memset(&p->stats, 0, sizeof(p->stats));
+
+   return 0;
+}
+
 /*
  * Summary of port operations
  */
@@ -190,4 +244,5 @@ struct rte_port_out_ops rte_port_sink_ops = {
.f_tx = rte_port_sink_tx,
.f_tx_bulk = rte_port_sink_tx_bulk,
.f_flush = NULL,
+   .f_stats = rte_port_sink_stats_read,
 };
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 12/13] port: added port_source stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for source port.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_port/rte_port_source_sink.c |   35 
 1 file changed, 35 insertions(+)

diff --git a/lib/librte_port/rte_port_source_sink.c 
b/lib/librte_port/rte_port_source_sink.c
index b9a25bb..c36adb9 100644
--- a/lib/librte_port/rte_port_source_sink.c
+++ b/lib/librte_port/rte_port_source_sink.c
@@ -42,7 +42,23 @@
 /*
  * Port SOURCE
  */
+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(port, val) \
+   port->stats.n_pkts_in += val
+#define RTE_PORT_SOURCE_STATS_PKTS_DROP_ADD(port, val) \
+   port->stats.n_pkts_drop += val
+
+#else
+
+#define RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(port, val)
+#define RTE_PORT_SOURCE_STATS_PKTS_DROP_ADD(port, val)
+
+#endif
+
 struct rte_port_source {
+   struct rte_port_in_stats stats;
+
struct rte_mempool *mempool;
 };

@@ -93,9 +109,27 @@ rte_port_source_rx(void *port, struct rte_mbuf **pkts, 
uint32_t n_pkts)
if (rte_mempool_get_bulk(p->mempool, (void **) pkts, n_pkts) != 0)
return 0;

+   RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(p, n_pkts);
+
return n_pkts;
 }

+static int
+rte_port_source_stats_read(void *port,
+   struct rte_port_in_stats *stats, int clear)
+{
+   struct rte_port_source *p =
+   (struct rte_port_source *) port;
+
+   if (stats != NULL)
+   memcpy(stats, &p->stats, sizeof(p->stats));
+
+   if (clear)
+   memset(&p->stats, 0, sizeof(p->stats));
+
+   return 0;
+}
+
 /*
  * Port SINK
  */
@@ -147,6 +181,7 @@ struct rte_port_in_ops rte_port_source_ops = {
.f_create = rte_port_source_create,
.f_free = rte_port_source_free,
.f_rx = rte_port_source_rx,
+   .f_stats = rte_port_source_stats_read,
 };

 struct rte_port_out_ops rte_port_sink_ops = {
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 11/13] port: added port_sched_writer stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for sched writer port.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_port/rte_port_sched.c |   57 ++
 1 file changed, 52 insertions(+), 5 deletions(-)

diff --git a/lib/librte_port/rte_port_sched.c b/lib/librte_port/rte_port_sched.c
index df774df..3db8a92 100644
--- a/lib/librte_port/rte_port_sched.c
+++ b/lib/librte_port/rte_port_sched.c
@@ -132,7 +132,23 @@ rte_port_sched_reader_stats_read(void *port,
 /*
  * Writer
  */
+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(port, val) \
+   port->stats.n_pkts_in += val
+#define RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(port, val) \
+   port->stats.n_pkts_drop += val
+
+#else
+
+#define RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(port, val)
+#define RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(port, val)
+
+#endif
+
 struct rte_port_sched_writer {
+   struct rte_port_out_stats stats;
+
struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
struct rte_sched_port *sched;
uint32_t tx_burst_sz;
@@ -180,8 +196,12 @@ rte_port_sched_writer_tx(void *port, struct rte_mbuf *pkt)
struct rte_port_sched_writer *p = (struct rte_port_sched_writer *) port;

p->tx_buf[p->tx_buf_count++] = pkt;
+   RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(p, 1);
if (p->tx_buf_count >= p->tx_burst_sz) {
-   rte_sched_port_enqueue(p->sched, p->tx_buf, p->tx_buf_count);
+   __rte_unused uint32_t nb_tx;
+
+   nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf, 
p->tx_buf_count);
+   RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - 
nb_tx);
p->tx_buf_count = 0;
}

@@ -200,15 +220,18 @@ rte_port_sched_writer_tx_bulk(void *port,
((pkts_mask & bsz_mask) ^ bsz_mask);

if (expr == 0) {
+   __rte_unused uint32_t nb_tx;
uint64_t n_pkts = __builtin_popcountll(pkts_mask);

if (tx_buf_count) {
-   rte_sched_port_enqueue(p->sched, p->tx_buf,
+   nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf,
tx_buf_count);
+   RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, 
tx_buf_count - nb_tx);
p->tx_buf_count = 0;
}

-   rte_sched_port_enqueue(p->sched, pkts, n_pkts);
+   nb_tx = rte_sched_port_enqueue(p->sched, pkts, n_pkts);
+   RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - nb_tx);
} else {
for ( ; pkts_mask; ) {
uint32_t pkt_index = __builtin_ctzll(pkts_mask);
@@ -216,13 +239,17 @@ rte_port_sched_writer_tx_bulk(void *port,
struct rte_mbuf *pkt = pkts[pkt_index];

p->tx_buf[tx_buf_count++] = pkt;
+   RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(p, 1);
pkts_mask &= ~pkt_mask;
}
p->tx_buf_count = tx_buf_count;

if (tx_buf_count >= p->tx_burst_sz) {
-   rte_sched_port_enqueue(p->sched, p->tx_buf,
+   __rte_unused uint32_t nb_tx;
+
+   nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf,
tx_buf_count);
+   RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, 
tx_buf_count - nb_tx);
p->tx_buf_count = 0;
}
}
@@ -236,7 +263,10 @@ rte_port_sched_writer_flush(void *port)
struct rte_port_sched_writer *p = (struct rte_port_sched_writer *) port;

if (p->tx_buf_count) {
-   rte_sched_port_enqueue(p->sched, p->tx_buf, p->tx_buf_count);
+   __rte_unused uint32_t nb_tx;
+
+   nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf, 
p->tx_buf_count);
+   RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - 
nb_tx);
p->tx_buf_count = 0;
}

@@ -257,6 +287,22 @@ rte_port_sched_writer_free(void *port)
return 0;
 }

+static int
+rte_port_sched_writer_stats_read(void *port,
+   struct rte_port_out_stats *stats, int clear)
+{
+   struct rte_port_sched_writer *p =
+   (struct rte_port_sched_writer *) port;
+
+   if (stats != NULL)
+   memcpy(stats, &p->stats, sizeof(p->stats));
+
+   if (clear)
+   memset(&p->stats, 0, sizeof(p->stats));
+
+   return 0;
+}
+
 /*
  * Summary of port operations
  */
@@ -273,4 +319,5 @@ struct rte_port_out_ops rte_port_sched_writer_ops = {
.f_tx = rte_port_sched_writer_tx,
.f_tx_bulk = rte_port_sched_writer_tx_bulk,
.f_flush = rte_port_sched_writer_flush,
+   .f_stats = rte_port_sched_writer_stats_read,
 };
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 10/13] port: added port_sched_reader stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for sched reader port.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_port/rte_port_sched.c |   39 +-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/lib/librte_port/rte_port_sched.c b/lib/librte_port/rte_port_sched.c
index 2107f4c..df774df 100644
--- a/lib/librte_port/rte_port_sched.c
+++ b/lib/librte_port/rte_port_sched.c
@@ -40,7 +40,23 @@
 /*
  * Reader
  */
+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_PORT_SCHED_READER_PKTS_IN_ADD(port, val) \
+   port->stats.n_pkts_in += val
+#define RTE_PORT_SCHED_READER_PKTS_DROP_ADD(port, val) \
+   port->stats.n_pkts_drop += val
+
+#else
+
+#define RTE_PORT_SCHED_READER_PKTS_IN_ADD(port, val)
+#define RTE_PORT_SCHED_READER_PKTS_DROP_ADD(port, val)
+
+#endif
+
 struct rte_port_sched_reader {
+   struct rte_port_in_stats stats;
+
struct rte_sched_port *sched;
 };

@@ -76,8 +92,12 @@ static int
 rte_port_sched_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
 {
struct rte_port_sched_reader *p = (struct rte_port_sched_reader *) port;
+   uint32_t nb_rx;

-   return rte_sched_port_dequeue(p->sched, pkts, n_pkts);
+   nb_rx = rte_sched_port_dequeue(p->sched, pkts, n_pkts);
+   RTE_PORT_SCHED_READER_PKTS_IN_ADD(p, nb_rx);
+
+   return nb_rx;
 }

 static int
@@ -93,6 +113,22 @@ rte_port_sched_reader_free(void *port)
return 0;
 }

+static int
+rte_port_sched_reader_stats_read(void *port,
+   struct rte_port_in_stats *stats, int clear)
+{
+   struct rte_port_sched_reader *p =
+   (struct rte_port_sched_reader *) port;
+
+   if (stats != NULL)
+   memcpy(stats, &p->stats, sizeof(p->stats));
+
+   if (clear)
+   memset(&p->stats, 0, sizeof(p->stats));
+
+   return 0;
+}
+
 /*
  * Writer
  */
@@ -228,6 +264,7 @@ struct rte_port_in_ops rte_port_sched_reader_ops = {
.f_create = rte_port_sched_reader_create,
.f_free = rte_port_sched_reader_free,
.f_rx = rte_port_sched_reader_rx,
+   .f_stats = rte_port_sched_reader_stats_read,
 };

 struct rte_port_out_ops rte_port_sched_writer_ops = {
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 09/13] port: added port_ring_writer_nodrop stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for ring writer nodrop port.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_port/rte_port_ring.c |   37 +
 1 file changed, 37 insertions(+)

diff --git a/lib/librte_port/rte_port_ring.c b/lib/librte_port/rte_port_ring.c
index 9fdd7d5..2e7f2f1 100644
--- a/lib/librte_port/rte_port_ring.c
+++ b/lib/librte_port/rte_port_ring.c
@@ -309,7 +309,23 @@ rte_port_ring_writer_stats_read(void *port,
 /*
  * Port RING Writer Nodrop
  */
+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
+   port->stats.n_pkts_in += val
+#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
+   port->stats.n_pkts_drop += val
+
+#else
+
+#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
+#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
+
+#endif
+
 struct rte_port_ring_writer_nodrop {
+   struct rte_port_out_stats stats;
+
struct rte_mbuf *tx_buf[RTE_PORT_IN_BURST_SIZE_MAX];
struct rte_ring *ring;
uint32_t tx_burst_sz;
@@ -379,6 +395,7 @@ send_burst_nodrop(struct rte_port_ring_writer_nodrop *p)
}

/* We didn't send the packets in maximum allowed attempts */
+   RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - 
nb_tx);
for ( ; nb_tx < p->tx_buf_count; nb_tx++)
rte_pktmbuf_free(p->tx_buf[nb_tx]);

@@ -392,6 +409,7 @@ rte_port_ring_writer_nodrop_tx(void *port, struct rte_mbuf 
*pkt)
(struct rte_port_ring_writer_nodrop *) port;

p->tx_buf[p->tx_buf_count++] = pkt;
+   RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
if (p->tx_buf_count >= p->tx_burst_sz)
send_burst_nodrop(p);

@@ -418,6 +436,7 @@ rte_port_ring_writer_nodrop_tx_bulk(void *port,
if (tx_buf_count)
send_burst_nodrop(p);

+   RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
n_pkts_ok = rte_ring_sp_enqueue_burst(p->ring, (void **)pkts, 
n_pkts);

if (n_pkts_ok >= n_pkts)
@@ -439,6 +458,7 @@ rte_port_ring_writer_nodrop_tx_bulk(void *port,
struct rte_mbuf *pkt = pkts[pkt_index];

p->tx_buf[tx_buf_count++] = pkt;
+   RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
pkts_mask &= ~pkt_mask;
}

@@ -476,6 +496,22 @@ rte_port_ring_writer_nodrop_free(void *port)
return 0;
 }

+static int
+rte_port_ring_writer_nodrop_stats_read(void *port,
+   struct rte_port_out_stats *stats, int clear)
+{
+   struct rte_port_ring_writer_nodrop *p =
+   (struct rte_port_ring_writer_nodrop *) port;
+
+   if (stats != NULL)
+   memcpy(stats, &p->stats, sizeof(p->stats));
+
+   if (clear)
+   memset(&p->stats, 0, sizeof(p->stats));
+
+   return 0;
+}
+
 /*
  * Summary of port operations
  */
@@ -501,4 +537,5 @@ struct rte_port_out_ops rte_port_ring_writer_nodrop_ops = {
.f_tx = rte_port_ring_writer_nodrop_tx,
.f_tx_bulk = rte_port_ring_writer_nodrop_tx_bulk,
.f_flush = rte_port_ring_writer_nodrop_flush,
+   .f_stats = rte_port_ring_writer_nodrop_stats_read,
 };
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 08/13] port: added port_ring_writer stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for port writer port.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_port/rte_port_ring.c |   38 ++
 1 file changed, 38 insertions(+)

diff --git a/lib/librte_port/rte_port_ring.c b/lib/librte_port/rte_port_ring.c
index e35a611..9fdd7d5 100644
--- a/lib/librte_port/rte_port_ring.c
+++ b/lib/librte_port/rte_port_ring.c
@@ -133,7 +133,23 @@ rte_port_ring_reader_stats_read(void *port,
 /*
  * Port RING Writer
  */
+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(port, val) \
+   port->stats.n_pkts_in += val
+#define RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(port, val) \
+   port->stats.n_pkts_drop += val
+
+#else
+
+#define RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(port, val)
+#define RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(port, val)
+
+#endif
+
 struct rte_port_ring_writer {
+   struct rte_port_out_stats stats;
+
struct rte_mbuf *tx_buf[RTE_PORT_IN_BURST_SIZE_MAX];
struct rte_ring *ring;
uint32_t tx_burst_sz;
@@ -181,6 +197,7 @@ send_burst(struct rte_port_ring_writer *p)
nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
p->tx_buf_count);

+   RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
for ( ; nb_tx < p->tx_buf_count; nb_tx++)
rte_pktmbuf_free(p->tx_buf[nb_tx]);

@@ -193,6 +210,7 @@ rte_port_ring_writer_tx(void *port, struct rte_mbuf *pkt)
struct rte_port_ring_writer *p = (struct rte_port_ring_writer *) port;

p->tx_buf[p->tx_buf_count++] = pkt;
+   RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
if (p->tx_buf_count >= p->tx_burst_sz)
send_burst(p);

@@ -219,8 +237,10 @@ rte_port_ring_writer_tx_bulk(void *port,
if (tx_buf_count)
send_burst(p);

+   RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
n_pkts_ok = rte_ring_sp_enqueue_burst(p->ring, (void **)pkts, 
n_pkts);

+   RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - n_pkts_ok);
for ( ; n_pkts_ok < n_pkts; n_pkts_ok++) {
struct rte_mbuf *pkt = pkts[n_pkts_ok];

@@ -233,6 +253,7 @@ rte_port_ring_writer_tx_bulk(void *port,
struct rte_mbuf *pkt = pkts[pkt_index];

p->tx_buf[tx_buf_count++] = pkt;
+   RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
pkts_mask &= ~pkt_mask;
}

@@ -269,6 +290,22 @@ rte_port_ring_writer_free(void *port)
return 0;
 }

+static int
+rte_port_ring_writer_stats_read(void *port,
+   struct rte_port_out_stats *stats, int clear)
+{
+   struct rte_port_ring_writer *p =
+   (struct rte_port_ring_writer *) port;
+
+   if (stats != NULL)
+   memcpy(stats, &p->stats, sizeof(p->stats));
+
+   if (clear)
+   memset(&p->stats, 0, sizeof(p->stats));
+
+   return 0;
+}
+
 /*
  * Port RING Writer Nodrop
  */
@@ -455,6 +492,7 @@ struct rte_port_out_ops rte_port_ring_writer_ops = {
.f_tx = rte_port_ring_writer_tx,
.f_tx_bulk = rte_port_ring_writer_tx_bulk,
.f_flush = rte_port_ring_writer_flush,
+   .f_stats = rte_port_ring_writer_stats_read,
 };

 struct rte_port_out_ops rte_port_ring_writer_nodrop_ops = {
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 07/13] port: added port_ring_reader stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for ring reader port.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_port/rte_port_ring.c |   39 ++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/lib/librte_port/rte_port_ring.c b/lib/librte_port/rte_port_ring.c
index 89b9641..e35a611 100644
--- a/lib/librte_port/rte_port_ring.c
+++ b/lib/librte_port/rte_port_ring.c
@@ -42,7 +42,23 @@
 /*
  * Port RING Reader
  */
+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(port, val) \
+   port->stats.n_pkts_in += val
+#define RTE_PORT_RING_READER_STATS_PKTS_DROP_ADD(port, val) \
+   port->stats.n_pkts_drop += val
+
+#else
+
+#define RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(port, val)
+#define RTE_PORT_RING_READER_STATS_PKTS_DROP_ADD(port, val)
+
+#endif
+
 struct rte_port_ring_reader {
+   struct rte_port_in_stats stats;
+
struct rte_ring *ring;
 };

@@ -77,8 +93,12 @@ static int
 rte_port_ring_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
 {
struct rte_port_ring_reader *p = (struct rte_port_ring_reader *) port;
+   uint32_t nb_rx;

-   return rte_ring_sc_dequeue_burst(p->ring, (void **) pkts, n_pkts);
+   nb_rx = rte_ring_sc_dequeue_burst(p->ring, (void **) pkts, n_pkts);
+   RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(p, nb_rx);
+
+   return nb_rx;
 }

 static int
@@ -94,6 +114,22 @@ rte_port_ring_reader_free(void *port)
return 0;
 }

+static int
+rte_port_ring_reader_stats_read(void *port,
+   struct rte_port_in_stats *stats, int clear)
+{
+   struct rte_port_ring_reader *p =
+   (struct rte_port_ring_reader *) port;
+
+   if (stats != NULL)
+   memcpy(stats, &p->stats, sizeof(p->stats));
+
+   if (clear)
+   memset(&p->stats, 0, sizeof(p->stats));
+
+   return 0;
+}
+
 /*
  * Port RING Writer
  */
@@ -410,6 +446,7 @@ struct rte_port_in_ops rte_port_ring_reader_ops = {
.f_create = rte_port_ring_reader_create,
.f_free = rte_port_ring_reader_free,
.f_rx = rte_port_ring_reader_rx,
+   .f_stats = rte_port_ring_reader_stats_read,
 };

 struct rte_port_out_ops rte_port_ring_writer_ops = {
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 06/13] port: added port_ras stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for IPv4 and IPv6 reassembly ports.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_port/rte_port_ras.c |   38 ++
 1 file changed, 38 insertions(+)

diff --git a/lib/librte_port/rte_port_ras.c b/lib/librte_port/rte_port_ras.c
index 5eb627a..a06674b 100644
--- a/lib/librte_port/rte_port_ras.c
+++ b/lib/librte_port/rte_port_ras.c
@@ -51,6 +51,20 @@
 #define RTE_PORT_RAS_N_ENTRIES (RTE_PORT_RAS_N_BUCKETS * 
RTE_PORT_RAS_N_ENTRIES_PER_BUCKET)
 #endif

+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(port, val) \
+   port->stats.n_pkts_in += val
+#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_DROP_ADD(port, val) \
+   port->stats.n_pkts_drop += val
+
+#else
+
+#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(port, val)
+#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_DROP_ADD(port, val)
+
+#endif
+
 struct rte_port_ring_writer_ras;

 typedef void (*ras_op)(
@@ -63,6 +77,8 @@ static void
 process_ipv6(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt);

 struct rte_port_ring_writer_ras {
+   struct rte_port_out_stats stats;
+
struct rte_mbuf *tx_buf[RTE_PORT_IN_BURST_SIZE_MAX];
struct rte_ring *ring;
uint32_t tx_burst_sz;
@@ -153,6 +169,7 @@ send_burst(struct rte_port_ring_writer_ras *p)
nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
p->tx_buf_count);

+   RTE_PORT_RING_WRITER_RAS_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - 
nb_tx);
for ( ; nb_tx < p->tx_buf_count; nb_tx++)
rte_pktmbuf_free(p->tx_buf[nb_tx]);

@@ -225,6 +242,7 @@ rte_port_ring_writer_ras_tx(void *port, struct rte_mbuf 
*pkt)
struct rte_port_ring_writer_ras *p =
(struct rte_port_ring_writer_ras *) port;

+   RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(p, 1);
p->f_ras(p, pkt);
if (p->tx_buf_count >= p->tx_burst_sz)
send_burst(p);
@@ -247,6 +265,7 @@ rte_port_ring_writer_ras_tx_bulk(void *port,
for (i = 0; i < n_pkts; i++) {
struct rte_mbuf *pkt = pkts[i];

+   RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(p, 1);
p->f_ras(p, pkt);
if (p->tx_buf_count >= p->tx_burst_sz)
send_burst(p);
@@ -257,6 +276,7 @@ rte_port_ring_writer_ras_tx_bulk(void *port,
uint64_t pkt_mask = 1LLU << pkt_index;
struct rte_mbuf *pkt = pkts[pkt_index];

+   RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(p, 1);
p->f_ras(p, pkt);
if (p->tx_buf_count >= p->tx_burst_sz)
send_burst(p);
@@ -298,6 +318,22 @@ rte_port_ring_writer_ras_free(void *port)
return 0;
 }

+static int
+rte_port_ras_writer_stats_read(void *port,
+   struct rte_port_out_stats *stats, int clear)
+{
+   struct rte_port_ring_writer_ras *p =
+   (struct rte_port_ring_writer_ras *) port;
+
+   if (stats != NULL)
+   memcpy(stats, &p->stats, sizeof(p->stats));
+
+   if (clear)
+   memset(&p->stats, 0, sizeof(p->stats));
+
+   return 0;
+}
+
 /*
  * Summary of port operations
  */
@@ -307,6 +343,7 @@ struct rte_port_out_ops rte_port_ring_writer_ipv4_ras_ops = 
{
.f_tx = rte_port_ring_writer_ras_tx,
.f_tx_bulk = rte_port_ring_writer_ras_tx_bulk,
.f_flush = rte_port_ring_writer_ras_flush,
+   .f_stats = rte_port_ras_writer_stats_read,
 };

 struct rte_port_out_ops rte_port_ring_writer_ipv6_ras_ops = {
@@ -315,4 +352,5 @@ struct rte_port_out_ops rte_port_ring_writer_ipv6_ras_ops = 
{
.f_tx = rte_port_ring_writer_ras_tx,
.f_tx_bulk = rte_port_ring_writer_ras_tx_bulk,
.f_flush = rte_port_ring_writer_ras_flush,
+   .f_stats = rte_port_ras_writer_stats_read,
 };
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 05/13] port: added port_frag stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for IPv4 and IPv6 fragmentation ports.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_port/rte_port_frag.c |   36 
 1 file changed, 36 insertions(+)

diff --git a/lib/librte_port/rte_port_frag.c b/lib/librte_port/rte_port_frag.c
index c4c05dc..3b06eb8 100644
--- a/lib/librte_port/rte_port_frag.c
+++ b/lib/librte_port/rte_port_frag.c
@@ -41,6 +41,20 @@
 /* Max number of fragments per packet allowed */
 #defineRTE_PORT_FRAG_MAX_FRAGS_PER_PACKET 0x80

+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_IN_ADD(port, val) \
+   port->stats.n_pkts_in += val
+#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_DROP_ADD(port, val) \
+   port->stats.n_pkts_drop += val
+
+#else
+
+#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_IN_ADD(port, val)
+#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_DROP_ADD(port, val)
+
+#endif
+
 typedef int32_t
(*frag_op)(struct rte_mbuf *pkt_in,
struct rte_mbuf **pkts_out,
@@ -50,6 +64,8 @@ typedef int32_t
struct rte_mempool *pool_indirect);

 struct rte_port_ring_reader_frag {
+   struct rte_port_in_stats stats;
+
/* Input parameters */
struct rte_ring *ring;
uint32_t mtu;
@@ -171,6 +187,7 @@ rte_port_ring_reader_frag_rx(void *port,
if (p->n_pkts == 0) {
p->n_pkts = rte_ring_sc_dequeue_burst(p->ring,
(void **) p->pkts, RTE_PORT_IN_BURST_SIZE_MAX);
+   RTE_PORT_RING_READER_FRAG_STATS_PKTS_IN_ADD(p, 
p->n_pkts);
if (p->n_pkts == 0)
return n_pkts_out;
p->pos_pkts = 0;
@@ -203,6 +220,7 @@ rte_port_ring_reader_frag_rx(void *port,

if (status < 0) {
rte_pktmbuf_free(pkt);
+   RTE_PORT_RING_READER_FRAG_STATS_PKTS_DROP_ADD(p, 1);
continue;
}

@@ -252,6 +270,22 @@ rte_port_ring_reader_frag_free(void *port)
return 0;
 }

+static int
+rte_port_frag_reader_stats_read(void *port,
+   struct rte_port_in_stats *stats, int clear)
+{
+   struct rte_port_ring_reader_frag *p =
+   (struct rte_port_ring_reader_frag *) port;
+
+   if (stats != NULL)
+   memcpy(stats, &p->stats, sizeof(p->stats));
+
+   if (clear)
+   memset(&p->stats, 0, sizeof(p->stats));
+
+   return 0;
+}
+
 /*
  * Summary of port operations
  */
@@ -259,10 +293,12 @@ struct rte_port_in_ops rte_port_ring_reader_ipv4_frag_ops 
= {
.f_create = rte_port_ring_reader_ipv4_frag_create,
.f_free = rte_port_ring_reader_frag_free,
.f_rx = rte_port_ring_reader_frag_rx,
+   .f_stats = rte_port_frag_reader_stats_read,
 };

 struct rte_port_in_ops rte_port_ring_reader_ipv6_frag_ops = {
.f_create = rte_port_ring_reader_ipv6_frag_create,
.f_free = rte_port_ring_reader_frag_free,
.f_rx = rte_port_ring_reader_frag_rx,
+   .f_stats = rte_port_frag_reader_stats_read,
 };
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 04/13] port: added port_ethdev_writer_nodrop stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for ethdev writer nodrop port.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_port/rte_port_ethdev.c |   36 
 1 file changed, 36 insertions(+)

diff --git a/lib/librte_port/rte_port_ethdev.c 
b/lib/librte_port/rte_port_ethdev.c
index af3e9d4..8b94afd 100644
--- a/lib/librte_port/rte_port_ethdev.c
+++ b/lib/librte_port/rte_port_ethdev.c
@@ -314,7 +314,23 @@ static int rte_port_ethdev_writer_stats_read(void *port,
 /*
  * Port ETHDEV Writer Nodrop
  */
+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
+   port->stats.n_pkts_in += val
+#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
+   port->stats.n_pkts_drop += val
+
+#else
+
+#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
+#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
+
+#endif
+
 struct rte_port_ethdev_writer_nodrop {
+   struct rte_port_out_stats stats;
+
struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
uint32_t tx_burst_sz;
uint16_t tx_buf_count;
@@ -387,6 +403,7 @@ send_burst_nodrop(struct rte_port_ethdev_writer_nodrop *p)
}

/* We didn't send the packets in maximum allowed attempts */
+   RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - 
nb_tx);
for ( ; nb_tx < p->tx_buf_count; nb_tx++)
rte_pktmbuf_free(p->tx_buf[nb_tx]);

@@ -400,6 +417,7 @@ rte_port_ethdev_writer_nodrop_tx(void *port, struct 
rte_mbuf *pkt)
(struct rte_port_ethdev_writer_nodrop *) port;

p->tx_buf[p->tx_buf_count++] = pkt;
+   RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
if (p->tx_buf_count >= p->tx_burst_sz)
send_burst_nodrop(p);

@@ -426,6 +444,7 @@ rte_port_ethdev_writer_nodrop_tx_bulk(void *port,
if (tx_buf_count)
send_burst_nodrop(p);

+   RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
n_pkts_ok = rte_eth_tx_burst(p->port_id, p->queue_id, pkts,
n_pkts);

@@ -448,6 +467,7 @@ rte_port_ethdev_writer_nodrop_tx_bulk(void *port,
struct rte_mbuf *pkt = pkts[pkt_index];

p->tx_buf[tx_buf_count++] = pkt;
+   RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
pkts_mask &= ~pkt_mask;
}

@@ -485,6 +505,21 @@ rte_port_ethdev_writer_nodrop_free(void *port)
return 0;
 }

+static int rte_port_ethdev_writer_nodrop_stats_read(void *port,
+   struct rte_port_out_stats *stats, int clear)
+{
+   struct rte_port_ethdev_writer_nodrop *p =
+   (struct rte_port_ethdev_writer_nodrop *) port;
+
+   if (stats != NULL)
+   memcpy(stats, &p->stats, sizeof(p->stats));
+
+   if (clear)
+   memset(&p->stats, 0, sizeof(p->stats));
+
+   return 0;
+}
+
 /*
  * Summary of port operations
  */
@@ -510,4 +545,5 @@ struct rte_port_out_ops rte_port_ethdev_writer_nodrop_ops = 
{
.f_tx = rte_port_ethdev_writer_nodrop_tx,
.f_tx_bulk = rte_port_ethdev_writer_nodrop_tx_bulk,
.f_flush = rte_port_ethdev_writer_nodrop_flush,
+   .f_stats = rte_port_ethdev_writer_nodrop_stats_read,
 };
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 03/13] port: added port_ethdev_writer stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for ethdev writer port.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_port/rte_port_ethdev.c |   37 +
 1 file changed, 37 insertions(+)

diff --git a/lib/librte_port/rte_port_ethdev.c 
b/lib/librte_port/rte_port_ethdev.c
index 3c15af6..af3e9d4 100644
--- a/lib/librte_port/rte_port_ethdev.c
+++ b/lib/librte_port/rte_port_ethdev.c
@@ -134,7 +134,23 @@ static int rte_port_ethdev_reader_stats_read(void *port,
 /*
  * Port ETHDEV Writer
  */
+#ifdef RTE_PORT_ETHDEV_WRITER_STATS_COLLECT
+
+#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(port, val) \
+   port->stats.n_pkts_in += val
+#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(port, val) \
+   port->stats.n_pkts_drop += val
+
+#else
+
+#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(port, val)
+#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(port, val)
+
+#endif
+
 struct rte_port_ethdev_writer {
+   struct rte_port_out_stats stats;
+
struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
uint32_t tx_burst_sz;
uint16_t tx_buf_count;
@@ -185,6 +201,7 @@ send_burst(struct rte_port_ethdev_writer *p)
nb_tx = rte_eth_tx_burst(p->port_id, p->queue_id,
 p->tx_buf, p->tx_buf_count);

+   RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
for ( ; nb_tx < p->tx_buf_count; nb_tx++)
rte_pktmbuf_free(p->tx_buf[nb_tx]);

@@ -198,6 +215,7 @@ rte_port_ethdev_writer_tx(void *port, struct rte_mbuf *pkt)
(struct rte_port_ethdev_writer *) port;

p->tx_buf[p->tx_buf_count++] = pkt;
+   RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
if (p->tx_buf_count >= p->tx_burst_sz)
send_burst(p);

@@ -223,9 +241,11 @@ rte_port_ethdev_writer_tx_bulk(void *port,
if (tx_buf_count)
send_burst(p);

+   RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
n_pkts_ok = rte_eth_tx_burst(p->port_id, p->queue_id, pkts,
n_pkts);

+   RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - 
n_pkts_ok);
for ( ; n_pkts_ok < n_pkts; n_pkts_ok++) {
struct rte_mbuf *pkt = pkts[n_pkts_ok];

@@ -238,6 +258,7 @@ rte_port_ethdev_writer_tx_bulk(void *port,
struct rte_mbuf *pkt = pkts[pkt_index];

p->tx_buf[tx_buf_count++] = pkt;
+   RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
pkts_mask &= ~pkt_mask;
}

@@ -275,6 +296,21 @@ rte_port_ethdev_writer_free(void *port)
return 0;
 }

+static int rte_port_ethdev_writer_stats_read(void *port,
+   struct rte_port_out_stats *stats, int clear)
+{
+   struct rte_port_ethdev_writer *p =
+   (struct rte_port_ethdev_writer *) port;
+
+   if (stats != NULL)
+   memcpy(stats, &p->stats, sizeof(p->stats));
+
+   if (clear)
+   memset(&p->stats, 0, sizeof(p->stats));
+
+   return 0;
+}
+
 /*
  * Port ETHDEV Writer Nodrop
  */
@@ -465,6 +501,7 @@ struct rte_port_out_ops rte_port_ethdev_writer_ops = {
.f_tx = rte_port_ethdev_writer_tx,
.f_tx_bulk = rte_port_ethdev_writer_tx_bulk,
.f_flush = rte_port_ethdev_writer_flush,
+   .f_stats = rte_port_ethdev_writer_stats_read,
 };

 struct rte_port_out_ops rte_port_ethdev_writer_nodrop_ops = {
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 02/13] port: added port_ethdev_reader stats

2015-05-26 Thread Maciej Gajdzica
Added statistics for ethdev reader port.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_port/rte_port_ethdev.c |   37 -
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/lib/librte_port/rte_port_ethdev.c 
b/lib/librte_port/rte_port_ethdev.c
index 39ed72d..3c15af6 100644
--- a/lib/librte_port/rte_port_ethdev.c
+++ b/lib/librte_port/rte_port_ethdev.c
@@ -42,7 +42,23 @@
 /*
  * Port ETHDEV Reader
  */
+#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
+
+#define RTE_PORT_ETHDEV_READER_STATS_PKTS_IN_ADD(port, val) \
+   port->stats.n_pkts_in += val
+#define RTE_PORT_ETHDEV_READER_STATS_PKTS_DROP_ADD(port, val) \
+   port->stats.n_pkts_drop += val
+
+#else
+
+#define RTE_PORT_ETHDEV_READER_STATS_PKTS_IN_ADD(port, val)
+#define RTE_PORT_ETHDEV_READER_STATS_PKTS_DROP_ADD(port, val)
+
+#endif
+
 struct rte_port_ethdev_reader {
+   struct rte_port_in_stats stats;
+
uint16_t queue_id;
uint8_t port_id;
 };
@@ -80,8 +96,11 @@ rte_port_ethdev_reader_rx(void *port, struct rte_mbuf 
**pkts, uint32_t n_pkts)
 {
struct rte_port_ethdev_reader *p =
(struct rte_port_ethdev_reader *) port;
+   uint16_t rx_pkt_cnt;

-   return rte_eth_rx_burst(p->port_id, p->queue_id, pkts, n_pkts);
+   rx_pkt_cnt = rte_eth_rx_burst(p->port_id, p->queue_id, pkts, n_pkts);
+   RTE_PORT_ETHDEV_READER_STATS_PKTS_IN_ADD(p, rx_pkt_cnt);
+   return rx_pkt_cnt;
 }

 static int
@@ -97,6 +116,21 @@ rte_port_ethdev_reader_free(void *port)
return 0;
 }

+static int rte_port_ethdev_reader_stats_read(void *port,
+   struct rte_port_in_stats * stats, int clear)
+{
+   struct rte_port_ethdev_reader *p =
+   (struct rte_port_ethdev_reader *) port;
+
+   if (stats != NULL)
+   memcpy(stats, &p->stats, sizeof(p->stats));
+
+   if (clear)
+   memset(&p->stats, 0, sizeof(p->stats));
+
+   return 0;
+}
+
 /*
  * Port ETHDEV Writer
  */
@@ -422,6 +456,7 @@ struct rte_port_in_ops rte_port_ethdev_reader_ops = {
.f_create = rte_port_ethdev_reader_create,
.f_free = rte_port_ethdev_reader_free,
.f_rx = rte_port_ethdev_reader_rx,
+   .f_stats = rte_port_ethdev_reader_stats_read,
 };

 struct rte_port_out_ops rte_port_ethdev_writer_ops = {
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 01/13] port: added structures for port stats

2015-05-26 Thread Maciej Gajdzica
Added common data structures for port statistics.

Signed-off-by: Maciej Gajdzica 
---
 lib/librte_port/rte_port.h |   60 
 1 file changed, 55 insertions(+), 5 deletions(-)

diff --git a/lib/librte_port/rte_port.h b/lib/librte_port/rte_port.h
index d84e5a1..ab433e5 100644
--- a/lib/librte_port/rte_port.h
+++ b/lib/librte_port/rte_port.h
@@ -81,6 +81,12 @@ extern "C" {
 Cannot be changed. */
 #define RTE_PORT_IN_BURST_SIZE_MAX 64

+/** Input port statistics */
+struct rte_port_in_stats {
+   uint64_t n_pkts_in;
+   uint64_t n_pkts_drop;
+};
+
 /**
  * Input port create
  *
@@ -120,17 +126,42 @@ typedef int (*rte_port_in_op_rx)(
struct rte_mbuf **pkts,
uint32_t n_pkts);

+/**
+ * Input port stats get
+ *
+ * @param port
+ *   Handle to output port instance
+ * @param stats
+ *   Handle to port_in stats struct to copy data
+ * @param clear
+ *   Flag indicating that stats should be cleared after read
+ *
+ * @return
+ *   Error code or 0 on success.
+ */
+typedef int (*rte_port_in_op_stats_read)(
+   void *port,
+   struct rte_port_in_stats *stats,
+   int clear);
+
 /** Input port interface defining the input port operation */
 struct rte_port_in_ops {
rte_port_in_op_create f_create; /**< Create */
rte_port_in_op_free f_free; /**< Free */
rte_port_in_op_rx f_rx; /**< Packet RX (packet burst) */
+   rte_port_in_op_stats_read f_stats;  /**< Stats */
 };

 /*
  * Port OUT
  *
  */
+/** Output port statistics */
+struct rte_port_out_stats {
+   uint64_t n_pkts_in;
+   uint64_t n_pkts_drop;
+};
+
 /**
  * Output port create
  *
@@ -197,13 +228,32 @@ typedef int (*rte_port_out_op_tx_bulk)(
  */
 typedef int (*rte_port_out_op_flush)(void *port);

+/**
+ * Output port stats read
+ *
+ * @param port
+ *   Handle to output port instance
+ * @param stats
+ *   Handle to port_out stats struct to copy data
+ * @param clear
+ *   Flag indicating that stats should be cleared after read
+ *
+ * @return
+ *   Error code or 0 on success.
+ */
+typedef int (*rte_port_out_op_stats_read)(
+   void *port,
+   struct rte_port_out_stats *stats,
+   int clear);
+
 /** Output port interface defining the output port operation */
 struct rte_port_out_ops {
-   rte_port_out_op_create f_create;   /**< Create */
-   rte_port_out_op_free f_free;   /**< Free */
-   rte_port_out_op_tx f_tx;   /**< Packet TX (single packet) */
-   rte_port_out_op_tx_bulk f_tx_bulk; /**< Packet TX (packet burst) */
-   rte_port_out_op_flush f_flush; /**< Flush */
+   rte_port_out_op_create f_create;/**< Create */
+   rte_port_out_op_free f_free;/**< Free */
+   rte_port_out_op_tx f_tx;/**< Packet TX 
(single packet) */
+   rte_port_out_op_tx_bulk f_tx_bulk;  /**< Packet TX (packet 
burst) */
+   rte_port_out_op_flush f_flush;  /**< Flush */
+   rte_port_out_op_stats_read f_stats; /**< Stats */
 };

 #ifdef __cplusplus
-- 
1.7.9.5



[dpdk-dev] [PATCH v3 00/13] port: added port statistics

2015-05-26 Thread Maciej Gajdzica
Added statistics for every type of port. By default all port statistics
are disabled, user must activate them in config file.

Changes in v2:
- added missing signoffs

Changes in v3:
- removed new config options to enable/disable stats
- using RTE_LOG_LEVEL instead

Maciej Gajdzica (13):
  port: added structures for port stats
  port: added port_ethdev_reader stats
  port: added port_ethdev_writer stats
  port: added port_ethdev_writer_nodrop stats
  port: added port_frag stats
  port: added port_ras stats
  port: added port_ring_reader stats
  port: added port_ring_writer stats
  port: added port_ring_writer_nodrop stats
  port: added port_sched_reader stats
  port: added port_sched_writer stats
  port: added port_source stats
  port: added port_sink stats

 lib/librte_port/rte_port.h |   60 +++--
 lib/librte_port/rte_port_ethdev.c  |  110 +-
 lib/librte_port/rte_port_frag.c|   36 ++
 lib/librte_port/rte_port_ras.c |   38 +++
 lib/librte_port/rte_port_ring.c|  114 +++-
 lib/librte_port/rte_port_sched.c   |   96 +--
 lib/librte_port/rte_port_source_sink.c |   98 +--
 7 files changed, 535 insertions(+), 17 deletions(-)

-- 
1.7.9.5



[dpdk-dev] FIB aware L3 forwarding

2015-05-26 Thread Stephen Hemminger
On Tue, 26 May 2015 10:51:01 -0700
Srikanth Akula  wrote:

> Hi Dev team ,
> 
> I am interested to know if DPDK supports multiple FIBs , and forwards L3
> packets based on the FIB ID we are interested in ?
> 
> -Srikanth

DPDK is not a router, it provides tools to build a router.
It is up to your software to manage things like  FIB's itself.


[dpdk-dev] [PATCH RFC] Memcpy optimization

2015-05-26 Thread Linhaifeng


On 2014/11/14 17:08, Wang, Zhihong wrote:
> Hi all,
> 
> I'd like to propose an update on DPDK memcpy optimization.
> Please see RFC below for details.
> 
> 
> Thanks
> John
> 
> ---
> 
> DPDK Memcpy Optimization
> 
> 1. Introduction
> 2. Terminology
> 3. Mechanism
> 3.1 Architectural Insights
> 3.2 DPDK memcpy optimization
> 3.3 Code change
> 4. Glibc memcpy analysis
> Acknowledgements
> Author's Address
> 
> 
> 1. Introduction
> 
> This document describes DPDK memcpy optimization, for both SSE and AVX 
> platforms.
> 
> Glibc memcpy is for general uses, it's not so efficient for DPDK where copies 
> are small and from cache to cache mainly.
> Also, glibc is changing over versions, some tradeoffs it made have negative 
> impact on DPDK performance. This in the meantime makes DPDK memcpy 
> performance glibc version dependent.
> For this cause, it's necessary to maintain a standalone memcpy implementation 
> to take full advantage of hardware features, and make special optimization 
> aiming at DPDK scenarios.
> 
> Current DPDK memcpy has the following improvement areas:
> * No support for 256-bit load/store
> * Poor performance for unaligned cases
> * Performance drops at certain odd copy sizes
> * Make slow glibc call for constant copies
> 
> It can be improved significantly by utilizing 256-bit AVX instructions and 
> applying more optimization techniques.
> 
> 2. Terminology
> 
> Aligned copy: Same offset for source & destination starting addresses
> Unaligned copy: Different offsets for source & destination starting addresses
> Constant payload size: Copy length can be decided at compile time
> Variable payload size: Copy length can't be decided at compile time
> 
> 3. Mechanism
> 
> 3.1 Architectural Insights
> 
> New architectures are likely to have better cache performance and stronger 
> ISA implementation.
> Memcpy needs to make full utilization of cache bandwidth, and implement 
> different mechanisms according to hardware features.
> Below is the architecture analysis for memory performance in Haswell and 
> Sandy Bridge.
> 
> Haswell has significant improvements in memory hierarchy over Sandy Bridge:
> * 2x cache bandwidth: From 48 B/cycle to 96 B/cycle
> * Sandy Bridge suffers from L1D bank conflicts, Haswell doesn't
> * Sandy Bridge has 2 split line buffers, Haswell has 4
> * Forwarding latency is 2 cycles for 256-bit AVX loads in Sandy Bridge, 1 in 
> Haswell
> 
> 3.2 DPDK memcpy optimization
> 
> DPDK memcpy calls are mainly cache to cache cases with payload no larger than 
> 8KB, they can be categorized into 4 scenarios:
> * Aligned copy, with constant payload size
> * Aligned copy, with variable payload size
> * Unaligned copy, with constant payload size
> * Unaligned copy, with variable payload size
> 
> Each scenario should be optimized according to its characteristics:
> * For aligned cases, no special optimization techniques are required
> * For unaligned cases:
> * Make store address aligned is a basic technique to improve performance
> * Load address alignment is a tradeoff between bit shifting overhead and 
> unaligned memory access penalty, which should be assessed by test
> * Load/store address should be made available as early as possible to 
> fully utilize the pipeline
> * For constant cases, inlining can bring significant benefits by means of gcc 
> optimization at compile time
> * For variable cases, it's important to reduce branches and make good use of 
> hardware prefetch
> 
> Memcpy optimization is summarized below:
> * Utilize full cache bandwidth
> * SSE: 128 bit
> * AVX/AVX2: 128/256 bit, depends on hardware implementation
> * Enforce aligned stores
> * Apply load address alignment based on architecture features
> * Enforce aligned loads for Sandy Bridge like architectures
> * No need to enforce aligned loads for Haswell because unaligned loads is 
> improved, also the AVX2 VPALIGNR is not efficient for 256-bit shifting and 
> leads to extra overhead
> * Make load/store address available as early as possible
> 
> Finally, general optimization techniques should be applied, like inlining, 
> branch reducing, prefetch pattern access, etc.
> 

Is this optimization in compile time or run time?

> 3.3 Code change
> 
> DPDK memcpy is implemented in a standalone file "rte_memcpy.h".
> The memcpy function is "rte_memcpy_func", which contains the copy flow, and 
> calls the inline move functions for actual data copy.
> 
> There will be major code change described as follows:
> * Differentiate architectural features based on CPU flags
> * Implement separated copy flow specifically optimized for target 
> architecture
> * Implement separated move functions for SSE/AVX/AVX2 to make full 
> utilization of cache bandwidth
> * Rewrite the memcpy function "rte_memcpy_func"
> * Add store aligning
> * Add load aligning for Sandy Bridge and older architectures
> * Put block copy loop into inline move functions for better cont

[dpdk-dev] [PATCH 2/2] mempool: fix pages computation to determine number of objects

2015-05-26 Thread Adrien Mazarguil
On Mon, May 25, 2015 at 06:20:03PM +, Ananyev, Konstantin wrote:
> Hi Adrien,

Hi Konstantin,

> > -Original Message-
> > From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Adrien Mazarguil
> > Sent: Monday, May 25, 2015 5:28 PM
> > To: dev at dpdk.org
> > Subject: [dpdk-dev] [PATCH 2/2] mempool: fix pages computation to determine 
> > number of objects
> > 
> > In rte_mempool_obj_iter(), even when a single page is required per object,
> > a loop checks that the the next page is contiguous and drops the first one
> > otherwise. This commit checks subsequent pages only when several are
> > required per object.
> > 
> > Also a minor fix for the amount of remaining space that prevents using the
> > entire region.
> > 
> > Fixes: 148f963fb532 ("xen: core library changes")
> > 
> > Signed-off-by: Adrien Mazarguil 
> > ---
> >  lib/librte_mempool/rte_mempool.c | 11 ---
> >  1 file changed, 8 insertions(+), 3 deletions(-)
> > 
> > diff --git a/lib/librte_mempool/rte_mempool.c 
> > b/lib/librte_mempool/rte_mempool.c
> > index d1a02a2..3c1efec 100644
> > --- a/lib/librte_mempool/rte_mempool.c
> > +++ b/lib/librte_mempool/rte_mempool.c
> > @@ -175,12 +175,17 @@ rte_mempool_obj_iter(void *vaddr, uint32_t elt_num, 
> > size_t elt_sz, size_t align,
> > pgn += j;
> > 
> > /* do we have enough space left for the next element. */
> > -   if (pgn >= pg_num)
> > +   if (pgn > pg_num)
> > break;
> 
> Hmm, that doesn't look right.
> Suppose:
> start==0; end==5120; pg_shift==12; pg_num == 1;
> So:
> pgn = 1; // (5120>>12)-(0>>12)
> 
> And we end-up accessing element that is beyond  allocated memory.
> 
> > 
> > -   for (k = j;
> > +   /*
> > +* Compute k so that (k - j) is the number of contiguous
> > +* pages starting from index j. Note that there is at least
> > +* one page.
> > +*/
> > +   for (k = j + 1;
> > k != pgn &&
> > -   paddr[k] + pg_sz == paddr[k + 1];
> > +   paddr[k - 1] + pg_sz == paddr[k];
> > k++)
> > ;
> 
> 
> Again, suppose:
> j==0; start==0; end==2048; pg_shift==12; pg_num == 2;
> So:
> pgn = 0;
> k = 1;
> and the loop goes beyond paddr[] boundaries.
> 
> The problem here, I think that you treat pgn as number of pages, while it is 
> index of last page to be used.

Well, I misunderstood the logic here, to me pgn was the number of pages
necessary for the current object on top of the number of pages used so
far. Assuming a single object uses at least one page (assuming 4K pages),
pgn wasn't supposed to be zero.

> As I understand, what you are trying to fix here, is a situation when end is 
> a multiply of page size (end == N * pg_sz),  right?

This and also when (end - start) < page size.

> Then, probably something simple like that would do:
> 
> - pgn = (end >> pg_shift) - (start >> pg_shift);
> + pgn = (end - 1 >> pg_shift) - (start >> pg_shift);
> + pg_next = (end >> pg_shift) - (start >> pg_shift);
> ...
>   if (k == pgn) {
> if (obj_iter != NULL)
> obj_iter(obj_iter_arg, (void *)start,
> (void *)end, i);
> va = end;
>  -  j = pgn;
> +  j = pg_next;
> i++;
> } else {
> ...

That does not seem to be enough to solve the issue in my scenario, I get
weird results (j never reaches pg_num).

I'll come up with a new patch that takes your comment into account,
hopefully covering all cases.

Thanks,

-- 
Adrien Mazarguil
6WIND


[dpdk-dev] [PATCH v3 00/13] port: added port statistics

2015-05-26 Thread Dumitrescu, Cristian


> -Original Message-
> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Maciej Gajdzica
> Sent: Tuesday, May 26, 2015 10:23 AM
> To: dev at dpdk.org
> Subject: [dpdk-dev] [PATCH v3 00/13] port: added port statistics
> 
> Added statistics for every type of port. By default all port statistics
> are disabled, user must activate them in config file.
> 
> Changes in v2:
>   - added missing signoffs
> 
> Changes in v3:
>   - removed new config options to enable/disable stats
>   - using RTE_LOG_LEVEL instead
> 
> Maciej Gajdzica (13):
>   port: added structures for port stats
>   port: added port_ethdev_reader stats
>   port: added port_ethdev_writer stats
>   port: added port_ethdev_writer_nodrop stats
>   port: added port_frag stats
>   port: added port_ras stats
>   port: added port_ring_reader stats
>   port: added port_ring_writer stats
>   port: added port_ring_writer_nodrop stats
>   port: added port_sched_reader stats
>   port: added port_sched_writer stats
>   port: added port_source stats
>   port: added port_sink stats
> 
>  lib/librte_port/rte_port.h |   60 +++--
>  lib/librte_port/rte_port_ethdev.c  |  110
> +-
>  lib/librte_port/rte_port_frag.c|   36 ++
>  lib/librte_port/rte_port_ras.c |   38 +++
>  lib/librte_port/rte_port_ring.c|  114
> +++-
>  lib/librte_port/rte_port_sched.c   |   96 +--
>  lib/librte_port/rte_port_source_sink.c |   98
> +--
>  7 files changed, 535 insertions(+), 17 deletions(-)
> 
> --
> 1.7.9.5

Acked-by: Cristian Dumitrescu 



[dpdk-dev] FIB aware L3 forwarding

2015-05-26 Thread Srikanth Akula
Hi Dev team ,

I am interested to know if DPDK supports multiple FIBs , and forwards L3
packets based on the FIB ID we are interested in ?

-Srikanth


[dpdk-dev] [RFC PATCH 1/2] Added ETH_SPEED_CAP bitmap in rte_eth_dev_info

2015-05-26 Thread Marc Sune


On 25/05/15 19:46, Stephen Hemminger wrote:
> On Tue, 12 May 2015 01:45:45 +0200
> Marc Sune  wrote:
>
>> +/**
>> + * Ethernet device information
>> + */
>>   struct rte_eth_dev_info {
>>  struct rte_pci_device *pci_dev; /**< Device PCI information. */
>>  const char *driver_name; /**< Device Driver name. */
>> @@ -924,6 +947,7 @@ struct rte_eth_dev_info {
>>  uint16_t vmdq_queue_base; /**< First queue ID for VMDQ pools. */
>>  uint16_t vmdq_queue_num;  /**< Queue number for VMDQ pools. */
>>  uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
>> +uint16_t speed_capa;  /**< Supported speeds bitmap. */
> Since you are likely to run out of 16 bits in future, why not 32 bits now?

Indeed, why not. I will convert it to uint32_t when I send the new version.

Thanks
marc



[dpdk-dev] [PATCH 2/5] cxgbe: add cxgbe poll mode driver.

2015-05-26 Thread Stephen Hemminger
On Tue, 26 May 2015 22:32:07 +0530
Rahul Lakkireddy  wrote:

> On Sat, May 23, 2015 at 11:27:56 +0530, Rahul Lakkireddy wrote:
> > On Fri, May 22, 2015 at 09:42:50 -0700, Stephen Hemminger wrote:
> > > On Fri, 22 May 2015 18:54:20 +0530
> > > Rahul Lakkireddy  wrote:
> > > 
> > > > +#define pr_err(y, args...) dev_err(0, y, ##args)
> > > > +#define pr_warn(y, args...) dev_warn(0, y, ##args)
> > > > +#define pr_info(y, args...) dev_info(0, y, ##args)
> > > > +#define BUG() pr_err("BUG at %s:%d", __func__, __LINE__)
> > > > +
> > > > +#define ASSERT(x) do {\
> > > > +   if (!(x)) \
> > > > +   rte_panic("CXGBE: x"); \
> > > > +} while (0)
> > > > +#define BUG_ON(x) ASSERT(!(x))
> > > > +
> > > > +#ifndef WARN_ON
> > > > +#define WARN_ON(x) do { \
> > > > +   int ret = !!(x); \
> > > > +   if (unlikely(ret)) \
> > > > +   pr_warn("WARN_ON: \"" #x "\" at %s:%d\n", __func__, 
> > > > __LINE__); \
> > > > +} while (0)
> > > > +#endif
> > > > +
> > > > +#define __iomem
> > > > +
> > > > +#ifndef BIT
> > > > +#define BIT(n) (1 << (n))
> > > > +#endif
> > > > +
> > > > +#define L1_CACHE_SHIFT  6
> > > > +#define L1_CACHE_BYTES  BIT(L1_CACHE_SHIFT)
> > > > +
> > > > +#define PAGE_SHIFT  12
> > > > +#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
> > > > +#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
> > > > +
> > > > +#define VLAN_HLEN 4
> > > > +
> > > > +#define rmb() rte_rmb() /* dpdk rte provided rmb */
> > > > +#define wmb() rte_wmb() /* dpdk rte provided wmb */
> > > > +
> > > > +typedef uint8_t   u8;
> > > > +typedef int8_ts8;
> > > > +typedef uint16_t  u16;
> > > > +typedef uint32_t  u32;
> > > > +typedef int32_t   s32;
> > > > +typedef uint64_t  u64;
> > > > +typedef int   bool;
> > > > +typedef uint64_t  dma_addr_t;
> > > > +
> > > > +#ifndef __le16
> > > > +#define __le16 uint16_t
> > > > +#endif
> > > > +#ifndef __le32
> > > > +#define __le32 uint32_t
> > > > +#endif
> > > > +#ifndef __le64
> > > > +#define __le64 uint64_t
> > > > +#endif
> > > > +#ifndef __be16
> > > > +#define __be16 uint16_t
> > > > +#endif
> > > > +#ifndef __be32
> > > > +#define __be32 uint32_t
> > > > +#endif
> > > > +#ifndef __be64
> > > > +#define __be64 uint64_t
> > > > +#endif
> > > > +#ifndef __u8
> > > > +#define __u8   uint8_t
> > > > +#endif
> > > > +#ifndef __u16
> > > > +#define __u16  uint16_t
> > > > +#endif
> > > > +#ifndef __u32
> > > > +#define __u32  uint32_t
> > > > +#endif
> > > > +#ifndef __u64
> > > > +#define __u64  uint64_t
> > > > +#endif
> > > > +
> > > > +#define FALSE  0
> > > > +#define TRUE   1
> > > > +#define false  0
> > > > +#define true   1
> > > > +
> > > > +#define min(a, b) RTE_MIN(a, b)
> > > > +#define max(a, b) RTE_MAX(a, b)
> > > 
> > > This is not Linux kernel.
> > > Please don't create wrappers for all the stuff in Linux to port your 
> > > driver.
> > 
> > We actually referred several PMD's compat file including - enic_compat.h,
> > i40e_osdep.h, ixgbe_osdep.h, fm10k_osdep.h, etc.
> > 
> > Most of the types above are already defined by many of existing PMD's compat
> > file.  Can we at-least keep those which are already defined by several PMD's
> > compat file?
> 
> Just to give a background - since we are new to dpdk community, we studied the
> already merged PMD's compat files as reference to understand how things are
> done for driver submission. And so, we wrote cxgbe compat file along similar
> lines. However, if above wrappers are not acceptable then, we will definitely
> remove them in V2.
> 
> Just trying to get a clarification so that we don't repeat the same mistake in
> V2 submission. Reviews from you and dpdk community are more than welcome and
> appreciated.

Does this driver share source code with other platforms? If it does then the
compatibility wrappers make sense and reduce the maintenance effort.
If the driver is a standalone port to DPDK, then it makes sense to complete
the effort and use standard DPDK coding practices (stdint, stdbool, etc).

The other drivers in DPDK do things based on that. Many of the hardware
drivers share code with BSD. Others like the virtual drivers were written
or ported completely from scratch.



[dpdk-dev] [PATCH] ixgbe: fall back to non-vector rx

2015-05-26 Thread Eric Kinzie
The ixgbe driver refuses to receive any packets when vector receive
is enabled and fewer than the minimum number of required mbufs (32)
are supplied.  This makes it incompatible with the bonding driver
which, during receive, may start out with enough buffers but as it
collects packets from each of the enslaved interfaces can drop below
that threshold.  Instead of just giving up when insufficient buffers are
supplied fall back to the original, non-vector, ixgbe receive function.

Signed-off-by: Eric Kinzie 
---
 drivers/net/ixgbe/ixgbe_rxtx.c |   10 +-
 drivers/net/ixgbe/ixgbe_rxtx.h |4 
 drivers/net/ixgbe/ixgbe_rxtx_vec.c |4 ++--
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 4f9ab22..fbba0ab 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -1088,9 +1088,9 @@ ixgbe_rx_fill_from_stage(struct ixgbe_rx_queue *rxq, 
struct rte_mbuf **rx_pkts,
return nb_pkts;
 }

-static inline uint16_t
-rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
-uint16_t nb_pkts)
+uint16_t
+ixgbe_rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+  uint16_t nb_pkts)
 {
struct ixgbe_rx_queue *rxq = (struct ixgbe_rx_queue *)rx_queue;
uint16_t nb_rx = 0;
@@ -1158,14 +1158,14 @@ ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct 
rte_mbuf **rx_pkts,
return 0;

if (likely(nb_pkts <= RTE_PMD_IXGBE_RX_MAX_BURST))
-   return rx_recv_pkts(rx_queue, rx_pkts, nb_pkts);
+   return ixgbe_rx_recv_pkts(rx_queue, rx_pkts, nb_pkts);

/* request is relatively large, chunk it up */
nb_rx = 0;
while (nb_pkts) {
uint16_t ret, n;
n = (uint16_t)RTE_MIN(nb_pkts, RTE_PMD_IXGBE_RX_MAX_BURST);
-   ret = rx_recv_pkts(rx_queue, &rx_pkts[nb_rx], n);
+   ret = ixgbe_rx_recv_pkts(rx_queue, &rx_pkts[nb_rx], n);
nb_rx = (uint16_t)(nb_rx + ret);
nb_pkts = (uint16_t)(nb_pkts - ret);
if (ret < n)
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.h b/drivers/net/ixgbe/ixgbe_rxtx.h
index af36438..811e514 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.h
+++ b/drivers/net/ixgbe/ixgbe_rxtx.h
@@ -283,6 +283,10 @@ uint16_t ixgbe_recv_scattered_pkts_vec(void *rx_queue,
 int ixgbe_rx_vec_dev_conf_condition_check(struct rte_eth_dev *dev);
 int ixgbe_rxq_vec_setup(struct ixgbe_rx_queue *rxq);

+uint16_t ixgbe_rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+   uint16_t nb_pkts);
+
+
 #ifdef RTE_IXGBE_INC_VECTOR

 uint16_t ixgbe_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx_vec.c 
b/drivers/net/ixgbe/ixgbe_rxtx_vec.c
index abd10f6..d27424c 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx_vec.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx_vec.c
@@ -181,7 +181,7 @@ desc_to_olflags_v(__m128i descs[4], struct rte_mbuf 
**rx_pkts)
  * in one loop
  *
  * Notice:
- * - nb_pkts < RTE_IXGBE_VPMD_RX_BURST, just return no packet
+ * - nb_pkts < RTE_IXGBE_VPMD_RX_BURST, fall back to non-vector receive
  * - nb_pkts > RTE_IXGBE_VPMD_RX_BURST, only scan RTE_IXGBE_VPMD_RX_BURST
  *   numbers of DD bit
  * - don't support ol_flags for rss and csum err
@@ -206,7 +206,7 @@ _recv_raw_pkts_vec(struct ixgbe_rx_queue *rxq, struct 
rte_mbuf **rx_pkts,
__m128i dd_check, eop_check;

if (unlikely(nb_pkts < RTE_IXGBE_VPMD_RX_BURST))
-   return 0;
+   return ixgbe_rx_recv_pkts(rxq, rx_pkts, nb_pkts);

/* Just the act of getting into the function from the application is
 * going to cost about 7 cycles */
-- 
1.7.10.4



[dpdk-dev] [PATCH] ixgbe fall back to non-vector rx

2015-05-26 Thread Eric Kinzie
This change addresses an issue found using the bonding driver
with ixgbe interfaces that have vector operations enabled
(CONFIG_RTE_IXGBE_INC_VECTOR=y).

Eric Kinzie (1):
  ixgbe: fall back to non-vector rx

 drivers/net/ixgbe/ixgbe_rxtx.c |   10 +-
 drivers/net/ixgbe/ixgbe_rxtx.h |4 
 drivers/net/ixgbe/ixgbe_rxtx_vec.c |4 ++--
 3 files changed, 11 insertions(+), 7 deletions(-)

-- 
1.7.10.4



[dpdk-dev] [PATCH v4 4/4] bond mode 4: tests for external state machine

2015-05-26 Thread Eric Kinzie
From: Eric Kinzie 

  This adds test cases for exercising the external state machine API to
  the mode 4 autotest.

Signed-off-by: Eric Kinzie 
---
 app/test/test_link_bonding_mode4.c |  210 ++--
 1 file changed, 201 insertions(+), 9 deletions(-)

diff --git a/app/test/test_link_bonding_mode4.c 
b/app/test/test_link_bonding_mode4.c
index d785393..6a459cd 100644
--- a/app/test/test_link_bonding_mode4.c
+++ b/app/test/test_link_bonding_mode4.c
@@ -151,6 +151,8 @@ static struct rte_eth_conf default_pmd_conf = {
.lpbk_mode = 0,
 };

+static uint8_t lacpdu_rx_count[RTE_MAX_ETHPORTS] = {0, };
+
 #define FOR_EACH(_i, _item, _array, _size) \
for (_i = 0, _item = &_array[0]; _i < _size && (_item = &_array[_i]); 
_i++)

@@ -320,8 +322,26 @@ remove_slave(struct slave_conf *slave)
return 0;
 }

+static void
+lacp_recv_cb(uint8_t slave_id, struct rte_mbuf *lacp_pkt)
+{
+   struct ether_hdr *hdr;
+   struct slow_protocol_frame *slow_hdr;
+
+   RTE_VERIFY(lacp_pkt != NULL);
+
+   hdr = rte_pktmbuf_mtod(lacp_pkt, struct ether_hdr *);
+   RTE_VERIFY(hdr->ether_type == rte_cpu_to_be_16(ETHER_TYPE_SLOW));
+
+   slow_hdr = rte_pktmbuf_mtod(lacp_pkt, struct slow_protocol_frame *);
+   RTE_VERIFY(slow_hdr->slow_protocol.subtype == SLOW_SUBTYPE_LACP);
+
+   lacpdu_rx_count[slave_id]++;
+   rte_pktmbuf_free(lacp_pkt);
+}
+
 static int
-initialize_bonded_device_with_slaves(uint8_t slave_count, uint8_t start)
+initialize_bonded_device_with_slaves(uint8_t slave_count, uint8_t external_sm)
 {
uint8_t i;

@@ -337,9 +357,17 @@ initialize_bonded_device_with_slaves(uint8_t slave_count, 
uint8_t start)
rte_eth_bond_8023ad_setup(test_params.bonded_port_id, NULL);
rte_eth_promiscuous_disable(test_params.bonded_port_id);

-   if (start)
-   
TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params.bonded_port_id),
-   "Failed to start bonded device");
+   if (external_sm) {
+   struct rte_eth_bond_8023ad_conf conf;
+
+   rte_eth_bond_8023ad_conf_get(test_params.bonded_port_id, &conf);
+   conf.slowrx_cb = lacp_recv_cb;
+   rte_eth_bond_8023ad_setup(test_params.bonded_port_id, &conf);
+
+   }
+
+   TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params.bonded_port_id),
+   "Failed to start bonded device");

return TEST_SUCCESS;
 }
@@ -642,7 +670,7 @@ test_mode4_lacp(void)
 {
int retval;

-   retval = initialize_bonded_device_with_slaves(TEST_LACP_SLAVE_COUT, 1);
+   retval = initialize_bonded_device_with_slaves(TEST_LACP_SLAVE_COUT, 0);
TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device");

/* Test LACP handshake function */
@@ -740,7 +768,7 @@ test_mode4_rx(void)
struct ether_addr dst_mac;
struct ether_addr bonded_mac;

-   retval = initialize_bonded_device_with_slaves(TEST_PROMISC_SLAVE_COUNT, 
1);
+   retval = initialize_bonded_device_with_slaves(TEST_PROMISC_SLAVE_COUNT, 
0);
TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device");

retval = bond_handshake();
@@ -917,7 +945,7 @@ test_mode4_tx_burst(void)
struct ether_addr dst_mac = { { 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00 } };
struct ether_addr bonded_mac;

-   retval = initialize_bonded_device_with_slaves(TEST_TX_SLAVE_COUNT, 1);
+   retval = initialize_bonded_device_with_slaves(TEST_TX_SLAVE_COUNT, 0);
TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device");

retval = bond_handshake();
@@ -1101,7 +1129,7 @@ test_mode4_marker(void)
uint8_t i, j;
const uint16_t ethtype_slow_be = rte_be_to_cpu_16(ETHER_TYPE_SLOW);

-   retval = initialize_bonded_device_with_slaves(TEST_MARKER_SLAVE_COUT, 
1);
+   retval = initialize_bonded_device_with_slaves(TEST_MARKER_SLAVE_COUT, 
0);
TEST_ASSERT_SUCCESS(retval, "Failed to initialize bonded device");

/* Test LACP handshake function */
@@ -1186,7 +1214,7 @@ test_mode4_expired(void)

struct rte_eth_bond_8023ad_conf conf;

-   retval = initialize_bonded_device_with_slaves(TEST_EXPIRED_SLAVE_COUNT, 
1);
+   retval = initialize_bonded_device_with_slaves(TEST_EXPIRED_SLAVE_COUNT, 
0);
/* Set custom timeouts to make test last shorter. */
rte_eth_bond_8023ad_conf_get(test_params.bonded_port_id, &conf);
conf.fast_periodic_ms = 100;
@@ -1268,6 +1296,156 @@ test_mode4_expired(void)
 }

 static int
+test_mode4_ext_ctrl(void)
+{
+   /*
+* configure bonded interface without the external sm enabled
+*   . try to transmit lacpdu (should fail)
+*   . try to set collecting and distributing flags (should fail)
+* reconfigure w/external sm
+*   . transmit one lacpdu on each slave using new api
+*   . make sure each slave receives one lacpdu using the callback api
+*   . transmit 

[dpdk-dev] [PATCH v4 3/4] bond mode 4: allow external state machine

2015-05-26 Thread Eric Kinzie
From: Eric Kinzie 

  Provide functions to allow an external 802.3ad state machine to transmit
  and recieve LACPDUs and to set the collection/distribution flags on
  slave interfaces.

  Size of struct rte_eth_bond_8023ad_conf changed.  Increment LIBABIVER
  and version bond_mode_8023ad_setup and bond_mode_8023ad_conf_get
  functions.

Signed-off-by: Eric Kinzie 
---
 drivers/net/bonding/Makefile  |2 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c |  240 -
 drivers/net/bonding/rte_eth_bond_8023ad.h |   44 
 drivers/net/bonding/rte_eth_bond_8023ad_private.h |   28 +++
 drivers/net/bonding/rte_eth_bond_version.map  |7 +
 5 files changed, 316 insertions(+), 5 deletions(-)

diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 83ccce3..d7e3f10 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -41,7 +41,7 @@ CFLAGS += $(WERROR_FLAGS)

 EXPORT_MAP := rte_eth_bond_version.map

-LIBABIVER := 1
+LIBABIVER := 2

 #
 # all source are stored in SRCS-y
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c 
b/drivers/net/bonding/rte_eth_bond_8023ad.c
index 1009d5b..06534ae 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -39,9 +39,12 @@
 #include 
 #include 
 #include 
+#include 

 #include "rte_eth_bond_private.h"

+static void bond_mode_8023ad_ext_periodic_cb(void *arg);
+
 #ifdef RTE_LIBRTE_BOND_DEBUG_8023AD
 #define MODE4_DEBUG(fmt, ...) RTE_LOG(DEBUG, PMD, "%6u [Port %u: %s] " fmt, \
bond_dbg_get_time_diff_ms(), slave_id, \
@@ -998,8 +1001,8 @@ bond_mode_8023ad_mac_address_update(struct rte_eth_dev 
*bond_dev)
bond_mode_8023ad_start(bond_dev);
 }

-void
-bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
+void __vsym
+bond_mode_8023ad_conf_get_v20(struct rte_eth_dev *dev,
struct rte_eth_bond_8023ad_conf *conf)
 {
struct bond_dev_private *internals = dev->data->dev_private;
@@ -1014,10 +1017,34 @@ bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
conf->tx_period_ms = mode4->tx_period_timeout / ms_ticks;
conf->update_timeout_ms = mode4->update_timeout_us / 1000;
conf->rx_marker_period_ms = mode4->rx_marker_timeout / ms_ticks;
+   conf->slowrx_cb = mode4->slowrx_cb;
 }

-void
-bond_mode_8023ad_setup(struct rte_eth_dev *dev,
+VERSION_SYMBOL(bond_mode_8023ad_conf_get, _v20, 2.0);
+
+void __vsym
+bond_mode_8023ad_conf_get_v21(struct rte_eth_dev *dev,
+   struct rte_eth_bond_8023ad_conf *conf)
+{
+   struct bond_dev_private *internals = dev->data->dev_private;
+   struct mode8023ad_private *mode4 = &internals->mode4;
+   uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
+
+   conf->fast_periodic_ms = mode4->fast_periodic_timeout / ms_ticks;
+   conf->slow_periodic_ms = mode4->slow_periodic_timeout / ms_ticks;
+   conf->short_timeout_ms = mode4->short_timeout / ms_ticks;
+   conf->long_timeout_ms = mode4->long_timeout / ms_ticks;
+   conf->aggregate_wait_timeout_ms = mode4->aggregate_wait_timeout / 
ms_ticks;
+   conf->tx_period_ms = mode4->tx_period_timeout / ms_ticks;
+   conf->update_timeout_ms = mode4->update_timeout_us / 1000;
+   conf->rx_marker_period_ms = mode4->rx_marker_timeout / ms_ticks;
+   conf->slowrx_cb = mode4->slowrx_cb;
+}
+
+BIND_DEFAULT_SYMBOL(bond_mode_8023ad_conf_get, _v21, 2.1);
+
+void __vsym
+bond_mode_8023ad_setup_v20(struct rte_eth_dev *dev,
struct rte_eth_bond_8023ad_conf *conf)
 {
struct rte_eth_bond_8023ad_conf def_conf;
@@ -1047,6 +1074,48 @@ bond_mode_8023ad_setup(struct rte_eth_dev *dev,
mode4->update_timeout_us = conf->update_timeout_ms * 1000;
 }

+VERSION_SYMBOL(bond_mode_8023ad_setup, _v20, 2.0);
+
+void __vsym
+bond_mode_8023ad_setup_v21(struct rte_eth_dev *dev,
+   struct rte_eth_bond_8023ad_conf *conf)
+{
+   struct rte_eth_bond_8023ad_conf def_conf;
+   struct bond_dev_private *internals = dev->data->dev_private;
+   struct mode8023ad_private *mode4 = &internals->mode4;
+   uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
+
+   if (conf == NULL) {
+   conf = &def_conf;
+   conf->fast_periodic_ms = BOND_8023AD_FAST_PERIODIC_MS;
+   conf->slow_periodic_ms = BOND_8023AD_SLOW_PERIODIC_MS;
+   conf->short_timeout_ms = BOND_8023AD_SHORT_TIMEOUT_MS;
+   conf->long_timeout_ms = BOND_8023AD_LONG_TIMEOUT_MS;
+   conf->aggregate_wait_timeout_ms = 
BOND_8023AD_AGGREGATE_WAIT_TIMEOUT_MS;
+   conf->tx_period_ms = BOND_8023AD_TX_MACHINE_PERIOD_MS;
+   conf->rx_marker_period_ms = BOND_8023AD_RX_MARKER_PERIOD_MS;
+   conf->update_timeout_ms = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS;
+   conf->slowrx_cb = NULL;
+   }
+
+   bond_mode_8023ad_stop(dev);
+
+   mode4->fast_periodic_timeout = con

[dpdk-dev] [PATCH v4 2/4] bond mode 4: do not ignore multicast

2015-05-26 Thread Eric Kinzie
From: Eric Kinzie 

The bonding PMD in mode 4 puts all enslaved interfaces into promiscuous
mode in order to receive LACPDUs and must filter unwanted packets
after the traffic has been "collected".  Allow broadcast and multicast
through so that ARP and IPv6 neighbor discovery continue to work.

Fixes: 46fb43683679 ("bond: add mode 4")

Signed-off-by: Eric Kinzie 
---
 app/test/test_link_bonding_mode4.c |7 +--
 drivers/net/bonding/rte_eth_bond_pmd.c |1 +
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/app/test/test_link_bonding_mode4.c 
b/app/test/test_link_bonding_mode4.c
index 460539d..d785393 100644
--- a/app/test/test_link_bonding_mode4.c
+++ b/app/test/test_link_bonding_mode4.c
@@ -749,8 +749,11 @@ test_mode4_rx(void)
rte_eth_macaddr_get(test_params.bonded_port_id, &bonded_mac);
ether_addr_copy(&bonded_mac, &dst_mac);

-   /* Assert that dst address is not bonding address */
-   dst_mac.addr_bytes[0]++;
+   /* Assert that dst address is not bonding address.  Do not set the
+* least significant bit of the zero byte as this would create a
+* multicast address.
+*/
+   dst_mac.addr_bytes[0] += 2;

/* First try with promiscuous mode enabled.
 * Add 2 packets to each slave. First with bonding MAC address, second 
with
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c 
b/drivers/net/bonding/rte_eth_bond_pmd.c
index c937e6b..1691300 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -170,6 +170,7 @@ bond_ethdev_rx_burst_8023ad(void *queue, struct rte_mbuf 
**bufs,
 * mode and packet address does not match. */
if (unlikely(hdr->ether_type == ether_type_slow_be ||
!collecting || (!promisc &&
+   !is_multicast_ether_addr(&hdr->d_addr) 
&&
!is_same_ether_addr(&bond_mac, 
&hdr->d_addr {

if (hdr->ether_type == ether_type_slow_be) {
-- 
1.7.10.4



[dpdk-dev] [PATCH v4 1/4] bond mode 4: copy entire config structure

2015-05-26 Thread Eric Kinzie
From: Eric Kinzie 

  Copy all needed fields from the mode8023ad_private structure in
  bond_mode_8023ad_conf_get().  This help ensure that a subsequent call
  to rte_eth_bond_8023ad_setup() is not passed uninitialized data that
  would result in either incorrect behavior or a failed sanity check.

Fixes: 46fb43683679 ("bond: add mode 4")

Signed-off-by: Eric Kinzie 
---
 drivers/net/bonding/rte_eth_bond_8023ad.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c 
b/drivers/net/bonding/rte_eth_bond_8023ad.c
index 97a828e..1009d5b 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -1013,6 +1013,7 @@ bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
conf->aggregate_wait_timeout_ms = mode4->aggregate_wait_timeout / 
ms_ticks;
conf->tx_period_ms = mode4->tx_period_timeout / ms_ticks;
conf->update_timeout_ms = mode4->update_timeout_us / 1000;
+   conf->rx_marker_period_ms = mode4->rx_marker_timeout / ms_ticks;
 }

 void
-- 
1.7.10.4



[dpdk-dev] [PATCH v4 0/4] bonding corrections and additions

2015-05-26 Thread Eric Kinzie
This patchset makes a couple of small corrections to the bonding driver
and introduces the ability to use an external state machine for mode
4 operation.

Changes in v2:
  . eliminate external_sm field in 802.3ad configuration 
(rte_eth_bond_8023ad_conf).
  . stop bonding device before changing the periodic callback function.
start again if needed.
  . remove unnecessary calls to valid_bonded_port_id().
  . do not check for NULL tx_ring.
  . return error in rte_eth_bond_8023ad_ext_slowtx() if packet is not LACP.
  . remove check for external sm configuration in periodic callback
  . check for valid LACPDU in test application's rx callback
  . add "Fixes:" tags

Changes in v3:
  . update rte_eth_bond_version.map

Changes in v4:
  . version functions that modify slowrx_cb

Eric Kinzie (4):
  bond mode 4: copy entire config structure
  bond mode 4: do not ignore multicast
  bond mode 4: allow external state machine
  bond mode 4: tests for external state machine

 app/test/test_link_bonding_mode4.c|  217 ++-
 drivers/net/bonding/Makefile  |2 +-
 drivers/net/bonding/rte_eth_bond_8023ad.c |  241 -
 drivers/net/bonding/rte_eth_bond_8023ad.h |   44 
 drivers/net/bonding/rte_eth_bond_8023ad_private.h |   28 +++
 drivers/net/bonding/rte_eth_bond_pmd.c|1 +
 drivers/net/bonding/rte_eth_bond_version.map  |7 +
 7 files changed, 524 insertions(+), 16 deletions(-)

-- 
1.7.10.4



[dpdk-dev] [PATCH 2/5] mbuf: use the reserved 16 bits for double vlan

2015-05-26 Thread Stephen Hemminger
On Tue, 26 May 2015 15:02:51 +
"Ananyev, Konstantin"  wrote:

> Hi Stephen,
> 
> > -Original Message-
> > From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Stephen Hemminger
> > Sent: Tuesday, May 26, 2015 3:55 PM
> > To: Zhang, Helin
> > Cc: dev at dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH 2/5] mbuf: use the reserved 16 bits for 
> > double vlan
> > 
> > On Tue, 26 May 2015 16:36:37 +0800
> > Helin Zhang  wrote:
> > 
> > > Use the reserved 16 bits in rte_mbuf structure for the outer vlan,
> > > also add QinQ offloading flags for both RX and TX sides.
> > >
> > > Signed-off-by: Helin Zhang 
> > 
> > Yet another change that is much needed, but breaks ABI compatibility.
> 
> Why do you think it breaks ABI compatibility?
> As I can see, it uses field that was reserved.
> Konstantin

Because an application maybe assuming something or reusing the reserved fields.
Yes, it would be dumb of application to do that but from absolute ABI point
of view it is a change.


[dpdk-dev] [RFC PATCH 1/2] Added ETH_SPEED_CAP bitmap in rte_eth_dev_info

2015-05-26 Thread Stephen Hemminger
On Tue, 12 May 2015 01:45:45 +0200
Marc Sune  wrote:

> +/**
> + * Ethernet device information
> + */
>  struct rte_eth_dev_info {
>   struct rte_pci_device *pci_dev; /**< Device PCI information. */
>   const char *driver_name; /**< Device Driver name. */
> @@ -924,6 +947,7 @@ struct rte_eth_dev_info {
>   uint16_t vmdq_queue_base; /**< First queue ID for VMDQ pools. */
>   uint16_t vmdq_queue_num;  /**< Queue number for VMDQ pools. */
>   uint16_t vmdq_pool_base;  /**< First ID of VMDQ pools. */
> + uint16_t speed_capa;  /**< Supported speeds bitmap. */
>  };
>  

Since you are changing size of key structure, this is an ABI change.


[dpdk-dev] Build DPDK with Google bazel

2015-05-26 Thread Stephen Hemminger
On Sat, 23 May 2015 17:53:27 -0700
Ming Zhao  wrote:

> bazel(http://bazel.io) is the open sourced version of Google build
> tool, and it has proved itself is a nice solution for monolithic
> server side development. In our company, we use both to build our
> products and it greatly reduced the hurdle of rolling out any change
> because we put the whole DPDK source code into tree and the build
> process can easily produce final binaries at any point(i.e. we can put
> a fix to DPDK code and the build process will always produce
> up-to-date binary based on the change).
> 
> We pushed all our changes to github in "bazel"
> branch(https://github.com/mzhaom/dpdk/tree/bazel) in case any one
> wants to try it. At the moment, due to the complexity of setting up
> bazel BUILD files to handle different compilation settings, we are not
> actively pursuing to integrate these changes back to upstream. But
> I'll be happy to answer any question and provide help in case anyone
> wants to do so.
> 
> Thanks!

Thanks for doing this, but please don't try and convert us.

As an experience Unix/Linux person, new glitzy build systems are kind
of a sore point. If you can make it work for you great, but let's keep
the DPDK as simple as possible.



[dpdk-dev] [PATCH] virtio: fix crash if CQ is not negotiated

2015-05-26 Thread Stephen Hemminger
On Mon, 25 May 2015 12:20:52 +0200
Damjan Marion  wrote:

> Fix NULL dereference if virtio control queue is not negotiated.
> 
> Signed-off-by: Damjan Marion 

This is good belt and suspenders thing to have, but did you see early
patches to check the feature bits and not call this code?

Acked-by: Stephen Hemminger 


[dpdk-dev] [PATCH v3 01/10] table: added structure for storing table stats

2015-05-26 Thread Stephen Hemminger
On Tue, 26 May 2015 14:39:38 +0200
Maciej Gajdzica  wrote:

> +
>  /** Lookup table interface defining the lookup table operation */
>  struct rte_table_ops {
>   rte_table_op_create f_create;   /**< Create */
> @@ -194,6 +218,7 @@ struct rte_table_ops {
>   rte_table_op_entry_add f_add;   /**< Entry add */
>   rte_table_op_entry_delete f_delete; /**< Entry delete */
>   rte_table_op_lookup f_lookup;   /**< Lookup */
> + rte_table_op_stats_read f_stats;/**< Stats */
>  };

Another good idea, which is an ABI change.


[dpdk-dev] [PATCH v3] pipeline: add statistics for librte_pipeline ports and tables

2015-05-26 Thread Stephen Hemminger
On Tue, 26 May 2015 15:39:18 +0200
Maciej Gajdzica  wrote:

> +#if RTE_LOG_LEVEL == RTE_LOG_DEBUG
> +#define RTE_PIPELINE_STATS_ADD(counter, val) \
> + ({ (counter) += (val); })
> +
> +#define RTE_PIPELINE_STATS_ADD_M(counter, mask) \
> + ({ (counter) += __builtin_popcountll(mask); })
> +#else
> +#define RTE_PIPELINE_STATS_ADD(counter, val)
> +#define RTE_PIPELINE_STATS_ADD_M(counter, mask)
> +#endif

This is worse idea than the previous one.
I want statistics done on a per lcore basis, and always available
because real users on production system want statistics (but they
don't want log spam).



[dpdk-dev] [PATCH 2/5] mbuf: use the reserved 16 bits for double vlan

2015-05-26 Thread Stephen Hemminger
On Tue, 26 May 2015 16:36:37 +0800
Helin Zhang  wrote:

> Use the reserved 16 bits in rte_mbuf structure for the outer vlan,
> also add QinQ offloading flags for both RX and TX sides.
> 
> Signed-off-by: Helin Zhang 

Yet another change that is much needed, but breaks ABI compatibility.


[dpdk-dev] [PATCH 4/6] vhost: Add new command line option: rxq

2015-05-26 Thread Ouyang, Changchun
Hi Thomas,

> -Original Message-
> From: Ouyang, Changchun
> Sent: Saturday, May 23, 2015 9:25 AM
> To: Thomas F Herbert; dpdk >> dev at dpdk.org
> Cc: Ouyang, Changchun
> Subject: RE: [dpdk-dev] [PATCH 4/6] vhost: Add new command line option:
> rxq
> 
> Hi Thomas,
> 
> > -Original Message-
> > From: Thomas F Herbert [mailto:therbert at redhat.com]
> > Sent: Friday, May 22, 2015 8:51 PM
> > To: Ouyang, Changchun; dpdk >> dev at dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH 4/6] vhost: Add new command line option:
> > rxq
> >
> >
> >
> > On 5/22/15 2:05 AM, Ouyang, Changchun wrote:
> > > Hi Thomas,
> > >
> > >> -Original Message-
> > >> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Thomas F
> > Herbert
> > >> Sent: Friday, May 22, 2015 9:39 AM
> > >> To: dpdk >> dev at dpdk.org
> > >> Subject: Re: [dpdk-dev] [PATCH 4/6] vhost: Add new command line
> > option:
> > >> rxq
> > >>
> > >>
> > >>
> > >> On 5/21/15 3:49 AM, Ouyang Changchun wrote:
> > >>> Sample vhost need know the queue number user want to enable for
> > each
> > >>> virtio device, so add the new option '--rxq' into it.
> > >> Could you also add the new --rxq option description to
> us_vhost_usage()?
> > >
> > > Actually we have, please see below
> > True enough. However, the code calls rte_eal_init() before parsing
> > args and therefore takes rte_exit before printing usage of the non-eal
> options.

Use this command line could address your question:
vhost-switch -c 0xf -n 4 -- -help
it will go through eal  and come to helper function in vhost-switch, then you 
can see the usage info for vhost.

Thanks
Changchun