Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] net: stmicro: fix LS field mask in EEE configuration
From: Rayagond Kokatanur @ 2017-01-23  5:31 UTC (permalink / raw)
  To: Joao Pinto; +Cc: David Miller, netdev
In-Reply-To: <ed690f703a3c82193737f1a9813dff8b1ff403dd.1484927665.git.jpinto@synopsys.com>

Acked-by:Rayagond Kokatanur <rayagond@vayavyalabs.com>

On Fri, Jan 20, 2017 at 9:30 PM, Joao Pinto <Joao.Pinto@synopsys.com> wrote:
> This patch fixes the LS mask when setting EEE timer.
> LS field is 10 bits long and not 11 as currently.
>
> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
> Reported-By: Rayagond Kokatanur <rayagond@vayavyalabs.com>
> ---
>  drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> index 834f40f..202216c 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> @@ -184,7 +184,7 @@ static void dwmac4_set_eee_pls(struct mac_device_info *hw, int link)
>  static void dwmac4_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
>  {
>         void __iomem *ioaddr = hw->pcsr;
> -       int value = ((tw & 0xffff)) | ((ls & 0x7ff) << 16);
> +       int value = ((tw & 0xffff)) | ((ls & 0x3ff) << 16);
>
>         /* Program the timers in the LPI timer control register:
>          * LS: minimum time (ms) for which the link
> --
> 2.9.3
>



-- 
wwr
Rayagond

^ permalink raw reply

* [PATCH net] r8152: don't execute runtime suspend if the tx is not empty
From: Hayes Wang @ 2017-01-23  6:18 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Runtime suspend shouldn't be executed if the tx queue is not empty,
because the device is not idle.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 0e99af0..e1466b4 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -32,7 +32,7 @@
 #define NETNEXT_VERSION		"08"
 
 /* Information for net */
-#define NET_VERSION		"6"
+#define NET_VERSION		"7"
 
 #define DRIVER_VERSION		"v1." NETNEXT_VERSION "." NET_VERSION
 #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
@@ -3574,6 +3574,8 @@ static bool delay_autosuspend(struct r8152 *tp)
 	 */
 	if (!sw_linking && tp->rtl_ops.in_nway(tp))
 		return true;
+	else if (!skb_queue_empty(&tp->tx_queue))
+		return true;
 	else
 		return false;
 }
-- 
2.7.4

^ permalink raw reply related

* [PATCH v4 net-next] net: mvneta: implement .set_wol and .get_wol
From: Jisheng Zhang @ 2017-01-23  6:55 UTC (permalink / raw)
  To: thomas.petazzoni, davem; +Cc: netdev, linux-kernel, Jingju Hou, Jisheng Zhang

From: Jingju Hou <houjingj@marvell.com>

From: Jingju Hou <houjingj@marvell.com>

The mvneta itself does not support WOL, but the PHY might.
So pass the calls to the PHY

Signed-off-by: Jingju Hou <houjingj@marvell.com>
Signed-off-by: Jisheng Zhang <jszhang@marvell.com>
---
since v3:
 - really fix the build error

since v2,v1:
 - using phy_dev member in struct net_device
 - add commit msg

 drivers/net/ethernet/marvell/mvneta.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 6dcc951af0ff..02611fa1c3b8 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -3929,6 +3929,25 @@ static int mvneta_ethtool_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
 	return 0;
 }
 
+static void mvneta_ethtool_get_wol(struct net_device *dev,
+				   struct ethtool_wolinfo *wol)
+{
+	wol->supported = 0;
+	wol->wolopts = 0;
+
+	if (dev->phydev)
+		return phy_ethtool_get_wol(dev->phydev, wol);
+}
+
+static int mvneta_ethtool_set_wol(struct net_device *dev,
+				  struct ethtool_wolinfo *wol)
+{
+	if (!dev->phydev)
+		return -EOPNOTSUPP;
+
+	return phy_ethtool_set_wol(dev->phydev, wol);
+}
+
 static const struct net_device_ops mvneta_netdev_ops = {
 	.ndo_open            = mvneta_open,
 	.ndo_stop            = mvneta_stop,
@@ -3958,6 +3977,8 @@ const struct ethtool_ops mvneta_eth_tool_ops = {
 	.set_rxfh	= mvneta_ethtool_set_rxfh,
 	.get_link_ksettings = phy_ethtool_get_link_ksettings,
 	.set_link_ksettings = mvneta_ethtool_set_link_ksettings,
+	.get_wol        = mvneta_ethtool_get_wol,
+	.set_wol        = mvneta_ethtool_set_wol,
 };
 
 /* Initialize hw */
-- 
2.11.0

^ permalink raw reply related

* Re: [PATCH] net: phy: micrel: add KSZ8795 ethernet switch
From: Sean Nyekjær @ 2017-01-23  7:22 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev
In-Reply-To: <20170120141728.GA13115@lunn.ch>



On 2017-01-20 15:17, Andrew Lunn wrote:
> On Fri, Jan 20, 2017 at 01:50:49PM +0100, Sean Nyekjaer wrote:
>> This ethernet switch have unfortunately the same phy id as KSZ8051.
> Hi Sean
>
> Please could you explain some more. You are adding PHY support here,
> not switch support. So is this to enable the PHY driver for the PHYs
> embedded in the switch?
>
> 	 Andrew
Yes of couse :-)
The KSZ8051 is a 5 port managed ethernet switch with integrated PHY with 
MII/RMII interface on one port.
Through the MDIO interface is possible to control the PHY on port 1-5.

I have just seen an issue with the reported speed and duplex, so i'm 
gonna submit a new version with a better description

/Sean

^ permalink raw reply

* Re: [PATCH 1/3] sh_eth: rename EESIPR bits
From: Geert Uytterhoeven @ 2017-01-23  7:39 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: netdev@vger.kernel.org, Linux-Renesas
In-Reply-To: <6851530.HAKW22qnWH@wasted.cogentembedded.com>

Hi Sergei,

On Sun, Jan 22, 2017 at 8:18 PM, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> Since the  commit  b0ca2a21f769 ("sh_eth: Add support of SH7763 to sh_eth")
> the *enum* declaring the EESIPR bits (interrupt mask) went out of sync with
> the *enum* declaring the EESR bits (interrupt status) WRT  bit naming  and
> formatting. I'd like to restore the consistency by using EESIPR as the bit
> name prefix, renaming the *enum* to EESIPR_BIT, and (finally) renaming the
> bits according to the available  Renesas SH77{34|63} manuals...

Which versions of the SH77{34|63} manuals did you use?
Several registers are called slightly different in mine, and also in my
r8a7740 manual.

> --- net-next.orig/drivers/net/ethernet/renesas/sh_eth.h
> +++ net-next/drivers/net/ethernet/renesas/sh_eth.h
> @@ -268,19 +268,29 @@ enum EESR_BIT {
>                                  EESR_TFE | EESR_TDE)
>
>  /* EESIPR */
> -enum DMAC_IM_BIT {
> -       DMAC_M_TWB = 0x40000000, DMAC_M_TABT = 0x04000000,
> -       DMAC_M_RABT = 0x02000000,
> -       DMAC_M_RFRMER = 0x01000000, DMAC_M_ADF = 0x00800000,
> -       DMAC_M_ECI = 0x00400000, DMAC_M_FTC = 0x00200000,
> -       DMAC_M_TDE = 0x00100000, DMAC_M_TFE = 0x00080000,
> -       DMAC_M_FRC = 0x00040000, DMAC_M_RDE = 0x00020000,
> -       DMAC_M_RFE = 0x00010000, DMAC_M_TINT4 = 0x00000800,
> -       DMAC_M_TINT3 = 0x00000400, DMAC_M_TINT2 = 0x00000200,
> -       DMAC_M_TINT1 = 0x00000100, DMAC_M_RINT8 = 0x00000080,
> -       DMAC_M_RINT5 = 0x00000010, DMAC_M_RINT4 = 0x00000008,
> -       DMAC_M_RINT3 = 0x00000004, DMAC_M_RINT2 = 0x00000002,
> -       DMAC_M_RINT1 = 0x00000001,
> +enum EESIPR_BIT {
> +       EESIPR_TWBIP    = 0x40000000,

TWBIP is actually two bits in my manual: TWB1IP and TWB0IP

> +       EESIPR_ADEIP    = 0x00800000,

Nonexistent bit in my manual.

> +       EESIPR_CNDIP    = 0x00000800,

Nonexistent bit in my manual.

Gr{oetje,eeting}s,

                        Geert

^ permalink raw reply

* Re: [PATCH 2/3] sh_eth: add missing EESIPR bits
From: Geert Uytterhoeven @ 2017-01-23  7:41 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: netdev@vger.kernel.org, Linux-Renesas
In-Reply-To: <3805935.iR4tgtFiHm@wasted.cogentembedded.com>

On Sun, Jan 22, 2017 at 8:18 PM, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> Renesas SH77{34|63} manuals  describe more EESIPR bits than the current
> driver. Declare the new bits with the end goal of using the bit names
> instead of the bare numbers  for  the 'sh_eth_cpu_data::eesipr_value'
> initializers...
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

> ---
>  drivers/net/ethernet/renesas/sh_eth.h |   10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
>
> Index: net-next/drivers/net/ethernet/renesas/sh_eth.h
> ===================================================================
> --- net-next.orig/drivers/net/ethernet/renesas/sh_eth.h
> +++ net-next/drivers/net/ethernet/renesas/sh_eth.h
> @@ -269,13 +269,17 @@ enum EESR_BIT {
>
>  /* EESIPR */
>  enum EESIPR_BIT {
> -       EESIPR_TWBIP    = 0x40000000,
> +       EESIPR_TWB1IP   = 0x80000000,
> +       EESIPR_TWBIP    = 0x40000000,   /* same as TWB0IP */

Ah, your adding it here ;-)

Gr{oetje,eeting}s,

                        Geert

^ permalink raw reply

* Re: [PATCH net-next v6 1/1] net sched actions: Add support for user cookies
From: Jiri Pirko @ 2017-01-23  7:48 UTC (permalink / raw)
  To: Jamal Hadi Salim
  Cc: davem, netdev, jiri, paulb, john.fastabend, simon.horman, mrv,
	hadarh, ogerlitz, roid, xiyou.wangcong, daniel
In-Reply-To: <1485116750-31198-1-git-send-email-jhs@emojatatu.com>

Sun, Jan 22, 2017 at 09:25:50PM CET, jhs@mojatatu.com wrote:
>From: Jamal Hadi Salim <jhs@mojatatu.com>
>
>Introduce optional 128-bit action cookie.
>Like all other cookie schemes in the networking world (eg in protocols
>like http or existing kernel fib protocol field, etc) the idea is to save
>user state that when retrieved serves as a correlator. The kernel
>_should not_ intepret it.  The user can store whatever they wish in the
>128 bits.
>
>Sample exercise(showing variable length use of cookie)
>
>.. create an accept action with cookie a1b2c3d4
>sudo $TC actions add action ok index 1 cookie a1b2c3d4
>
>.. dump all gact actions..
>sudo $TC -s actions ls action gact
>
>    action order 0: gact action pass
>     random type none pass val 0
>     index 1 ref 1 bind 0 installed 5 sec used 5 sec
>    Action statistics:
>    Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>    backlog 0b 0p requeues 0
>    cookie a1b2c3d4
>
>.. bind the accept action to a filter..
>sudo $TC filter add dev lo parent ffff: protocol ip prio 1 \
>u32 match ip dst 127.0.0.1/32 flowid 1:1 action gact index 1
>
>... send some traffic..
>$ ping 127.0.0.1 -c 3
>PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
>64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.020 ms
>64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.027 ms
>64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.038 ms
>
>--- 127.0.0.1 ping statistics ---
>3 packets transmitted, 3 received, 0% packet loss, time 2109ms
>rtt min/avg/max/mdev = 0.020/0.028/0.038/0.008 ms 1
>
>... show some stats
>$ sudo $TC -s actions get action gact index 1
>
>    action order 1: gact action pass
>     random type none pass val 0
>     index 1 ref 2 bind 1 installed 204 sec used 5 sec
>    Action statistics:
>        Sent 12168 bytes 164 pkt (dropped 0, overlimits 0 requeues 0)
>    backlog 0b 0p requeues 0
>    cookie a1b2c3d4
>
>.. try longer cookie...
>$ sudo $TC actions replace action ok index 1 cookie 1234567890abcdef
>.. dump..
>$ sudo $TC -s actions ls action gact
>
>    action order 1: gact action pass
>     random type none pass val 0
>     index 1 ref 2 bind 1 installed 204 sec used 5 sec
>    Action statistics:
>        Sent 12168 bytes 164 pkt (dropped 0, overlimits 0 requeues 0)
>    backlog 0b 0p requeues 0
>    cookie 1234567890abcdef
>
>Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>

Reviewed-by: Jiri Pirko <jiri@mellanox.com>

^ permalink raw reply

* [PATCH v1] net: phy: micrel: add KSZ8795 ethernet switch
From: Sean Nyekjaer @ 2017-01-23  7:58 UTC (permalink / raw)
  To: netdev; +Cc: Sean Nyekjaer, andrew

This is add support for the PHYs in the KSZ8795 5port managed switch.

It will allow to detect the link between the switch and the soc
and uses the same read_status functions as the KSZ8873MLL switch.

This ethernet switch have unfortunately the same phy id as KSZ8051.

Signed-off-by: Sean Nyekjaer <sean.nyekjaer@prevas.dk>
---
 drivers/net/phy/micrel.c   | 14 ++++++++++++++
 include/linux/micrel_phy.h |  2 ++
 2 files changed, 16 insertions(+)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index ea92d524d5a8..fa158ae5115b 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -1014,6 +1014,20 @@ static struct phy_driver ksphy_driver[] = {
 	.get_stats	= kszphy_get_stats,
 	.suspend	= genphy_suspend,
 	.resume		= genphy_resume,
+}, {
+	.phy_id		= PHY_ID_KSZ8795,
+	.phy_id_mask	= MICREL_PHY_ID_MASK,
+	.name		= "Micrel KSZ8795 Switch",
+	.features	= (SUPPORTED_Pause | SUPPORTED_Asym_Pause),
+	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
+	.config_init	= kszphy_config_init,
+	.config_aneg	= ksz8873mll_config_aneg,
+	.read_status	= ksz8873mll_read_status,
+	.get_sset_count = kszphy_get_sset_count,
+	.get_strings	= kszphy_get_strings,
+	.get_stats	= kszphy_get_stats,
+	.suspend	= genphy_suspend,
+	.resume		= genphy_resume,
 } };
 
 module_phy_driver(ksphy_driver);
diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h
index 257173e0095e..f541da68d1e7 100644
--- a/include/linux/micrel_phy.h
+++ b/include/linux/micrel_phy.h
@@ -35,6 +35,8 @@
 #define PHY_ID_KSZ886X		0x00221430
 #define PHY_ID_KSZ8863		0x00221435
 
+#define PHY_ID_KSZ8795		0x00221550
+
 /* struct phy_device dev_flags definitions */
 #define MICREL_PHY_50MHZ_CLK	0x00000001
 #define MICREL_PHY_FXEN		0x00000002
-- 
2.11.0

^ permalink raw reply related

* Re: [PATCH 3/3] sh_eth: stop using bare numbers for EESIPR values
From: Geert Uytterhoeven @ 2017-01-23  8:00 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: netdev@vger.kernel.org, Linux-Renesas
In-Reply-To: <4605565.M0SEEbnHAH@wasted.cogentembedded.com>

Hi Sergei,

On Sun, Jan 22, 2017 at 8:19 PM, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> Now  that we  have almost all EESIPR bits declared (and those that  are
> still not are most probably reserved anyway) we can at last replace the
> bare  numbers used for 'sh_eth_cpu_data::eesipr_value' initializers with
> the bit names ORed together...
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>
> ---
>  drivers/net/ethernet/renesas/sh_eth.c |   89 +++++++++++++++++++++++++++++-----
>  1 file changed, 78 insertions(+), 11 deletions(-)
>
> Index: net-next/drivers/net/ethernet/renesas/sh_eth.c
> ===================================================================
> --- net-next.orig/drivers/net/ethernet/renesas/sh_eth.c
> +++ net-next/drivers/net/ethernet/renesas/sh_eth.c

> @@ -800,7 +843,12 @@ static struct sh_eth_cpu_data sh7734_dat
>
>         .ecsr_value     = ECSR_ICD | ECSR_MPD,
>         .ecsipr_value   = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
> -       .eesipr_value   = EESIPR_RFCOFIP | EESIPR_ECIIP | 0x003f07ff,
> +       .eesipr_value   = EESIPR_RFCOFIP | EESIPR_ECIIP |
> +                         EESIPR_FTCIP | EESIPR_TDEIP | EESIPR_TFUFIP |
> +                         EESIPR_FRIP | EESIPR_RDEIP | EESIPR_RFOFIP |

Missing:

        EESIPR_DLCIP | EESIPR_CDIP | EESIPR_TROIP |

> +                         EESIPR_RMAFIP | EESIPR_CEEFIP | EESIPR_CELFIP |
> +                         EESIPR_RRFIP | EESIPR_RTLFIP | EESIPR_RTSFIP |
> +                         EESIPR_PREIP | EESIPR_CERFIP,
>
>         .tx_check       = EESR_TC1 | EESR_FTC,
>         .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
> @@ -830,7 +878,12 @@ static struct sh_eth_cpu_data sh7763_dat
>
>         .ecsr_value     = ECSR_ICD | ECSR_MPD,
>         .ecsipr_value   = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
> -       .eesipr_value   = EESIPR_RFCOFIP | EESIPR_ECIIP | 0x003f07ff,
> +       .eesipr_value   = EESIPR_RFCOFIP | EESIPR_ECIIP |
> +                         EESIPR_FTCIP | EESIPR_TDEIP | EESIPR_TFUFIP |
> +                         EESIPR_FRIP | EESIPR_RDEIP | EESIPR_RFOFIP |

Likewise

> +                         EESIPR_RMAFIP | EESIPR_CEEFIP | EESIPR_CELFIP |
> +                         EESIPR_RRFIP | EESIPR_RTLFIP | EESIPR_RTSFIP |
> +                         EESIPR_PREIP | EESIPR_CERFIP,

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [RFC PATCH net-next 0/5] bridge: per vlan lwt and dst_metadata support
From: Jiri Pirko @ 2017-01-23  8:08 UTC (permalink / raw)
  To: Roopa Prabhu
  Cc: netdev, davem, stephen, nikolay, tgraf, hannes, jbenc, pshelar,
	dsa, hadi
In-Reply-To: <1484977616-1541-1-git-send-email-roopa@cumulusnetworks.com>

Sat, Jan 21, 2017 at 06:46:51AM CET, roopa@cumulusnetworks.com wrote:
>From: Roopa Prabhu <roopa@cumulusnetworks.com>
>
>High level summary:
>lwt and dst_metadata/collect_metadata have enabled vxlan l3 deployments
>to use a single vxlan netdev for multiple vnis eliminating the scalability
>problem with using a single vxlan netdev per vni. This series tries to
>do the same for vxlan netdevs in pure l2 bridged networks.
>Use-case/deployment and details are below.
>
>Deployment scerario details:
>As we know VXLAN is used to build layer 2 virtual networks across the
>underlay layer3 infrastructure. A VXLAN tunnel endpoint (VTEP)
>originates and terminates VXLAN tunnels. And a VTEP can be a TOR switch
>or a vswitch in the hypervisor. This patch series mainly
>focuses on the TOR switch configured as a Vtep. Vxlan segment ID (vni)
>along with vlan id is used to identify layer 2 segments in a vxlan
>overlay network. Vxlan bridging is the function provided by Vteps to terminate
>vxlan tunnels and map the vxlan vni to traditional end host vlan. This is
>covered in the "VXLAN Deployment Scenarios" in sections 6 and 6.1 in RFC 7348.
>To provide vxlan bridging function, a vtep has to map vlan to a vni. The rfc
>says that the ingress VTEP device shall remove the IEEE 802.1Q VLAN tag in
>the original Layer 2 packet if there is one before encapsulating the packet
>into the VXLAN format to transmit it through the underlay network. The remote
>VTEP devices have information about the VLAN in which the packet will be
>placed based on their own VLAN-to-VXLAN VNI mapping configurations.
>
>Existing solution:
>Without this patch series one can deploy such a vtep configuration by
>by adding the local ports and vxlan netdevs into a vlan filtering bridge.
>The local ports are configured as trunk ports carrying all vlans.
>A vxlan netdev per vni is added to the bridge. Vlan mapping to vni is
>achieved by configuring the vlan as pvid on the corresponding vxlan netdev.
>The vxlan netdev only receives traffic corresponding to the vlan it is mapped
>to. This configuration maps traffic belonging to a vlan to the corresponding
>vxlan segment.
>
>          -----------------------------------
>         |              bridge               |
>         |                                   |
>          -----------------------------------
>            |100,200       |100 (pvid)    |200 (pvid)
>            |              |              |
>           swp1          vxlan1000      vxlan2000
>                    
>This provides the required vxlan bridging function but poses a
>scalability problem with using a single vxlan netdev for each vni.
>
>Solution in this patch series:
>The Goal is to use a single vxlan device to carry all vnis similar
>to the vxlan collect metadata mode but vxlan driver still carrying all
>the forwarding information.
>- vxlan driver changes:
>    - enable collect metadata mode device to be used with learning,
>      replication, fdb
>    - A single fdb table hashed by (mac, vni)
>    - rx path already has the vni
>    - tx path expects a vni in the packet with dst_metadata and vxlan
>      driver has all the forwarding information for the vni in the
>      dst_metadata.
>
>- Bridge driver changes: per vlan LWT and dst_metadata support:
>    - Our use case is vxlan and 1-1 mapping between vlan and vni, but I have
>      kept the api generic for any tunnel info
>    - Uapi to configure/unconfigure/dump per vlan tunnel data
>    - new bridge port flag to turn this feature on/off. off by default
>    - ingress hook:
>        - if port is a lwt tunnel port, use tunnel info in
>          attached dst_metadata to map it to a local vlan
>    - egress hook:
>        - if port is a lwt tunnel port, use tunnel info attached to vlan
>          to set dst_metadata on the skb
>
>Other approaches tried and vetoed:
>- tc vlan push/pop and tunnel metadata dst:
>    - posses a tc rule scalability problem (2 rules per vni)

Why it is a problem?


>    - cannot handle the case where a packet needs to be replicated to
>      multiple vxlan remote tunnel end-points.. which the vxlan driver
>      can do today by having multiple remote destinations per fdb.

Can't you just extend the tc to support this?


To me, looks like the tc is the correct place to hangle this. Then, the
user can use it for multiple cases of forwarding, including bridge,
tc-mirred, ovs and others. Putting this in bridge somehow seems wrong in
this light. Also, the bridge code is polluted enough as it is. I this we
should be super-picky to add another code there.

Can you please elaborate more why can't have this as a re-usable TC solution?


Thanks.

^ permalink raw reply

* RE: [PATCH v2] net: broadcom: bnx2x: use new api ethtool_{get|set}_link_ksettings
From: Mintz, Yuval @ 2017-01-23  8:16 UTC (permalink / raw)
  To: Philippe Reynes, davem@davemloft.net
  Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	Elior, Ariel
In-Reply-To: <1485006196-6472-1-git-send-email-tremyfr@gmail.com>

> The ethtool api {get|set}_settings is deprecated.
> We move this driver to new api {get|set}_link_ksettings.
> 
> As I don't have the hardware, I'd be very pleased if someone may test this
> patch.
> 
> Signed-off-by: Philippe Reynes <tremyfr@gmail.com>

>From the little testing I've did, things look fine. Thanks.
Acked-by: Yuval Mintz <Yuval.Mintz@cavium.com>

^ permalink raw reply

* Re: [PATCH net] net/mlx5e: Do not recycle pages from emergency reserve
From: Jesper Dangaard Brouer @ 2017-01-23  8:39 UTC (permalink / raw)
  To: Saeed Mahameed
  Cc: brouer, Tom Herbert, Saeed Mahameed, netdev, Tariq Toukan, Davem,
	Eric Dumazet
In-Reply-To: <CALzJLG9JEorLwV48H3m0vQ1+VDnpYbKhiBoUw+WW-JFouJoj1g@mail.gmail.com>


On Sat, 21 Jan 2017 22:31:26 +0200 Saeed Mahameed <saeedm@dev.mellanox.co.il> wrote:

> > My previous measurements show approx 20℅ speedup on a UDP test with delivery
> > to remote CPU.
> >
> > Removing the cache would of cause be a good usecase for speeding up the page
> > allocator (PCP). Which Mel Gorman and me are working on. AFAIK current page
> > order0 cost 240 cycles. Mel have reduced til to 180, and without NUMA 150
> > cycles. And with bulking this can be amortized to 80 cycles.
> >  
> 
> Are you trying to say that we won't need the cache if you manage to
> deliver those optimizations ?

These page alloc optimization are good, but not fast-enough to replace
your cache.  Maybe I can improve it further, but it will be very hard
to compete with a recycle cache (it can skip many checks the page alloc
need, as it knows the page state).

Said in another way, the gap will be significantly smaller, and you
will not see a big boost from using this cache.


BUT there are other advantages of using a guaranteed recycle pool
facility (like the page_pool).  Namely, (1) DMA-overhead: keeping page
DMA mapped to counter DMA+IOMMU overhead, (2) RX-zero-copy: opens up
for a software memory model solution for pre-VMA-mapping pages to
userspace (See: [1] for argument how this avoids leaking kernel mem,
but only expose/leak packet-data mem)


> can you compare those optimizations with the page_frag_cache from
> dev_alloc_skb ?

IHMO the page_frag_cache is indirectly a bulk page allocator facility,
which is limiting the number of times the page allocator is called, and
thus amortize the cost of talking to the page allocator.  Performance
wise, it is likely comparable to your page cache, and likely faster
than the 80 cycles order0-bulking.
BUT we generally worry about using these 32K pages, as it opens a
window for attackers pinning down memory.


[1] https://prototype-kernel.readthedocs.io/en/latest/vm/page_pool/design/memory_model_nic.html
-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  LinkedIn: http://www.linkedin.com/in/brouer

^ permalink raw reply

* Re: ieee802154: atusb: fix driver to work with older firmware versions
From: Geert Uytterhoeven @ 2017-01-23  8:42 UTC (permalink / raw)
  To: Stefan Schmidt, Marcel Holtmann
  Cc: Linux Kernel Mailing List, linux-wpan, netdev@vger.kernel.org
In-Reply-To: <20170117181132.05BEF660FF6@gitolite.kernel.org>

On Tue, Jan 17, 2017 at 7:11 PM, Linux Kernel Mailing List
<linux-kernel@vger.kernel.org> wrote:
> Web:        https://git.kernel.org/torvalds/c/8e38b7d4d71479b23b77f01cf0e5071610b8f357
> Commit:     8e38b7d4d71479b23b77f01cf0e5071610b8f357
> Parent:     f301606934b240fb54d8edf3618a0483e36046fc
> Refname:    refs/heads/master
> Author:     Stefan Schmidt <stefan@osg.samsung.com>
> AuthorDate: Mon Jan 2 16:58:13 2017 +0100
> Committer:  Marcel Holtmann <marcel@holtmann.org>
> CommitDate: Thu Jan 12 22:12:43 2017 +0100
>
>     ieee802154: atusb: fix driver to work with older firmware versions
>
>     After the addition of the frame_retries callback we could run into cases where
>     a ATUSB device with an older firmware version would now longer be able to bring
>     the interface up.
>
>     We keep this functionality disabled now if the minimum firmware version for this
>     feature is not available.
>
>     Fixes: 5d82288b93db3bc ("ieee802154: atusb: implement .set_frame_retries
>     ops callback")
>     Reported-by: Alexander Aring <aar@pengutronix.de>
>     Acked-by: Alexander Aring <aar@pengutronix.de>
>     Signed-off-by: Stefan Schmidt <stefan@osg.samsung.com>
>     Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  drivers/net/ieee802154/atusb.c | 13 ++++---------
>  1 file changed, 4 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c
> index 63cb679..ef68851 100644
> --- a/drivers/net/ieee802154/atusb.c
> +++ b/drivers/net/ieee802154/atusb.c
> @@ -562,13 +562,6 @@ static int
>  atusb_set_frame_retries(struct ieee802154_hw *hw, s8 retries)
>  {
>         struct atusb *atusb = hw->priv;
> -       struct device *dev = &atusb->usb_dev->dev;
> -
> -       if (atusb->fw_ver_maj == 0 && atusb->fw_ver_min < 3) {
> -               dev_info(dev, "Automatic frame retransmission is only available from "
> -                       "firmware version 0.3. Please update if you want this feature.");
> -               return -EINVAL;
> -       }
>
>         return atusb_write_subreg(atusb, SR_MAX_FRAME_RETRIES, retries);
>  }
> @@ -802,8 +795,7 @@ static int atusb_probe(struct usb_interface *interface,
>
>         hw->parent = &usb_dev->dev;
>         hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT |
> -                   IEEE802154_HW_PROMISCUOUS | IEEE802154_HW_CSMA_PARAMS |
> -                   IEEE802154_HW_FRAME_RETRIES;
> +                   IEEE802154_HW_PROMISCUOUS | IEEE802154_HW_CSMA_PARAMS;
>
>         hw->phy->flags = WPAN_PHY_FLAG_TXPOWER | WPAN_PHY_FLAG_CCA_ED_LEVEL |
>                          WPAN_PHY_FLAG_CCA_MODE;
> @@ -832,6 +824,9 @@ static int atusb_probe(struct usb_interface *interface,
>         atusb_get_and_show_build(atusb);
>         atusb_set_extended_addr(atusb);
>
> +       if (atusb->fw_ver_maj >= 0 && atusb->fw_ver_min >= 3)

As fw_ver_maj is unsigned char, gcc 4.1.2 complains:

warning: comparison is always true due to limited range of data type

> +               hw->flags |= IEEE802154_HW_FRAME_RETRIES;
> +

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [RFC PATCH net-next 0/5] bridge: per vlan lwt and dst_metadata support
From: Jiri Benc @ 2017-01-23  8:51 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Roopa Prabhu, netdev, davem, stephen, nikolay, tgraf, hannes,
	pshelar, dsa, hadi
In-Reply-To: <20170123080805.GB1831@nanopsycho.orion>

On Mon, 23 Jan 2017 09:08:05 +0100, Jiri Pirko wrote:
> Sat, Jan 21, 2017 at 06:46:51AM CET, roopa@cumulusnetworks.com wrote:
> >Other approaches tried and vetoed:
> >- tc vlan push/pop and tunnel metadata dst:
> >    - posses a tc rule scalability problem (2 rules per vni)
> 
> Why it is a problem?

Wanted to ask exactly the same question.

> >    - cannot handle the case where a packet needs to be replicated to
> >      multiple vxlan remote tunnel end-points.. which the vxlan driver
> >      can do today by having multiple remote destinations per fdb.
> 
> Can't you just extend the tc to support this?

+1

> To me, looks like the tc is the correct place to hangle this. Then, the
> user can use it for multiple cases of forwarding, including bridge,
> tc-mirred, ovs and others. Putting this in bridge somehow seems wrong in
> this light. Also, the bridge code is polluted enough as it is. I this we
> should be super-picky to add another code there.

Completely agreed.

 Jiri

^ permalink raw reply

* [PATCH net] net/sched: matchall: Fix configuration race
From: Yotam Gigi @ 2017-01-23  8:54 UTC (permalink / raw)
  To: mlxsw, jiri, eladr, daniel, jhs, davem, netdev; +Cc: Yotam Gigi

In the current version, the matchall internal state is split into two
structs: cls_matchall_head and cls_matchall_filter. This makes little
sense, as matchall instance supports only one filter, and there is no
situation where one exists and the other does not. In addition, that led
to some races when filter was deleted while packet was processed.

Unify that two structs into one, thus simplifying the process of matchall
creation and deletion. As a result, the new, delete and get callbacks have
a dummy implementation where all the work is done in destroy and change
callbacks, as was done in cls_cgroup.

Fixes: bf3994d2ed31 ("net/sched: introduce Match-all classifier")
Signed-off-by: Yotam Gigi <yotamg@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_matchall.c | 129 +++++++++++++++++------------------------------
 1 file changed, 46 insertions(+), 83 deletions(-)

diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
index fcecf5a..f2141cb 100644
--- a/net/sched/cls_matchall.c
+++ b/net/sched/cls_matchall.c
@@ -16,16 +16,11 @@
 #include <net/sch_generic.h>
 #include <net/pkt_cls.h>
 
-struct cls_mall_filter {
+struct cls_mall_head {
 	struct tcf_exts exts;
 	struct tcf_result res;
 	u32 handle;
-	struct rcu_head	rcu;
 	u32 flags;
-};
-
-struct cls_mall_head {
-	struct cls_mall_filter *filter;
 	struct rcu_head	rcu;
 };
 
@@ -33,38 +28,29 @@ static int mall_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 			 struct tcf_result *res)
 {
 	struct cls_mall_head *head = rcu_dereference_bh(tp->root);
-	struct cls_mall_filter *f = head->filter;
 
-	if (tc_skip_sw(f->flags))
+	if (tc_skip_sw(head->flags))
 		return -1;
 
-	return tcf_exts_exec(skb, &f->exts, res);
+	return tcf_exts_exec(skb, &head->exts, res);
 }
 
 static int mall_init(struct tcf_proto *tp)
 {
-	struct cls_mall_head *head;
-
-	head = kzalloc(sizeof(*head), GFP_KERNEL);
-	if (!head)
-		return -ENOBUFS;
-
-	rcu_assign_pointer(tp->root, head);
-
 	return 0;
 }
 
-static void mall_destroy_filter(struct rcu_head *head)
+static void mall_destroy_rcu(struct rcu_head *rcu)
 {
-	struct cls_mall_filter *f = container_of(head, struct cls_mall_filter, rcu);
+	struct cls_mall_head *head = container_of(rcu, struct cls_mall_head,
+						  rcu);
 
-	tcf_exts_destroy(&f->exts);
-
-	kfree(f);
+	tcf_exts_destroy(&head->exts);
+	kfree(head);
 }
 
 static int mall_replace_hw_filter(struct tcf_proto *tp,
-				  struct cls_mall_filter *f,
+				  struct cls_mall_head *head,
 				  unsigned long cookie)
 {
 	struct net_device *dev = tp->q->dev_queue->dev;
@@ -74,7 +60,7 @@ static int mall_replace_hw_filter(struct tcf_proto *tp,
 	offload.type = TC_SETUP_MATCHALL;
 	offload.cls_mall = &mall_offload;
 	offload.cls_mall->command = TC_CLSMATCHALL_REPLACE;
-	offload.cls_mall->exts = &f->exts;
+	offload.cls_mall->exts = &head->exts;
 	offload.cls_mall->cookie = cookie;
 
 	return dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol,
@@ -82,7 +68,7 @@ static int mall_replace_hw_filter(struct tcf_proto *tp,
 }
 
 static void mall_destroy_hw_filter(struct tcf_proto *tp,
-				   struct cls_mall_filter *f,
+				   struct cls_mall_head *head,
 				   unsigned long cookie)
 {
 	struct net_device *dev = tp->q->dev_queue->dev;
@@ -103,29 +89,20 @@ static bool mall_destroy(struct tcf_proto *tp, bool force)
 {
 	struct cls_mall_head *head = rtnl_dereference(tp->root);
 	struct net_device *dev = tp->q->dev_queue->dev;
-	struct cls_mall_filter *f = head->filter;
 
-	if (!force && f)
-		return false;
+	if (!head)
+		return true;
 
-	if (f) {
-		if (tc_should_offload(dev, tp, f->flags))
-			mall_destroy_hw_filter(tp, f, (unsigned long) f);
+	if (tc_should_offload(dev, tp, head->flags))
+		mall_destroy_hw_filter(tp, head, (unsigned long) head);
 
-		call_rcu(&f->rcu, mall_destroy_filter);
-	}
-	kfree_rcu(head, rcu);
+	call_rcu(&head->rcu, mall_destroy_rcu);
 	return true;
 }
 
 static unsigned long mall_get(struct tcf_proto *tp, u32 handle)
 {
-	struct cls_mall_head *head = rtnl_dereference(tp->root);
-	struct cls_mall_filter *f = head->filter;
-
-	if (f && f->handle == handle)
-		return (unsigned long) f;
-	return 0;
+	return 0UL;
 }
 
 static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = {
@@ -134,7 +111,7 @@ static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = {
 };
 
 static int mall_set_parms(struct net *net, struct tcf_proto *tp,
-			  struct cls_mall_filter *f,
+			  struct cls_mall_head *head,
 			  unsigned long base, struct nlattr **tb,
 			  struct nlattr *est, bool ovr)
 {
@@ -149,11 +126,11 @@ static int mall_set_parms(struct net *net, struct tcf_proto *tp,
 		goto errout;
 
 	if (tb[TCA_MATCHALL_CLASSID]) {
-		f->res.classid = nla_get_u32(tb[TCA_MATCHALL_CLASSID]);
-		tcf_bind_filter(tp, &f->res, base);
+		head->res.classid = nla_get_u32(tb[TCA_MATCHALL_CLASSID]);
+		tcf_bind_filter(tp, &head->res, base);
 	}
 
-	tcf_exts_change(tp, &f->exts, &e);
+	tcf_exts_change(tp, &head->exts, &e);
 
 	return 0;
 errout:
@@ -167,21 +144,17 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
 		       unsigned long *arg, bool ovr)
 {
 	struct cls_mall_head *head = rtnl_dereference(tp->root);
-	struct cls_mall_filter *fold = (struct cls_mall_filter *) *arg;
 	struct net_device *dev = tp->q->dev_queue->dev;
-	struct cls_mall_filter *f;
 	struct nlattr *tb[TCA_MATCHALL_MAX + 1];
+	struct cls_mall_head *new;
 	u32 flags = 0;
 	int err;
 
 	if (!tca[TCA_OPTIONS])
 		return -EINVAL;
 
-	if (head->filter)
-		return -EBUSY;
-
-	if (fold)
-		return -EINVAL;
+	if (head)
+		return -EEXIST;
 
 	err = nla_parse_nested(tb, TCA_MATCHALL_MAX,
 			       tca[TCA_OPTIONS], mall_policy);
@@ -194,25 +167,25 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
 			return -EINVAL;
 	}
 
-	f = kzalloc(sizeof(*f), GFP_KERNEL);
-	if (!f)
+	new = kzalloc(sizeof(*new), GFP_KERNEL);
+	if (!new)
 		return -ENOBUFS;
 
-	err = tcf_exts_init(&f->exts, TCA_MATCHALL_ACT, 0);
+	err = tcf_exts_init(&new->exts, TCA_MATCHALL_ACT, 0);
 	if (err)
 		goto err_exts_init;
 
 	if (!handle)
 		handle = 1;
-	f->handle = handle;
-	f->flags = flags;
+	new->handle = handle;
+	new->flags = flags;
 
-	err = mall_set_parms(net, tp, f, base, tb, tca[TCA_RATE], ovr);
+	err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], ovr);
 	if (err)
 		goto err_set_parms;
 
 	if (tc_should_offload(dev, tp, flags)) {
-		err = mall_replace_hw_filter(tp, f, (unsigned long) f);
+		err = mall_replace_hw_filter(tp, new, (unsigned long) new);
 		if (err) {
 			if (tc_skip_sw(flags))
 				goto err_replace_hw_filter;
@@ -221,42 +194,32 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
 		}
 	}
 
-	*arg = (unsigned long) f;
-	rcu_assign_pointer(head->filter, f);
-
+	*arg = (unsigned long) head;
+	rcu_assign_pointer(tp->root, new);
+	if (head)
+		call_rcu(&head->rcu, mall_destroy_rcu);
 	return 0;
 
 err_replace_hw_filter:
 err_set_parms:
-	tcf_exts_destroy(&f->exts);
+	tcf_exts_destroy(&new->exts);
 err_exts_init:
-	kfree(f);
+	kfree(new);
 	return err;
 }
 
 static int mall_delete(struct tcf_proto *tp, unsigned long arg)
 {
-	struct cls_mall_head *head = rtnl_dereference(tp->root);
-	struct cls_mall_filter *f = (struct cls_mall_filter *) arg;
-	struct net_device *dev = tp->q->dev_queue->dev;
-
-	if (tc_should_offload(dev, tp, f->flags))
-		mall_destroy_hw_filter(tp, f, (unsigned long) f);
-
-	RCU_INIT_POINTER(head->filter, NULL);
-	tcf_unbind_filter(tp, &f->res);
-	call_rcu(&f->rcu, mall_destroy_filter);
-	return 0;
+	return -EOPNOTSUPP;
 }
 
 static void mall_walk(struct tcf_proto *tp, struct tcf_walker *arg)
 {
 	struct cls_mall_head *head = rtnl_dereference(tp->root);
-	struct cls_mall_filter *f = head->filter;
 
 	if (arg->count < arg->skip)
 		goto skip;
-	if (arg->fn(tp, (unsigned long) f, arg) < 0)
+	if (arg->fn(tp, (unsigned long) head, arg) < 0)
 		arg->stop = 1;
 skip:
 	arg->count++;
@@ -265,28 +228,28 @@ static void mall_walk(struct tcf_proto *tp, struct tcf_walker *arg)
 static int mall_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 		     struct sk_buff *skb, struct tcmsg *t)
 {
-	struct cls_mall_filter *f = (struct cls_mall_filter *) fh;
+	struct cls_mall_head *head = (struct cls_mall_head *) fh;
 	struct nlattr *nest;
 
-	if (!f)
+	if (!head)
 		return skb->len;
 
-	t->tcm_handle = f->handle;
+	t->tcm_handle = head->handle;
 
 	nest = nla_nest_start(skb, TCA_OPTIONS);
 	if (!nest)
 		goto nla_put_failure;
 
-	if (f->res.classid &&
-	    nla_put_u32(skb, TCA_MATCHALL_CLASSID, f->res.classid))
+	if (head->res.classid &&
+	    nla_put_u32(skb, TCA_MATCHALL_CLASSID, head->res.classid))
 		goto nla_put_failure;
 
-	if (tcf_exts_dump(skb, &f->exts))
+	if (tcf_exts_dump(skb, &head->exts))
 		goto nla_put_failure;
 
 	nla_nest_end(skb, nest);
 
-	if (tcf_exts_dump_stats(skb, &f->exts) < 0)
+	if (tcf_exts_dump_stats(skb, &head->exts) < 0)
 		goto nla_put_failure;
 
 	return skb->len;
-- 
2.4.11

^ permalink raw reply related

* Re: [PATCH net-next 1/2] vxlan: don't flush static fdb entries on admin down
From: Jiri Benc @ 2017-01-23  8:55 UTC (permalink / raw)
  To: Roopa Prabhu; +Cc: davem, netdev, ramanb, stephen, pshelar
In-Reply-To: <1484984599-16712-2-git-send-email-roopa@cumulusnetworks.com>

On Fri, 20 Jan 2017 23:43:18 -0800, Roopa Prabhu wrote:
> This patch skips flushing static fdb entries in
> ndo_stop, but flushes all fdb entries during vxlan
> device delete. This is consistent with the bridge
> driver fdb

This makes sense but isn't this a uAPI change? Do you know whether
there are users relying on the current behavior?

 Jiri

^ permalink raw reply

* Re: [PATCH net] net/mlx5e: Do not recycle pages from emergency reserve
From: Jesper Dangaard Brouer @ 2017-01-23  9:14 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: brouer, Tom Herbert, Saeed Mahameed, netdev, Tariq Toukan, Davem,
	Saeed Mahameed
In-Reply-To: <1485026809.16328.181.camel@edumazet-glaptop3.roam.corp.google.com>

On Sat, 21 Jan 2017 11:26:49 -0800
Eric Dumazet <eric.dumazet@gmail.com> wrote:

> > My previous measurements show approx 20℅ speedup on a UDP test with
> > delivery to remote CPU.
> >   
> I find this a bit strange. When you have time (ie not while driving your
> car or during week end) please give more details, for example on message
> size.

I tested this with both 64 bytes and 1500 bytes.  After I moved to 50G
and 100G testing then I don't need to use 64 bytes packets to provoke
the bottlenecks in the stack ;-)

> Was it before skb_condense() was added ?

It tested this just before skb_condense() was added.  BUT
skb_condense() does not get activated when using mlx5, because uses
build_skb() ie. not using frags.  

For people that don't realize this:
 Eric's optimization in skb_condense() is about trading remote CPU
 atomic refcnt (put_page) for copy + local CPU refcnt dec.

My measurements show cycles cost local=31 vs. remote=208, thus a
estimated saving around 177 cycles.  Which is spend on calling a fairly
complex function __pskb_pull_tail(), and only works for more complex
SKBs with frags.

-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  LinkedIn: http://www.linkedin.com/in/brouer

^ permalink raw reply

* Re: [PATCH/RFC v2 net-next] ravb: unmap descriptors when freeing rings
From: Simon Horman @ 2017-01-23  9:19 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: David Miller, Magnus Damm, netdev, linux-renesas-soc
In-Reply-To: <8ab10450-5fe3-bc33-6c66-6f3ea861f561@cogentembedded.com>

On Mon, Jan 16, 2017 at 11:41:51PM +0300, Sergei Shtylyov wrote:
> Hello!
> 
> On 01/12/2017 04:18 PM, Simon Horman wrote:
> 
> >...
> 
> >>>>  Here, it stop once an untransmitted buffer is encountered...
> >>>
> >>>Yes, I see that now.
> >>>
> >>>I wonder if we should:
> >>>
> >>>a) paramatise ravb_tx_free() so it may either clear all transmitted buffers
> >>>  (current behaviour) or all buffers (new behaviour).
> >>>b) provide a different version of this loop in ravb_ring_free()
> >>>
> >>>What are your thoughts?
> >>
> >>   I'm voting for (b).
> 
>    After looking at this issue for another time, I'll vote for (a). Sorry
> for back-and-forth on this matter -- I somehow thought we could do a better
> job by scanning all the TX ring...

No problem. I also have had several opinions on this over time.
I'll see about respinning the patch.

> 
> >Ok, something like this?
> >
> >@@ -215,6 +225,30 @@ static void ravb_ring_free(struct net_device *ndev, int q)
> > 	}
> >
> > 	if (priv->tx_ring[q]) {
> >+		for (; priv->cur_tx[q] - priv->dirty_tx[q] > 0; priv->dirty_tx[q]++) {
> >+			struct ravb_tx_desc *desc;
> >+			int entry;
> >+
> >+			entry = priv->dirty_tx[q] % (priv->num_tx_ring[q] *
> >+						     NUM_TX_DESC);
> >+			desc = &priv->tx_ring[q][entry];
> >+
> >+			/* Free the original skb. */
> >+			if (priv->tx_skb[q][entry / NUM_TX_DESC]) {
> >+				u32 size = le16_to_cpu(desc->ds_tagl) & TX_DS;
> >+
> >+				dma_unmap_single(ndev->dev.parent,
> >+						 le32_to_cpu(desc->dptr),
> >+						 size, DMA_TO_DEVICE);
> >+				/* Last packet descriptor? */
> >+				if (entry % NUM_TX_DESC == NUM_TX_DESC - 1) {
> >+					entry /= NUM_TX_DESC;
> >+					dev_kfree_skb_any(priv->tx_skb[q][entry]);
> >+					priv->tx_skb[q][entry] = NULL;
> >+				}
> >+			}
> >+		}
> >+
> 
>    This is only different from ravb_tx_free() by not stopping on unfinished
> descriptor, so we must be good with adding an extra param to it...
> 
> [...]
> 
> MBR, Sergei
> 

^ permalink raw reply

* Re: [PATCH 0/4] Make xfrm usable by 32-bit programs
From: Steffen Klassert @ 2017-01-23  9:35 UTC (permalink / raw)
  To: Kevin Cernekee
  Cc: herbert, davem, paul, sds, eparis, linux-kernel, netdev, selinux,
	fw, fan.du, dianders, dtor
In-Reply-To: <20170121000507.34381-1-cernekee@chromium.org>

On Fri, Jan 20, 2017 at 04:05:03PM -0800, Kevin Cernekee wrote:
> Several of the xfrm netlink and setsockopt() interfaces are not usable
> from a 32-bit binary running on a 64-bit kernel due to struct padding
> differences.  This has been the case for many, many years[0].  This
> patch series deprecates the broken netlink messages and replaces them
> with packed structs that are compatible between 64-bit and 32-bit
> programs.  It retains support for legacy user programs (i.e. anything
> that is currently working today), and allows legacy support to be
> compiled out via CONFIG_XFRM_USER_LEGACY if it becomes unnecessary in
> the future.

This would mean that we have to maintain two APIs from now on.
This is something I really want to avoid because it is almost
impossible to get rid of the old one.

> 
> Earlier attempts at fixing the problem had implemented a compat layer.
> A compat layer is helpful because it avoids the need to recompile old
> user binaries, but there are many challenges involved in implementing
> it.  I believe a compat layer is of limited value in this instance
> because anybody who really needed to solve the problem without
> recompiling their binaries has almost certainly found another solution
> in the ~7 years since the compat patches were first proposed.
> 
> A benefit of this approach is that long-term, the broken netlink messages
> will no longer be used.  A drawback is that in the short term, user
> programs that want to adopt the new message formats will require a
> modern kernel.  Projects like strongSwan and iproute2 bundle the xfrm.h
> header inside their own source trees, so they will need to make a
> judgment call on when to remove support for kernels that do not support
> the new messages.  And programs built against the new kernel headers
> will not work on old kernels.

So this creates new incompatibilities what is another argument against
this approach. If you really need this, try to implement a full compat
layer. I think this is the only sane solution for this.

^ permalink raw reply

* Re: [PATCH] net:phy fix driver reference count error when attach and detach phy device
From: maowenan @ 2017-01-23  9:33 UTC (permalink / raw)
  To: Florian Fainelli, David Laight, netdev@vger.kernel.org,
	Dingtianhong, weiyongjun (A), Andrew Lunn
In-Reply-To: <9086cf5e-18c4-0e17-4f0e-6a630cf1c7d7@gmail.com>



On 2017/1/6 12:48, Florian Fainelli wrote:
> Le 01/05/17 à 19:39, maowenan a écrit :
>>
>>
>> On 2017/1/6 11:21, Florian Fainelli wrote:
>>> +Andrew,
>>>
>>> Le 01/05/17 à 18:29, maowenan a écrit :
>>>>>> @Florian Fainelli, what's your comments about this patch?
>>>>>
>>>>> I am trying to reproduce what you are seeing, but at first glance is looks like an
>>>>> appropriate solution to me. Do you mind giving me a couple more days?
>>>>>
>>>>> Thanks!
>>>>> --
>>>>> Florian
>>>>
>>>> Hi Florian, 
>>>>   Do you have any update about this patch?
>>>
>>> Your patch is not complete, there are now MDIO device (which PHY devices
>>> are a superset of) that would also need a similar fix.
>>>
>> ok, is there any patch to fix MDIO yet?  if not, i will verify it and give a fix patch?
>>
> 
> No, there is not a patch yet, your approach looks okay, but need to be
> made general and cover MDIO devices as well.
> 
> Thank you!
> 

Hi Florian,
Sorry I can't get you. There has already existed codes which are not originally written by me to cover MDIO device in phy_attach_direct and phy_detach in my patch .
Please help check, thank you.
phy_attach_direct:
struct device *d = &phydev->mdio.dev;
...
get_device(d);
...

phy_detach:
 	put_device(&phydev->mdio.dev);       /*--MDIO device--*/
+	module_put(phydev->mdio.dev.driver->owner);
 	module_put(bus->owner);

^ permalink raw reply

* RE: [PATCH v2 net-next] net:add one common config ARCH_WANT_RELAX_ORDER to support relax ordering.
From: David Laight @ 2017-01-23  9:44 UTC (permalink / raw)
  To: 'Alexander Duyck'
  Cc: David Miller, maowenan@huawei.com, netdev@vger.kernel.org,
	jeffrey.t.kirsher@intel.com
In-Reply-To: <CAKgT0UeW1LgzFiycz+aQb8j9VamdXO8Q1mO1DqcazeTkwQmYCA@mail.gmail.com>

Alexander Duyck
> Sent: 19 January 2017 15:55
...
> >> The Relaxed Ordering attribute doesn't get applied across the board.
> >> It ends up being limited to a subset of the transactions if I recall
> >> correctly.  In this case it is the Tx descriptor write back, and the
> >> Rx data write back.  We don't apply the RO bit to any other
> >> transactions.
> >>
> >> In the case of Tx descriptor there is no harm in allowing it to be
> >> reordered because we only really read the DD bit so we don't care
> >> about the ordering of the write back.  In the case of the Rx data the
> >> Rx descriptor essentially acts as a flush since it is sent without the
> >> RO bit set.  So all the writes before it must be completed before the
> >> Rx descriptor write back.
> >
> > In which case why not set it unconditionally for all architectures?
> >
> > I'm surprised (I often am) that allowing those re-orderings makes
> > any significant difference.
> > Unfortunately you need a PCIe analyser to see what is really happening
> > and they don't come cheap.
> >
> > What I do vaguely remember is that some hosts don't always implement
> > the 'normal' re-ordering of reads and read completions.
> > Re-ordering of reads allows descriptor reads to overtake transmit
> > traffic which is likely to make a difference.
> 
> I think part of the issue, at least in the case of SPARC, is that the
> handling of the memory writes in the PCIe root complex is impacted by
> the RO attribute.  On the bus itself it doesn't matter much, but at
> the root complex it can become expensive to have to wait on a partial
> write to complete while there are other writes pending.  This is why
> the IOMMU for SPARC now has a WEAK_ORDERING attribute you can add so
> that it can write the data in whatever order it wants in relation to
> other writes in that region.

I hope the IOMMU only ever reorders writes that have the RO bit set.

Has anyone tried cache invalidates on the rx buffers?
Might make the writes less expensive.
Or is the issue with NUMA rather than cache.

	David


^ permalink raw reply

* [patch net-next v2 0/4] Add support for offloading packet-sampling
From: Jiri Pirko @ 2017-01-23 10:07 UTC (permalink / raw)
  To: netdev
  Cc: davem, yotamg, idosch, eladr, nogahf, ogerlitz, jhs,
	geert+renesas, stephen, xiyou.wangcong, linux, roopa,
	john.fastabend, simon.horman, mrv

From: Jiri Pirko <jiri@mellanox.com>

Yotam says:

The first patch introduces the psample module, a netlink channel dedicated
to packet sampling implemented using generic netlink. This module provides
a generic way for kernel modules to sample packets, while not being tied
to any specific subsystem like NFLOG.

The second patch adds the sample tc action, which uses psample to randomly
sample packets that match a classifier. The user can configure the psample
group number, the sampling rate and the packet's truncation (to save
kernel-user traffic).

The last two patches add the support for offloading the matchall-sample
tc command in the mlxsw driver, for ingress qdiscs.

An example for psample usage can be found in the libpsample project at:
https://github.com/Mellanox/libpsample

---
v1->v2:
- Reword first patch's commit message
- Fix typo in comment in second patch
- Change order of tc_sample uapi enum to match convention
- Rename act_sample action callback tcf_sample -> tcf_sample_act

Yotam Gigi (4):
  net: Introduce psample, a new genetlink channel for packet sampling
  net/sched: Introduce sample tc action
  mlxsw: reg: add the Monitoring Packet Sampling Configuration Register
  mlxsw: spectrum: Add packet sample offloading support

 MAINTAINERS                                    |   7 +
 drivers/net/ethernet/mellanox/mlxsw/reg.h      |  41 ++++
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 111 +++++++++
 drivers/net/ethernet/mellanox/mlxsw/spectrum.h |  10 +
 drivers/net/ethernet/mellanox/mlxsw/trap.h     |   1 +
 include/net/psample.h                          |  36 +++
 include/net/tc_act/tc_sample.h                 |  50 ++++
 include/uapi/linux/Kbuild                      |   1 +
 include/uapi/linux/psample.h                   |  35 +++
 include/uapi/linux/tc_act/Kbuild               |   1 +
 include/uapi/linux/tc_act/tc_sample.h          |  26 +++
 net/Kconfig                                    |   1 +
 net/Makefile                                   |   1 +
 net/psample/Kconfig                            |  15 ++
 net/psample/Makefile                           |   5 +
 net/psample/psample.c                          | 301 +++++++++++++++++++++++++
 net/sched/Kconfig                              |  12 +
 net/sched/Makefile                             |   1 +
 net/sched/act_sample.c                         | 274 ++++++++++++++++++++++
 19 files changed, 929 insertions(+)
 create mode 100644 include/net/psample.h
 create mode 100644 include/net/tc_act/tc_sample.h
 create mode 100644 include/uapi/linux/psample.h
 create mode 100644 include/uapi/linux/tc_act/tc_sample.h
 create mode 100644 net/psample/Kconfig
 create mode 100644 net/psample/Makefile
 create mode 100644 net/psample/psample.c
 create mode 100644 net/sched/act_sample.c

-- 
2.7.4

^ permalink raw reply

* [patch net-next v2 1/4] net: Introduce psample, a new genetlink channel for packet sampling
From: Jiri Pirko @ 2017-01-23 10:07 UTC (permalink / raw)
  To: netdev
  Cc: davem, yotamg, idosch, eladr, nogahf, ogerlitz, jhs,
	geert+renesas, stephen, xiyou.wangcong, linux, roopa,
	john.fastabend, simon.horman, mrv
In-Reply-To: <1485166031-4773-1-git-send-email-jiri@resnulli.us>

From: Yotam Gigi <yotamg@mellanox.com>

Add a general way for kernel modules to sample packets, without being tied
to any specific subsystem. This netlink channel can be used by tc,
iptables, etc. and allow to standardize packet sampling in the kernel.

For every sampled packet, the psample module adds the following metadata
fields:

PSAMPLE_ATTR_IIFINDEX - the packets input ifindex, if applicable

PSAMPLE_ATTR_OIFINDEX - the packet output ifindex, if applicable

PSAMPLE_ATTR_ORIGSIZE - the packet's original size, in case it has been
   truncated during sampling

PSAMPLE_ATTR_SAMPLE_GROUP - the packet's sample group, which is set by the
   user who initiated the sampling. This field allows the user to
   differentiate between several samplers working simultaneously and
   filter packets relevant to him

PSAMPLE_ATTR_GROUP_SEQ - sequence counter of last sent packet. The
   sequence is kept for each group

PSAMPLE_ATTR_SAMPLE_RATE - the sampling rate used for sampling the packets

PSAMPLE_ATTR_DATA - the actual packet bits

The sampled packets are sent to the PSAMPLE_NL_MCGRP_SAMPLE multicast
group. In addition, add the GET_GROUPS netlink command which allows the
user to see the current sample groups, their refcount and sequence number.
This command currently supports only netlink dump mode.

Signed-off-by: Yotam Gigi <yotamg@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
 MAINTAINERS                  |   7 +
 include/net/psample.h        |  36 ++++++
 include/uapi/linux/Kbuild    |   1 +
 include/uapi/linux/psample.h |  35 +++++
 net/Kconfig                  |   1 +
 net/Makefile                 |   1 +
 net/psample/Kconfig          |  15 +++
 net/psample/Makefile         |   5 +
 net/psample/psample.c        | 301 +++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 402 insertions(+)
 create mode 100644 include/net/psample.h
 create mode 100644 include/uapi/linux/psample.h
 create mode 100644 net/psample/Kconfig
 create mode 100644 net/psample/Makefile
 create mode 100644 net/psample/psample.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 3c84a8f..d76fccd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9957,6 +9957,13 @@ L:	linuxppc-dev@lists.ozlabs.org
 S:	Maintained
 F:	drivers/block/ps3vram.c
 
+PSAMPLE PACKET SAMPLING SUPPORT:
+M:	Yotam Gigi <yotamg@mellanox.com>
+S:	Maintained
+F:	net/psample
+F:	include/net/psample.h
+F:	include/uapi/linux/psample.h
+
 PSTORE FILESYSTEM
 M:	Anton Vorontsov <anton@enomsg.org>
 M:	Colin Cross <ccross@android.com>
diff --git a/include/net/psample.h b/include/net/psample.h
new file mode 100644
index 0000000..8888b0e
--- /dev/null
+++ b/include/net/psample.h
@@ -0,0 +1,36 @@
+#ifndef __NET_PSAMPLE_H
+#define __NET_PSAMPLE_H
+
+#include <uapi/linux/psample.h>
+#include <linux/module.h>
+#include <linux/list.h>
+
+struct psample_group {
+	struct list_head list;
+	struct net *net;
+	u32 group_num;
+	u32 refcount;
+	u32 seq;
+};
+
+struct psample_group *psample_group_get(struct net *net, u32 group_num);
+void psample_group_put(struct psample_group *group);
+
+#if IS_ENABLED(CONFIG_PSAMPLE)
+
+void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
+			   u32 trunc_size, int in_ifindex, int out_ifindex,
+			   u32 sample_rate);
+
+#else
+
+static inline void psample_sample_packet(struct psample_group *group,
+					 struct sk_buff *skb, u32 trunc_size,
+					 int in_ifindex, int out_ifindex,
+					 u32 sample_rate)
+{
+}
+
+#endif
+
+#endif /* __NET_PSAMPLE_H */
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index e600b50..80ad741 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -305,6 +305,7 @@ header-y += netrom.h
 header-y += net_namespace.h
 header-y += net_tstamp.h
 header-y += nfc.h
+header-y += psample.h
 header-y += nfs2.h
 header-y += nfs3.h
 header-y += nfs4.h
diff --git a/include/uapi/linux/psample.h b/include/uapi/linux/psample.h
new file mode 100644
index 0000000..ed48996
--- /dev/null
+++ b/include/uapi/linux/psample.h
@@ -0,0 +1,35 @@
+#ifndef __UAPI_PSAMPLE_H
+#define __UAPI_PSAMPLE_H
+
+enum {
+	/* sampled packet metadata */
+	PSAMPLE_ATTR_IIFINDEX,
+	PSAMPLE_ATTR_OIFINDEX,
+	PSAMPLE_ATTR_ORIGSIZE,
+	PSAMPLE_ATTR_SAMPLE_GROUP,
+	PSAMPLE_ATTR_GROUP_SEQ,
+	PSAMPLE_ATTR_SAMPLE_RATE,
+	PSAMPLE_ATTR_DATA,
+
+	/* commands attributes */
+	PSAMPLE_ATTR_GROUP_REFCOUNT,
+
+	__PSAMPLE_ATTR_MAX
+};
+
+enum psample_command {
+	PSAMPLE_CMD_SAMPLE,
+	PSAMPLE_CMD_GET_GROUP,
+	PSAMPLE_CMD_NEW_GROUP,
+	PSAMPLE_CMD_DEL_GROUP,
+};
+
+/* Can be overridden at runtime by module option */
+#define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1)
+
+#define PSAMPLE_NL_MCGRP_CONFIG_NAME "config"
+#define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets"
+#define PSAMPLE_GENL_NAME "psample"
+#define PSAMPLE_GENL_VERSION 1
+
+#endif
diff --git a/net/Kconfig b/net/Kconfig
index 92ae150..ce4aee6 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -390,6 +390,7 @@ source "net/9p/Kconfig"
 source "net/caif/Kconfig"
 source "net/ceph/Kconfig"
 source "net/nfc/Kconfig"
+source "net/psample/Kconfig"
 
 config LWTUNNEL
 	bool "Network light weight tunnels"
diff --git a/net/Makefile b/net/Makefile
index 5d6e0e5f..7d41de4 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_DNS_RESOLVER)	+= dns_resolver/
 obj-$(CONFIG_CEPH_LIB)		+= ceph/
 obj-$(CONFIG_BATMAN_ADV)	+= batman-adv/
 obj-$(CONFIG_NFC)		+= nfc/
+obj-$(CONFIG_PSAMPLE)		+= psample/
 obj-$(CONFIG_OPENVSWITCH)	+= openvswitch/
 obj-$(CONFIG_VSOCKETS)	+= vmw_vsock/
 obj-$(CONFIG_MPLS)		+= mpls/
diff --git a/net/psample/Kconfig b/net/psample/Kconfig
new file mode 100644
index 0000000..d850246
--- /dev/null
+++ b/net/psample/Kconfig
@@ -0,0 +1,15 @@
+#
+# psample packet sampling configuration
+#
+
+menuconfig PSAMPLE
+	depends on NET
+	tristate "Packet-sampling netlink channel"
+	default n
+	help
+	  Say Y here to add support for packet-sampling netlink channel
+	  This netlink channel allows transferring packets alongside some
+	  metadata to userspace.
+
+	  To compile this support as a module, choose M here: the module will
+	  be called psample.
diff --git a/net/psample/Makefile b/net/psample/Makefile
new file mode 100644
index 0000000..609b0a7
--- /dev/null
+++ b/net/psample/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the psample netlink channel
+#
+
+obj-$(CONFIG_PSAMPLE) += psample.o
diff --git a/net/psample/psample.c b/net/psample/psample.c
new file mode 100644
index 0000000..8aa58a9
--- /dev/null
+++ b/net/psample/psample.c
@@ -0,0 +1,301 @@
+/*
+ * net/psample/psample.c - Netlink channel for packet sampling
+ * Copyright (c) 2017 Yotam Gigi <yotamg@mellanox.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/skbuff.h>
+#include <linux/module.h>
+#include <net/net_namespace.h>
+#include <net/sock.h>
+#include <net/netlink.h>
+#include <net/genetlink.h>
+#include <net/psample.h>
+#include <linux/spinlock.h>
+
+#define PSAMPLE_MAX_PACKET_SIZE 0xffff
+
+static LIST_HEAD(psample_groups_list);
+static DEFINE_SPINLOCK(psample_groups_lock);
+
+/* multicast groups */
+enum psample_nl_multicast_groups {
+	PSAMPLE_NL_MCGRP_CONFIG,
+	PSAMPLE_NL_MCGRP_SAMPLE,
+};
+
+static const struct genl_multicast_group psample_nl_mcgrps[] = {
+	[PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME },
+	[PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME },
+};
+
+static struct genl_family psample_nl_family __ro_after_init;
+
+static int psample_group_nl_fill(struct sk_buff *msg,
+				 struct psample_group *group,
+				 enum psample_command cmd, u32 portid, u32 seq,
+				 int flags)
+{
+	void *hdr;
+	int ret;
+
+	hdr = genlmsg_put(msg, portid, seq, &psample_nl_family, flags, cmd);
+	if (!hdr)
+		return -EMSGSIZE;
+
+	ret = nla_put_u32(msg, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num);
+	if (ret < 0)
+		goto error;
+
+	ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_REFCOUNT, group->refcount);
+	if (ret < 0)
+		goto error;
+
+	ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_SEQ, group->seq);
+	if (ret < 0)
+		goto error;
+
+	genlmsg_end(msg, hdr);
+	return 0;
+
+error:
+	genlmsg_cancel(msg, hdr);
+	return -EMSGSIZE;
+}
+
+static int psample_nl_cmd_get_group_dumpit(struct sk_buff *msg,
+					   struct netlink_callback *cb)
+{
+	struct psample_group *group;
+	int start = cb->args[0];
+	int idx = 0;
+	int err;
+
+	spin_lock(&psample_groups_lock);
+	list_for_each_entry(group, &psample_groups_list, list) {
+		if (!net_eq(group->net, sock_net(msg->sk)))
+			continue;
+		if (idx < start) {
+			idx++;
+			continue;
+		}
+		err = psample_group_nl_fill(msg, group, PSAMPLE_CMD_NEW_GROUP,
+					    NETLINK_CB(cb->skb).portid,
+					    cb->nlh->nlmsg_seq, NLM_F_MULTI);
+		if (err)
+			break;
+		idx++;
+	}
+
+	spin_unlock(&psample_groups_lock);
+	cb->args[0] = idx;
+	return msg->len;
+}
+
+static const struct genl_ops psample_nl_ops[] = {
+	{
+		.cmd = PSAMPLE_CMD_GET_GROUP,
+		.dumpit = psample_nl_cmd_get_group_dumpit,
+		/* can be retrieved by unprivileged users */
+	}
+};
+
+static struct genl_family psample_nl_family __ro_after_init = {
+	.name		= PSAMPLE_GENL_NAME,
+	.version	= PSAMPLE_GENL_VERSION,
+	.maxattr	= PSAMPLE_ATTR_MAX,
+	.netnsok	= true,
+	.module		= THIS_MODULE,
+	.mcgrps		= psample_nl_mcgrps,
+	.ops		= psample_nl_ops,
+	.n_ops		= ARRAY_SIZE(psample_nl_ops),
+	.n_mcgrps	= ARRAY_SIZE(psample_nl_mcgrps),
+};
+
+static void psample_group_notify(struct psample_group *group,
+				 enum psample_command cmd)
+{
+	struct sk_buff *msg;
+	int err;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+	if (!msg)
+		return;
+
+	err = psample_group_nl_fill(msg, group, cmd, 0, 0, NLM_F_MULTI);
+	if (!err)
+		genlmsg_multicast_netns(&psample_nl_family, group->net, msg, 0,
+					PSAMPLE_NL_MCGRP_CONFIG, GFP_ATOMIC);
+	else
+		nlmsg_free(msg);
+}
+
+static struct psample_group *psample_group_create(struct net *net,
+						  u32 group_num)
+{
+	struct psample_group *group;
+
+	group = kzalloc(sizeof(*group), GFP_ATOMIC);
+	if (!group)
+		return NULL;
+
+	group->net = net;
+	group->group_num = group_num;
+	list_add_tail(&group->list, &psample_groups_list);
+
+	psample_group_notify(group, PSAMPLE_CMD_NEW_GROUP);
+	return group;
+}
+
+static void psample_group_destroy(struct psample_group *group)
+{
+	psample_group_notify(group, PSAMPLE_CMD_DEL_GROUP);
+	list_del(&group->list);
+	kfree(group);
+}
+
+static struct psample_group *
+psample_group_lookup(struct net *net, u32 group_num)
+{
+	struct psample_group *group;
+
+	list_for_each_entry(group, &psample_groups_list, list)
+		if ((group->group_num == group_num) && (group->net == net))
+			return group;
+	return NULL;
+}
+
+struct psample_group *psample_group_get(struct net *net, u32 group_num)
+{
+	struct psample_group *group;
+
+	spin_lock(&psample_groups_lock);
+
+	group = psample_group_lookup(net, group_num);
+	if (!group) {
+		group = psample_group_create(net, group_num);
+		if (!group)
+			goto out;
+	}
+	group->refcount++;
+
+out:
+	spin_unlock(&psample_groups_lock);
+	return group;
+}
+EXPORT_SYMBOL_GPL(psample_group_get);
+
+void psample_group_put(struct psample_group *group)
+{
+	spin_lock(&psample_groups_lock);
+
+	if (--group->refcount == 0)
+		psample_group_destroy(group);
+
+	spin_unlock(&psample_groups_lock);
+}
+EXPORT_SYMBOL_GPL(psample_group_put);
+
+void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
+			   u32 trunc_size, int in_ifindex, int out_ifindex,
+			   u32 sample_rate)
+{
+	struct sk_buff *nl_skb;
+	int data_len;
+	int meta_len;
+	void *data;
+	int ret;
+
+	meta_len = (in_ifindex ? nla_total_size(sizeof(u16)) : 0) +
+		   (out_ifindex ? nla_total_size(sizeof(u16)) : 0) +
+		   nla_total_size(sizeof(u32)) +	/* sample_rate */
+		   nla_total_size(sizeof(u32)) +	/* orig_size */
+		   nla_total_size(sizeof(u32)) +	/* group_num */
+		   nla_total_size(sizeof(u32));		/* seq */
+
+	data_len = min(skb->len, trunc_size);
+	if (meta_len + nla_total_size(data_len) > PSAMPLE_MAX_PACKET_SIZE)
+		data_len = PSAMPLE_MAX_PACKET_SIZE - meta_len - NLA_HDRLEN
+			    - NLA_ALIGNTO;
+
+	nl_skb = genlmsg_new(meta_len + data_len, GFP_ATOMIC);
+	if (unlikely(!nl_skb))
+		return;
+
+	data = genlmsg_put(nl_skb, 0, 0, &psample_nl_family, 0,
+			   PSAMPLE_CMD_SAMPLE);
+	if (unlikely(!data))
+		goto error;
+
+	if (in_ifindex) {
+		ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_IIFINDEX, in_ifindex);
+		if (unlikely(ret < 0))
+			goto error;
+	}
+
+	if (out_ifindex) {
+		ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_OIFINDEX, out_ifindex);
+		if (unlikely(ret < 0))
+			goto error;
+	}
+
+	ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_RATE, sample_rate);
+	if (unlikely(ret < 0))
+		goto error;
+
+	ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_ORIGSIZE, skb->len);
+	if (unlikely(ret < 0))
+		goto error;
+
+	ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num);
+	if (unlikely(ret < 0))
+		goto error;
+
+	ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_GROUP_SEQ, group->seq++);
+	if (unlikely(ret < 0))
+		goto error;
+
+	if (data_len) {
+		int nla_len = nla_total_size(data_len);
+		struct nlattr *nla;
+
+		nla = (struct nlattr *)skb_put(nl_skb, nla_len);
+		nla->nla_type = PSAMPLE_ATTR_DATA;
+		nla->nla_len = nla_attr_size(data_len);
+
+		if (skb_copy_bits(skb, 0, nla_data(nla), data_len))
+			goto error;
+	}
+
+	genlmsg_end(nl_skb, data);
+	genlmsg_multicast_netns(&psample_nl_family, group->net, nl_skb, 0,
+				PSAMPLE_NL_MCGRP_SAMPLE, GFP_ATOMIC);
+
+	return;
+error:
+	pr_err_ratelimited("Could not create psample log message\n");
+	nlmsg_free(nl_skb);
+}
+EXPORT_SYMBOL_GPL(psample_sample_packet);
+
+static int __init psample_module_init(void)
+{
+	return genl_register_family(&psample_nl_family);
+}
+
+static void __exit psample_module_exit(void)
+{
+	genl_unregister_family(&psample_nl_family);
+}
+
+module_init(psample_module_init);
+module_exit(psample_module_exit);
+
+MODULE_AUTHOR("Yotam Gigi <yotamg@mellanox.com>");
+MODULE_DESCRIPTION("netlink channel for packet sampling");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4

^ permalink raw reply related

* [patch net-next v2 2/4] net/sched: Introduce sample tc action
From: Jiri Pirko @ 2017-01-23 10:07 UTC (permalink / raw)
  To: netdev
  Cc: davem, yotamg, idosch, eladr, nogahf, ogerlitz, jhs,
	geert+renesas, stephen, xiyou.wangcong, linux, roopa,
	john.fastabend, simon.horman, mrv
In-Reply-To: <1485166031-4773-1-git-send-email-jiri@resnulli.us>

From: Yotam Gigi <yotamg@mellanox.com>

This action allows the user to sample traffic matched by tc classifier.
The sampling consists of choosing packets randomly and sampling them using
the psample module. The user can configure the psample group number, the
sampling rate and the packet's truncation (to save kernel-user traffic).

Example:
To sample ingress traffic from interface eth1, one may use the commands:

tc qdisc add dev eth1 handle ffff: ingress

tc filter add dev eth1 parent ffff: \
	   matchall action sample rate 12 group 4

Where the first command adds an ingress qdisc and the second starts
sampling randomly with an average of one sampled packet per 12 packets on
dev eth1 to psample group 4.

Signed-off-by: Yotam Gigi <yotamg@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
 include/net/tc_act/tc_sample.h        |  50 +++++++
 include/uapi/linux/tc_act/Kbuild      |   1 +
 include/uapi/linux/tc_act/tc_sample.h |  26 ++++
 net/sched/Kconfig                     |  12 ++
 net/sched/Makefile                    |   1 +
 net/sched/act_sample.c                | 274 ++++++++++++++++++++++++++++++++++
 6 files changed, 364 insertions(+)
 create mode 100644 include/net/tc_act/tc_sample.h
 create mode 100644 include/uapi/linux/tc_act/tc_sample.h
 create mode 100644 net/sched/act_sample.c

diff --git a/include/net/tc_act/tc_sample.h b/include/net/tc_act/tc_sample.h
new file mode 100644
index 0000000..89e9305
--- /dev/null
+++ b/include/net/tc_act/tc_sample.h
@@ -0,0 +1,50 @@
+#ifndef __NET_TC_SAMPLE_H
+#define __NET_TC_SAMPLE_H
+
+#include <net/act_api.h>
+#include <linux/tc_act/tc_sample.h>
+#include <net/psample.h>
+
+struct tcf_sample {
+	struct tc_action common;
+	u32 rate;
+	bool truncate;
+	u32 trunc_size;
+	struct psample_group __rcu *psample_group;
+	u32 psample_group_num;
+	struct list_head tcfm_list;
+	struct rcu_head rcu;
+};
+#define to_sample(a) ((struct tcf_sample *)a)
+
+static inline bool is_tcf_sample(const struct tc_action *a)
+{
+#ifdef CONFIG_NET_CLS_ACT
+	return a->ops && a->ops->type == TCA_ACT_SAMPLE;
+#else
+	return false;
+#endif
+}
+
+static inline __u32 tcf_sample_rate(const struct tc_action *a)
+{
+	return to_sample(a)->rate;
+}
+
+static inline bool tcf_sample_truncate(const struct tc_action *a)
+{
+	return to_sample(a)->truncate;
+}
+
+static inline int tcf_sample_trunc_size(const struct tc_action *a)
+{
+	return to_sample(a)->trunc_size;
+}
+
+static inline struct psample_group *
+tcf_sample_psample_group(const struct tc_action *a)
+{
+	return rcu_dereference(to_sample(a)->psample_group);
+}
+
+#endif /* __NET_TC_SAMPLE_H */
diff --git a/include/uapi/linux/tc_act/Kbuild b/include/uapi/linux/tc_act/Kbuild
index e3db740..ba62ddf 100644
--- a/include/uapi/linux/tc_act/Kbuild
+++ b/include/uapi/linux/tc_act/Kbuild
@@ -4,6 +4,7 @@ header-y += tc_defact.h
 header-y += tc_gact.h
 header-y += tc_ipt.h
 header-y += tc_mirred.h
+header-y += tc_sample.h
 header-y += tc_nat.h
 header-y += tc_pedit.h
 header-y += tc_skbedit.h
diff --git a/include/uapi/linux/tc_act/tc_sample.h b/include/uapi/linux/tc_act/tc_sample.h
new file mode 100644
index 0000000..edc9058
--- /dev/null
+++ b/include/uapi/linux/tc_act/tc_sample.h
@@ -0,0 +1,26 @@
+#ifndef __LINUX_TC_SAMPLE_H
+#define __LINUX_TC_SAMPLE_H
+
+#include <linux/types.h>
+#include <linux/pkt_cls.h>
+#include <linux/if_ether.h>
+
+#define TCA_ACT_SAMPLE 26
+
+struct tc_sample {
+	tc_gen;
+};
+
+enum {
+	TCA_SAMPLE_UNSPEC,
+	TCA_SAMPLE_TM,
+	TCA_SAMPLE_PARMS,
+	TCA_SAMPLE_RATE,
+	TCA_SAMPLE_TRUNC_SIZE,
+	TCA_SAMPLE_PSAMPLE_GROUP,
+	TCA_SAMPLE_PAD,
+	__TCA_SAMPLE_MAX
+};
+#define TCA_SAMPLE_MAX (__TCA_SAMPLE_MAX - 1)
+
+#endif
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index a9aa38d..72cfa3a 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -650,6 +650,18 @@ config NET_ACT_MIRRED
 	  To compile this code as a module, choose M here: the
 	  module will be called act_mirred.
 
+config NET_ACT_SAMPLE
+        tristate "Traffic Sampling"
+        depends on NET_CLS_ACT
+        select PSAMPLE
+        ---help---
+	  Say Y here to allow packet sampling tc action. The packet sample
+	  action consists of statistically choosing packets and sampling
+	  them using the psample module.
+
+	  To compile this code as a module, choose M here: the
+	  module will be called act_sample.
+
 config NET_ACT_IPT
         tristate "IPtables targets"
         depends on NET_CLS_ACT && NETFILTER && IP_NF_IPTABLES
diff --git a/net/sched/Makefile b/net/sched/Makefile
index 4bdda36..7b915d2 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_NET_CLS_ACT)	+= act_api.o
 obj-$(CONFIG_NET_ACT_POLICE)	+= act_police.o
 obj-$(CONFIG_NET_ACT_GACT)	+= act_gact.o
 obj-$(CONFIG_NET_ACT_MIRRED)	+= act_mirred.o
+obj-$(CONFIG_NET_ACT_SAMPLE)	+= act_sample.o
 obj-$(CONFIG_NET_ACT_IPT)	+= act_ipt.o
 obj-$(CONFIG_NET_ACT_NAT)	+= act_nat.o
 obj-$(CONFIG_NET_ACT_PEDIT)	+= act_pedit.o
diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c
new file mode 100644
index 0000000..3922975
--- /dev/null
+++ b/net/sched/act_sample.c
@@ -0,0 +1,274 @@
+/*
+ * net/sched/act_sample.c - Packet sampling tc action
+ * Copyright (c) 2017 Yotam Gigi <yotamg@mellanox.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+#include <linux/rtnetlink.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/gfp.h>
+#include <net/net_namespace.h>
+#include <net/netlink.h>
+#include <net/pkt_sched.h>
+#include <linux/tc_act/tc_sample.h>
+#include <net/tc_act/tc_sample.h>
+#include <net/psample.h>
+
+#include <linux/if_arp.h>
+
+#define SAMPLE_TAB_MASK     7
+static unsigned int sample_net_id;
+static struct tc_action_ops act_sample_ops;
+
+static const struct nla_policy sample_policy[TCA_SAMPLE_MAX + 1] = {
+	[TCA_SAMPLE_PARMS]		= { .len = sizeof(struct tc_sample) },
+	[TCA_SAMPLE_RATE]		= { .type = NLA_U32 },
+	[TCA_SAMPLE_TRUNC_SIZE]		= { .type = NLA_U32 },
+	[TCA_SAMPLE_PSAMPLE_GROUP]	= { .type = NLA_U32 },
+};
+
+static int tcf_sample_init(struct net *net, struct nlattr *nla,
+			   struct nlattr *est, struct tc_action **a, int ovr,
+			   int bind)
+{
+	struct tc_action_net *tn = net_generic(net, sample_net_id);
+	struct nlattr *tb[TCA_SAMPLE_MAX + 1];
+	struct psample_group *psample_group;
+	struct tc_sample *parm;
+	struct tcf_sample *s;
+	bool exists = false;
+	int ret;
+
+	if (!nla)
+		return -EINVAL;
+	ret = nla_parse_nested(tb, TCA_SAMPLE_MAX, nla, sample_policy);
+	if (ret < 0)
+		return ret;
+	if (!tb[TCA_SAMPLE_PARMS] || !tb[TCA_SAMPLE_RATE] ||
+	    !tb[TCA_SAMPLE_PSAMPLE_GROUP])
+		return -EINVAL;
+
+	parm = nla_data(tb[TCA_SAMPLE_PARMS]);
+
+	exists = tcf_hash_check(tn, parm->index, a, bind);
+	if (exists && bind)
+		return 0;
+
+	if (!exists) {
+		ret = tcf_hash_create(tn, parm->index, est, a,
+				      &act_sample_ops, bind, false);
+		if (ret)
+			return ret;
+		ret = ACT_P_CREATED;
+	} else {
+		tcf_hash_release(*a, bind);
+		if (!ovr)
+			return -EEXIST;
+	}
+	s = to_sample(*a);
+
+	ASSERT_RTNL();
+	s->tcf_action = parm->action;
+	s->rate = nla_get_u32(tb[TCA_SAMPLE_RATE]);
+	s->psample_group_num = nla_get_u32(tb[TCA_SAMPLE_PSAMPLE_GROUP]);
+	psample_group = psample_group_get(net, s->psample_group_num);
+	if (!psample_group)
+		return -ENOMEM;
+	RCU_INIT_POINTER(s->psample_group, psample_group);
+
+	if (tb[TCA_SAMPLE_TRUNC_SIZE]) {
+		s->truncate = true;
+		s->trunc_size = nla_get_u32(tb[TCA_SAMPLE_TRUNC_SIZE]);
+	}
+
+	if (ret == ACT_P_CREATED)
+		tcf_hash_insert(tn, *a);
+	return ret;
+}
+
+static void tcf_sample_cleanup_rcu(struct rcu_head *rcu)
+{
+	struct tcf_sample *s = container_of(rcu, struct tcf_sample, rcu);
+	struct psample_group *psample_group;
+
+	psample_group = rcu_dereference_protected(s->psample_group, 1);
+	RCU_INIT_POINTER(s->psample_group, NULL);
+	psample_group_put(psample_group);
+}
+
+static void tcf_sample_cleanup(struct tc_action *a, int bind)
+{
+	struct tcf_sample *s = to_sample(a);
+
+	call_rcu(&s->rcu, tcf_sample_cleanup_rcu);
+}
+
+static bool tcf_sample_dev_ok_push(struct net_device *dev)
+{
+	switch (dev->type) {
+	case ARPHRD_TUNNEL:
+	case ARPHRD_TUNNEL6:
+	case ARPHRD_SIT:
+	case ARPHRD_IPGRE:
+	case ARPHRD_VOID:
+	case ARPHRD_NONE:
+		return false;
+	default:
+		return true;
+	}
+}
+
+static int tcf_sample_act(struct sk_buff *skb, const struct tc_action *a,
+			  struct tcf_result *res)
+{
+	struct tcf_sample *s = to_sample(a);
+	struct psample_group *psample_group;
+	int retval;
+	int size;
+	int iif;
+	int oif;
+
+	tcf_lastuse_update(&s->tcf_tm);
+	bstats_cpu_update(this_cpu_ptr(s->common.cpu_bstats), skb);
+	retval = READ_ONCE(s->tcf_action);
+
+	rcu_read_lock();
+	psample_group = rcu_dereference(s->psample_group);
+
+	/* randomly sample packets according to rate */
+	if (psample_group && (prandom_u32() % s->rate == 0)) {
+		if (!skb_at_tc_ingress(skb)) {
+			iif = skb->skb_iif;
+			oif = skb->dev->ifindex;
+		} else {
+			iif = skb->dev->ifindex;
+			oif = 0;
+		}
+
+		/* on ingress, the mac header gets popped, so push it back */
+		if (skb_at_tc_ingress(skb) && tcf_sample_dev_ok_push(skb->dev))
+			skb_push(skb, skb->mac_len);
+
+		size = s->truncate ? s->trunc_size : skb->len;
+		psample_sample_packet(psample_group, skb, size, iif, oif,
+				      s->rate);
+
+		if (skb_at_tc_ingress(skb) && tcf_sample_dev_ok_push(skb->dev))
+			skb_pull(skb, skb->mac_len);
+	}
+
+	rcu_read_unlock();
+	return retval;
+}
+
+static int tcf_sample_dump(struct sk_buff *skb, struct tc_action *a,
+			   int bind, int ref)
+{
+	unsigned char *b = skb_tail_pointer(skb);
+	struct tcf_sample *s = to_sample(a);
+	struct tc_sample opt = {
+		.index      = s->tcf_index,
+		.action     = s->tcf_action,
+		.refcnt     = s->tcf_refcnt - ref,
+		.bindcnt    = s->tcf_bindcnt - bind,
+	};
+	struct tcf_t t;
+
+	if (nla_put(skb, TCA_SAMPLE_PARMS, sizeof(opt), &opt))
+		goto nla_put_failure;
+
+	tcf_tm_dump(&t, &s->tcf_tm);
+	if (nla_put_64bit(skb, TCA_SAMPLE_TM, sizeof(t), &t, TCA_SAMPLE_PAD))
+		goto nla_put_failure;
+
+	if (nla_put_u32(skb, TCA_SAMPLE_RATE, s->rate))
+		goto nla_put_failure;
+
+	if (s->truncate)
+		if (nla_put_u32(skb, TCA_SAMPLE_TRUNC_SIZE, s->trunc_size))
+			goto nla_put_failure;
+
+	if (nla_put_u32(skb, TCA_SAMPLE_PSAMPLE_GROUP, s->psample_group_num))
+		goto nla_put_failure;
+	return skb->len;
+
+nla_put_failure:
+	nlmsg_trim(skb, b);
+	return -1;
+}
+
+static int tcf_sample_walker(struct net *net, struct sk_buff *skb,
+			     struct netlink_callback *cb, int type,
+			     const struct tc_action_ops *ops)
+{
+	struct tc_action_net *tn = net_generic(net, sample_net_id);
+
+	return tcf_generic_walker(tn, skb, cb, type, ops);
+}
+
+static int tcf_sample_search(struct net *net, struct tc_action **a, u32 index)
+{
+	struct tc_action_net *tn = net_generic(net, sample_net_id);
+
+	return tcf_hash_search(tn, a, index);
+}
+
+static struct tc_action_ops act_sample_ops = {
+	.kind	  = "sample",
+	.type	  = TCA_ACT_SAMPLE,
+	.owner	  = THIS_MODULE,
+	.act	  = tcf_sample_act,
+	.dump	  = tcf_sample_dump,
+	.init	  = tcf_sample_init,
+	.cleanup  = tcf_sample_cleanup,
+	.walk	  = tcf_sample_walker,
+	.lookup	  = tcf_sample_search,
+	.size	  = sizeof(struct tcf_sample),
+};
+
+static __net_init int sample_init_net(struct net *net)
+{
+	struct tc_action_net *tn = net_generic(net, sample_net_id);
+
+	return tc_action_net_init(tn, &act_sample_ops, SAMPLE_TAB_MASK);
+}
+
+static void __net_exit sample_exit_net(struct net *net)
+{
+	struct tc_action_net *tn = net_generic(net, sample_net_id);
+
+	tc_action_net_exit(tn);
+}
+
+static struct pernet_operations sample_net_ops = {
+	.init = sample_init_net,
+	.exit = sample_exit_net,
+	.id   = &sample_net_id,
+	.size = sizeof(struct tc_action_net),
+};
+
+static int __init sample_init_module(void)
+{
+	return tcf_register_action(&act_sample_ops, &sample_net_ops);
+}
+
+static void __exit sample_cleanup_module(void)
+{
+	tcf_unregister_action(&act_sample_ops, &sample_net_ops);
+}
+
+module_init(sample_init_module);
+module_exit(sample_cleanup_module);
+
+MODULE_AUTHOR("Yotam Gigi <yotamg@mellanox.com>");
+MODULE_DESCRIPTION("Packet sampling action");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4

^ permalink raw reply related

* [patch net-next v2 3/4] mlxsw: reg: add the Monitoring Packet Sampling Configuration Register
From: Jiri Pirko @ 2017-01-23 10:07 UTC (permalink / raw)
  To: netdev
  Cc: davem, yotamg, idosch, eladr, nogahf, ogerlitz, jhs,
	geert+renesas, stephen, xiyou.wangcong, linux, roopa,
	john.fastabend, simon.horman, mrv
In-Reply-To: <1485166031-4773-1-git-send-email-jiri@resnulli.us>

From: Yotam Gigi <yotamg@mellanox.com>

The MPSC register allows to configure ingress packet sampling on specific
port of the mlxsw device. The sampled packets are then trapped via
PKT_SAMPLE trap.

Signed-off-by: Yotam Gigi <yotamg@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/reg.h | 41 +++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index 1357fe0..9fb0316 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -4965,6 +4965,46 @@ static inline void mlxsw_reg_mlcr_pack(char *payload, u8 local_port,
 					   MLXSW_REG_MLCR_DURATION_MAX : 0);
 }
 
+/* MPSC - Monitoring Packet Sampling Configuration Register
+ * --------------------------------------------------------
+ * MPSC Register is used to configure the Packet Sampling mechanism.
+ */
+#define MLXSW_REG_MPSC_ID 0x9080
+#define MLXSW_REG_MPSC_LEN 0x1C
+
+MLXSW_REG_DEFINE(mpsc, MLXSW_REG_MPSC_ID, MLXSW_REG_MPSC_LEN);
+
+/* reg_mpsc_local_port
+ * Local port number
+ * Not supported for CPU port
+ * Access: Index
+ */
+MLXSW_ITEM32(reg, mpsc, local_port, 0x00, 16, 8);
+
+/* reg_mpsc_e
+ * Enable sampling on port local_port
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mpsc, e, 0x04, 30, 1);
+
+#define MLXSW_REG_MPSC_RATE_MAX 3500000000UL
+
+/* reg_mpsc_rate
+ * Sampling rate = 1 out of rate packets (with randomization around
+ * the point). Valid values are: 1 to MLXSW_REG_MPSC_RATE_MAX
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mpsc, rate, 0x08, 0, 32);
+
+static inline void mlxsw_reg_mpsc_pack(char *payload, u8 local_port, bool e,
+				       u32 rate)
+{
+	MLXSW_REG_ZERO(mpsc, payload);
+	mlxsw_reg_mpsc_local_port_set(payload, local_port);
+	mlxsw_reg_mpsc_e_set(payload, e);
+	mlxsw_reg_mpsc_rate_set(payload, rate);
+}
+
 /* SBPR - Shared Buffer Pools Register
  * -----------------------------------
  * The SBPR configures and retrieves the shared buffer pools and configuration.
@@ -5429,6 +5469,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
 	MLXSW_REG(mpat),
 	MLXSW_REG(mpar),
 	MLXSW_REG(mlcr),
+	MLXSW_REG(mpsc),
 	MLXSW_REG(sbpr),
 	MLXSW_REG(sbcm),
 	MLXSW_REG(sbpm),
-- 
2.7.4

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox