Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 01/11] devlink: Create helper to fill port type information
From: Ido Schimmel @ 2019-07-07  7:58 UTC (permalink / raw)
  To: netdev
  Cc: davem, jiri, mlxsw, dsahern, roopa, nikolay, andy, pablo,
	jakub.kicinski, pieter.jansenvanvuuren, andrew, f.fainelli,
	vivien.didelot, Ido Schimmel
In-Reply-To: <20190707075828.3315-1-idosch@idosch.org>

From: Ido Schimmel <idosch@mellanox.com>

The function that fills port attributes in a netlink message fills the
port type attributes together with other attributes such as the device
handle.

The port type attributes will also need to be filled for trapped packets
by a subsequent patch.

Prevent code duplication and create a helper that can be used from both
places.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
 net/core/devlink.c | 49 +++++++++++++++++++++++++++-------------------
 1 file changed, 29 insertions(+), 20 deletions(-)

diff --git a/net/core/devlink.c b/net/core/devlink.c
index 89c533778135..755a9a32015e 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -527,6 +527,33 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg,
 	return 0;
 }
 
+static int devlink_nl_port_type_fill(struct sk_buff *msg,
+				     const struct devlink_port *devlink_port)
+{
+	if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
+		return -EMSGSIZE;
+
+	if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
+		struct net_device *netdev = devlink_port->type_dev;
+
+		if (netdev &&
+		    (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
+				 netdev->ifindex) ||
+		     nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
+				    netdev->name)))
+			return -EMSGSIZE;
+	} else if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
+		struct ib_device *ibdev = devlink_port->type_dev;
+
+		if (ibdev &&
+		    nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
+				   ibdev->name))
+			return -EMSGSIZE;
+	}
+
+	return 0;
+}
+
 static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
 				struct devlink_port *devlink_port,
 				enum devlink_command cmd, u32 portid,
@@ -544,30 +571,12 @@ static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
 		goto nla_put_failure;
 
 	spin_lock(&devlink_port->type_lock);
-	if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
-		goto nla_put_failure_type_locked;
 	if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
 	    nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
 			devlink_port->desired_type))
 		goto nla_put_failure_type_locked;
-	if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
-		struct net_device *netdev = devlink_port->type_dev;
-
-		if (netdev &&
-		    (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
-				 netdev->ifindex) ||
-		     nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
-				    netdev->name)))
-			goto nla_put_failure_type_locked;
-	}
-	if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
-		struct ib_device *ibdev = devlink_port->type_dev;
-
-		if (ibdev &&
-		    nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
-				   ibdev->name))
-			goto nla_put_failure_type_locked;
-	}
+	if (devlink_nl_port_type_fill(msg, devlink_port))
+		goto nla_put_failure_type_locked;
 	spin_unlock(&devlink_port->type_lock);
 	if (devlink_nl_port_attrs_put(msg, devlink_port))
 		goto nla_put_failure;
-- 
2.20.1


^ permalink raw reply related

* [PATCH net-next 00/11] Add drop monitor for offloaded data paths
From: Ido Schimmel @ 2019-07-07  7:58 UTC (permalink / raw)
  To: netdev
  Cc: davem, jiri, mlxsw, dsahern, roopa, nikolay, andy, pablo,
	jakub.kicinski, pieter.jansenvanvuuren, andrew, f.fainelli,
	vivien.didelot, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

Users have several ways to debug the kernel and understand why a packet
was dropped. For example, using "drop monitor" and "perf". Both
utilities trace kfree_skb(), which is the function called when a packet
is freed as part of a failure. The information provided by these tools
is invaluable when trying to understand the cause of a packet loss.

In recent years, large portions of the kernel data path were offloaded
to capable devices. Today, it is possible to perform L2 and L3
forwarding in hardware, as well as tunneling (IP-in-IP and VXLAN).
Different TC classifiers and actions are also offloaded to capable
devices, at both ingress and egress.

However, when the data path is offloaded it is not possible to achieve
the same level of introspection as tools such "perf" and "drop monitor"
become irrelevant.

This patchset aims to solve this by allowing users to monitor packets
that the underlying device decided to drop along with relevant metadata
such as the drop reason and ingress port.

The above is achieved by exposing a fundamental capability of devices
capable of data path offloading - packet trapping. While the common use
case for packet trapping is the trapping of packets required for the
correct functioning of the control plane (e.g., STP, BGP packets),
packets can also be trapped due to other reasons such as exceptions
(e.g., TTL error) and drops (e.g., blackhole route).

Given this ability is not specific to a port, but rather to a device, it
is exposed using devlink. Each capable driver is expected to register
its supported packet traps with devlink and report trapped packets to
devlink as they income. devlink will perform accounting of received
packets and bytes and will potentially generate an event to user space
using a new generic netlink multicast group.

While this patchset is concerned with traps corresponding to dropped
packets, the interface itself is generic and can be used to expose traps
corresponding to control packets in the future. The API is vendor
neutral and similar to the API exposed by SAI which is implemented by
several vendors already.

The implementation in this patchset is on top of both mlxsw and
netdevsim so that people could experiment with the interface and provide
useful feedback.

Patches #1-#4 add the devlink-trap infrastructure.

Patches #5-#6 add an example implementation of netdevsim.

Patches #7-#11 add a real world implementation over mlxsw.

Tests for both the core infrastructure (over netdevsim) and mlxsw will
be sent separately as RFC as they are dependent on the acceptance of the
iproute2 changes.

Example
=======

Instantiate netdevsim
---------------------

# echo "10 1" > /sys/bus/netdevsim/new_device
# ip link set dev eth0 up

List supported traps
--------------------

# devlink trap show
netdevsim/netdevsim10:
  name source_mac_is_multicast type drop generic true report false action drop group l2_drops
  name vlan_tag_mismatch type drop generic true report false action drop group l2_drops
  name ingress_vlan_filter type drop generic true report false action drop group l2_drops
  name ingress_spanning_tree_filter type drop generic true report false action drop group l2_drops
  name port_list_is_empty type drop generic true report false action drop group l2_drops
  name port_loopback_filter type drop generic true report false action drop group l2_drops
  name fid_miss type exception generic false report false action trap group l2_drops
  name blackhole_route type drop generic true report false action drop group l3_drops
  name ttl_value_is_too_small type exception generic true report false action trap group l3_drops
  name tail_drop type drop generic true report false action drop group buffer_drops

Enable a trap
-------------

# devlink trap set netdevsim/netdevsim10 trap blackhole_route action trap report true

Query statistics
----------------

# devlink -s trap show netdevsim/netdevsim10 trap blackhole_route
netdevsim/netdevsim10:
  name blackhole_route type drop generic true report true action trap group l3_drops
    stats:
        rx:
          bytes 18744 packets 132

Monitor dropped packets
-----------------------

# devlink -v mon trap-report
[trap-report,report] netdevsim/netdevsim10: name blackhole_route type drop group l3_drops length 142 timestamp Sun Jun 30 20:26:12 2019 835605178 nsec
  input_port:
    netdevsim/netdevsim10/0: type eth netdev eth0

Future plans
============

* Provide more drop reasons as well as more metadata

v1:
* Rename trap names to make them more generic
* Change policer settings in mlxsw

Ido Schimmel (11):
  devlink: Create helper to fill port type information
  devlink: Add packet trap infrastructure
  devlink: Add generic packet traps and groups
  Documentation: Add devlink-trap documentation
  netdevsim: Add devlink-trap support
  Documentation: Add description of netdevsim traps
  mlxsw: core: Add API to set trap action
  mlxsw: reg: Add new trap action
  mlxsw: Add layer 2 discard trap IDs
  mlxsw: Add trap group for layer 2 discards
  mlxsw: spectrum: Add devlink-trap support

 .../networking/devlink-trap-netdevsim.rst     |   20 +
 Documentation/networking/devlink-trap.rst     |  190 +++
 Documentation/networking/index.rst            |    2 +
 drivers/net/ethernet/mellanox/mlxsw/Makefile  |    2 +-
 drivers/net/ethernet/mellanox/mlxsw/core.c    |   64 +
 drivers/net/ethernet/mellanox/mlxsw/core.h    |   12 +
 drivers/net/ethernet/mellanox/mlxsw/reg.h     |   10 +
 .../net/ethernet/mellanox/mlxsw/spectrum.c    |   17 +
 .../net/ethernet/mellanox/mlxsw/spectrum.h    |   13 +
 .../ethernet/mellanox/mlxsw/spectrum_trap.c   |  270 ++++
 drivers/net/ethernet/mellanox/mlxsw/trap.h    |    7 +
 drivers/net/netdevsim/dev.c                   |  273 +++-
 drivers/net/netdevsim/netdevsim.h             |    1 +
 include/net/devlink.h                         |  175 +++
 include/uapi/linux/devlink.h                  |   68 +
 net/core/devlink.c                            | 1312 ++++++++++++++++-
 16 files changed, 2409 insertions(+), 27 deletions(-)
 create mode 100644 Documentation/networking/devlink-trap-netdevsim.rst
 create mode 100644 Documentation/networking/devlink-trap.rst
 create mode 100644 drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c

-- 
2.20.1


^ permalink raw reply

* Re: [PATCH rdma-next 0/2] DEVX VHCA tunnel support
From: Leon Romanovsky @ 2019-07-07  7:51 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Doug Ledford, RDMA mailing list, Max Gurtovoy, Yishai Hadas,
	Saeed Mahameed, linux-netdev
In-Reply-To: <20190705174007.GA7787@ziepe.ca>

On Fri, Jul 05, 2019 at 02:40:07PM -0300, Jason Gunthorpe wrote:
> On Mon, Jul 01, 2019 at 09:14:00PM +0300, Leon Romanovsky wrote:
> > From: Leon Romanovsky <leonro@mellanox.com>
> >
> > Hi,
> >
> > Those two patches introduce VHCA tunnel mechanism to DEVX interface
> > needed for Bluefield SOC. See extensive commit messages for more
> > information.
> >
> > Thanks
> >
> > Max Gurtovoy (2):
> >   net/mlx5: Introduce VHCA tunnel device capability
> >   IB/mlx5: Implement VHCA tunnel mechanism in DEVX
> >
> >  drivers/infiniband/hw/mlx5/devx.c | 24 ++++++++++++++++++++----
> >  include/linux/mlx5/mlx5_ifc.h     | 10 ++++++++--
> >  2 files changed, 28 insertions(+), 6 deletions(-)
>
> This looks Ok can you apply the mlx5-next patch please

1dd7382b1bb6 net/mlx5: Introduce VHCA tunnel device capability

Thanks

>
> Thanks,
> Jason
>

^ permalink raw reply

* Re: [PATCH net-next v3 1/4] net/sched: Introduce action ct
From: Paul Blakey @ 2019-07-07  6:54 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Jiri Pirko, Roi Dayan, Yossi Kuperman, Oz Shlomo,
	Marcelo Ricardo Leitner, netdev@vger.kernel.org, David Miller,
	Aaron Conole, Zhike Wang, Rony Efraim, nst-kernel@redhat.com,
	John Hurley, Simon Horman, Justin Pettit
In-Reply-To: <20190704145521.29f67ba4@cakuba.netronome.com>

On 7/5/2019 12:55 AM, Jakub Kicinski wrote:

> On Thu,  4 Jul 2019 14:53:50 +0300, Paul Blakey wrote:
>> +static const struct nla_policy ct_policy[TCA_CT_MAX + 1] = {
>> +	[TCA_CT_ACTION] = { .type = NLA_U16 },
> Please use strict checking in all new policies.
>
> attr 0 must have .strict_start_type set.


Thanks, I'll fix it.


^ permalink raw reply

* Re: [PATCH net-next 00/12] mlx5 TLS TX HW offload support
From: Tariq Toukan @ 2019-07-07  6:44 UTC (permalink / raw)
  To: David Miller, Tariq Toukan
  Cc: netdev@vger.kernel.org, Eran Ben Elisha, Saeed Mahameed,
	jakub.kicinski@netronome.com, Moshe Shemesh
In-Reply-To: <20190705.162947.1737460613201841097.davem@davemloft.net>



On 7/6/2019 2:29 AM, David Miller wrote:
> From: Tariq Toukan <tariqt@mellanox.com>
> Date: Fri,  5 Jul 2019 18:30:10 +0300
> 
>> This series from Eran and me, adds TLS TX HW offload support to
>> the mlx5 driver.
> 
> Series applied, please deal with any further feedback you get from
> Jakub et al.
> 
> Thanks.
> 

I will followup with patches addressing Jakub's feedback.

Thanks,
Tariq

^ permalink raw reply

* Re: [PATCH 4/4] net: mvmdio: defer probe of orion-mdio if a clock is not ready
From: kbuild test robot @ 2019-07-07  5:21 UTC (permalink / raw)
  To: josua; +Cc: kbuild-all, netdev, Josua Mayer, David S. Miller
In-Reply-To: <20190706151900.14355-5-josua@solid-run.com>

[-- Attachment #1: Type: text/plain, Size: 6091 bytes --]

Hi,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.2-rc7 next-20190705]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/josua-solid-run-com/Fix-hang-of-Armada-8040-SoC-in-orion-mdio/20190707-111919
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 7.4.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.4.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/net/ethernet/marvell/mvmdio.c: In function 'orion_mdio_probe':
>> drivers/net/ethernet/marvell/mvmdio.c:324:30: warning: passing argument 1 of 'PTR_ERR' makes pointer from integer without a cast [-Wint-conversion]
      if (dev->clk[i] == PTR_ERR(-EPROBE_DEFER)) {
                                 ^
   In file included from include/linux/clk.h:12:0,
                    from drivers/net/ethernet/marvell/mvmdio.c:20:
   include/linux/err.h:29:33: note: expected 'const void *' but argument is of type 'int'
    static inline long __must_check PTR_ERR(__force const void *ptr)
                                    ^~~~~~~
>> drivers/net/ethernet/marvell/mvmdio.c:324:19: warning: comparison between pointer and integer
      if (dev->clk[i] == PTR_ERR(-EPROBE_DEFER)) {
                      ^~
   In file included from include/linux/node.h:18:0,
                    from include/linux/cpu.h:17,
                    from include/linux/of_device.h:5,
                    from drivers/net/ethernet/marvell/mvmdio.c:26:
   drivers/net/ethernet/marvell/mvmdio.c:334:12: error: passing argument 1 of '_dev_warn' from incompatible pointer type [-Werror=incompatible-pointer-types]
      dev_warn(dev, "unsupported number of clocks, limiting to the first "
               ^
   include/linux/device.h:1487:12: note: in definition of macro 'dev_warn'
     _dev_warn(dev, dev_fmt(fmt), ##__VA_ARGS__)
               ^~~
   include/linux/device.h:1425:6: note: expected 'const struct device *' but argument is of type 'struct orion_mdio_dev *'
    void _dev_warn(const struct device *dev, const char *fmt, ...);
         ^~~~~~~~~
   cc1: some warnings being treated as errors

vim +/PTR_ERR +324 drivers/net/ethernet/marvell/mvmdio.c

   275	
   276	static int orion_mdio_probe(struct platform_device *pdev)
   277	{
   278		enum orion_mdio_bus_type type;
   279		struct resource *r;
   280		struct mii_bus *bus;
   281		struct orion_mdio_dev *dev;
   282		int i, ret;
   283	
   284		type = (enum orion_mdio_bus_type)of_device_get_match_data(&pdev->dev);
   285	
   286		r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
   287		if (!r) {
   288			dev_err(&pdev->dev, "No SMI register address given\n");
   289			return -ENODEV;
   290		}
   291	
   292		bus = devm_mdiobus_alloc_size(&pdev->dev,
   293					      sizeof(struct orion_mdio_dev));
   294		if (!bus)
   295			return -ENOMEM;
   296	
   297		switch (type) {
   298		case BUS_TYPE_SMI:
   299			bus->read = orion_mdio_smi_read;
   300			bus->write = orion_mdio_smi_write;
   301			break;
   302		case BUS_TYPE_XSMI:
   303			bus->read = orion_mdio_xsmi_read;
   304			bus->write = orion_mdio_xsmi_write;
   305			break;
   306		}
   307	
   308		bus->name = "orion_mdio_bus";
   309		snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii",
   310			 dev_name(&pdev->dev));
   311		bus->parent = &pdev->dev;
   312	
   313		dev = bus->priv;
   314		dev->regs = devm_ioremap(&pdev->dev, r->start, resource_size(r));
   315		if (!dev->regs) {
   316			dev_err(&pdev->dev, "Unable to remap SMI register\n");
   317			return -ENODEV;
   318		}
   319	
   320		init_waitqueue_head(&dev->smi_busy_wait);
   321	
   322		for (i = 0; i < ARRAY_SIZE(dev->clk); i++) {
   323			dev->clk[i] = of_clk_get(pdev->dev.of_node, i);
 > 324			if (dev->clk[i] == PTR_ERR(-EPROBE_DEFER)) {
   325				ret = -EPROBE_DEFER;
   326				goto out_clk;
   327			}
   328			if (IS_ERR(dev->clk[i]))
   329				break;
   330			clk_prepare_enable(dev->clk[i]);
   331		}
   332	
   333		if (!IS_ERR(of_clk_get(pdev->dev.of_node, i)))
   334			dev_warn(dev, "unsupported number of clocks, limiting to the first "
   335				 __stringify(ARRAY_SIZE(dev->clk)) "\n");
   336	
   337		dev->err_interrupt = platform_get_irq(pdev, 0);
   338		if (dev->err_interrupt > 0 &&
   339		    resource_size(r) < MVMDIO_ERR_INT_MASK + 4) {
   340			dev_err(&pdev->dev,
   341				"disabling interrupt, resource size is too small\n");
   342			dev->err_interrupt = 0;
   343		}
   344		if (dev->err_interrupt > 0) {
   345			ret = devm_request_irq(&pdev->dev, dev->err_interrupt,
   346						orion_mdio_err_irq,
   347						IRQF_SHARED, pdev->name, dev);
   348			if (ret)
   349				goto out_mdio;
   350	
   351			writel(MVMDIO_ERR_INT_SMI_DONE,
   352				dev->regs + MVMDIO_ERR_INT_MASK);
   353	
   354		} else if (dev->err_interrupt == -EPROBE_DEFER) {
   355			ret = -EPROBE_DEFER;
   356			goto out_mdio;
   357		}
   358	
   359		ret = of_mdiobus_register(bus, pdev->dev.of_node);
   360		if (ret < 0) {
   361			dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret);
   362			goto out_mdio;
   363		}
   364	
   365		platform_set_drvdata(pdev, bus);
   366	
   367		return 0;
   368	
   369	out_mdio:
   370		if (dev->err_interrupt > 0)
   371			writel(0, dev->regs + MVMDIO_ERR_INT_MASK);
   372	
   373	out_clk:
   374		for (i = 0; i < ARRAY_SIZE(dev->clk); i++) {
   375			if (IS_ERR(dev->clk[i]))
   376				break;
   377			clk_disable_unprepare(dev->clk[i]);
   378			clk_put(dev->clk[i]);
   379		}
   380	
   381		return ret;
   382	}
   383	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 70930 bytes --]

^ permalink raw reply

* Re: [PATCH 3/4] net: mvmdio: print warning when orion-mdio has too many clocks
From: kbuild test robot @ 2019-07-07  5:04 UTC (permalink / raw)
  To: josua; +Cc: kbuild-all, netdev, Josua Mayer, David S. Miller
In-Reply-To: <20190706151900.14355-4-josua@solid-run.com>

[-- Attachment #1: Type: text/plain, Size: 5216 bytes --]

Hi,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v5.2-rc7 next-20190705]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/josua-solid-run-com/Fix-hang-of-Armada-8040-SoC-in-orion-mdio/20190707-111919
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 7.4.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.4.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from include/linux/node.h:18:0,
                    from include/linux/cpu.h:17,
                    from include/linux/of_device.h:5,
                    from drivers/net/ethernet/marvell/mvmdio.c:26:
   drivers/net/ethernet/marvell/mvmdio.c: In function 'orion_mdio_probe':
>> drivers/net/ethernet/marvell/mvmdio.c:330:12: error: passing argument 1 of '_dev_warn' from incompatible pointer type [-Werror=incompatible-pointer-types]
      dev_warn(dev, "unsupported number of clocks, limiting to the first "
               ^
   include/linux/device.h:1487:12: note: in definition of macro 'dev_warn'
     _dev_warn(dev, dev_fmt(fmt), ##__VA_ARGS__)
               ^~~
   include/linux/device.h:1425:6: note: expected 'const struct device *' but argument is of type 'struct orion_mdio_dev *'
    void _dev_warn(const struct device *dev, const char *fmt, ...);
         ^~~~~~~~~
   cc1: some warnings being treated as errors

vim +/_dev_warn +330 drivers/net/ethernet/marvell/mvmdio.c

   275	
   276	static int orion_mdio_probe(struct platform_device *pdev)
   277	{
   278		enum orion_mdio_bus_type type;
   279		struct resource *r;
   280		struct mii_bus *bus;
   281		struct orion_mdio_dev *dev;
   282		int i, ret;
   283	
   284		type = (enum orion_mdio_bus_type)of_device_get_match_data(&pdev->dev);
   285	
   286		r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
   287		if (!r) {
   288			dev_err(&pdev->dev, "No SMI register address given\n");
   289			return -ENODEV;
   290		}
   291	
   292		bus = devm_mdiobus_alloc_size(&pdev->dev,
   293					      sizeof(struct orion_mdio_dev));
   294		if (!bus)
   295			return -ENOMEM;
   296	
   297		switch (type) {
   298		case BUS_TYPE_SMI:
   299			bus->read = orion_mdio_smi_read;
   300			bus->write = orion_mdio_smi_write;
   301			break;
   302		case BUS_TYPE_XSMI:
   303			bus->read = orion_mdio_xsmi_read;
   304			bus->write = orion_mdio_xsmi_write;
   305			break;
   306		}
   307	
   308		bus->name = "orion_mdio_bus";
   309		snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii",
   310			 dev_name(&pdev->dev));
   311		bus->parent = &pdev->dev;
   312	
   313		dev = bus->priv;
   314		dev->regs = devm_ioremap(&pdev->dev, r->start, resource_size(r));
   315		if (!dev->regs) {
   316			dev_err(&pdev->dev, "Unable to remap SMI register\n");
   317			return -ENODEV;
   318		}
   319	
   320		init_waitqueue_head(&dev->smi_busy_wait);
   321	
   322		for (i = 0; i < ARRAY_SIZE(dev->clk); i++) {
   323			dev->clk[i] = of_clk_get(pdev->dev.of_node, i);
   324			if (IS_ERR(dev->clk[i]))
   325				break;
   326			clk_prepare_enable(dev->clk[i]);
   327		}
   328	
   329		if (!IS_ERR(of_clk_get(pdev->dev.of_node, i)))
 > 330			dev_warn(dev, "unsupported number of clocks, limiting to the first "
   331				 __stringify(ARRAY_SIZE(dev->clk)) "\n");
   332	
   333		dev->err_interrupt = platform_get_irq(pdev, 0);
   334		if (dev->err_interrupt > 0 &&
   335		    resource_size(r) < MVMDIO_ERR_INT_MASK + 4) {
   336			dev_err(&pdev->dev,
   337				"disabling interrupt, resource size is too small\n");
   338			dev->err_interrupt = 0;
   339		}
   340		if (dev->err_interrupt > 0) {
   341			ret = devm_request_irq(&pdev->dev, dev->err_interrupt,
   342						orion_mdio_err_irq,
   343						IRQF_SHARED, pdev->name, dev);
   344			if (ret)
   345				goto out_mdio;
   346	
   347			writel(MVMDIO_ERR_INT_SMI_DONE,
   348				dev->regs + MVMDIO_ERR_INT_MASK);
   349	
   350		} else if (dev->err_interrupt == -EPROBE_DEFER) {
   351			ret = -EPROBE_DEFER;
   352			goto out_mdio;
   353		}
   354	
   355		ret = of_mdiobus_register(bus, pdev->dev.of_node);
   356		if (ret < 0) {
   357			dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret);
   358			goto out_mdio;
   359		}
   360	
   361		platform_set_drvdata(pdev, bus);
   362	
   363		return 0;
   364	
   365	out_mdio:
   366		if (dev->err_interrupt > 0)
   367			writel(0, dev->regs + MVMDIO_ERR_INT_MASK);
   368	
   369		for (i = 0; i < ARRAY_SIZE(dev->clk); i++) {
   370			if (IS_ERR(dev->clk[i]))
   371				break;
   372			clk_disable_unprepare(dev->clk[i]);
   373			clk_put(dev->clk[i]);
   374		}
   375	
   376		return ret;
   377	}
   378	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 70930 bytes --]

^ permalink raw reply

* [PATCH] ipvs: Delete some unused space characters in Kconfig
From: xianfengting221 @ 2019-07-07  4:16 UTC (permalink / raw)
  To: wensong, horms, ja, pablo, kadlec, fw, davem
  Cc: netdev, lvs-devel, linux-kernel, Hu Haowen

From: Hu Haowen <xianfengting221@163.com>

The space characters at the end of lines are always unused and
not easy to find. This patch deleted some of them I have found
in Kconfig.

Signed-off-by: Hu Haowen <xianfengting221@163.com>
---

This is my first patch to the Linux kernel, so please forgive
me if anything went wrong.

 net/netfilter/ipvs/Kconfig | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/net/netfilter/ipvs/Kconfig b/net/netfilter/ipvs/Kconfig
index f6f1a0d..54afad5 100644
--- a/net/netfilter/ipvs/Kconfig
+++ b/net/netfilter/ipvs/Kconfig
@@ -120,7 +120,7 @@ config	IP_VS_RR
 
 	  If you want to compile it in kernel, say Y. To compile it as a
 	  module, choose M here. If unsure, say N.
- 
+
 config	IP_VS_WRR
 	tristate "weighted round-robin scheduling"
 	---help---
@@ -138,7 +138,7 @@ config	IP_VS_LC
         tristate "least-connection scheduling"
 	---help---
 	  The least-connection scheduling algorithm directs network
-	  connections to the server with the least number of active 
+	  connections to the server with the least number of active
 	  connections.
 
 	  If you want to compile it in kernel, say Y. To compile it as a
@@ -193,7 +193,7 @@ config  IP_VS_LBLCR
 	tristate "locality-based least-connection with replication scheduling"
 	---help---
 	  The locality-based least-connection with replication scheduling
-	  algorithm is also for destination IP load balancing. It is 
+	  algorithm is also for destination IP load balancing. It is
 	  usually used in cache cluster. It differs from the LBLC scheduling
 	  as follows: the load balancer maintains mappings from a target
 	  to a set of server nodes that can serve the target. Requests for
@@ -250,8 +250,8 @@ config	IP_VS_SED
 	tristate "shortest expected delay scheduling"
 	---help---
 	  The shortest expected delay scheduling algorithm assigns network
-	  connections to the server with the shortest expected delay. The 
-	  expected delay that the job will experience is (Ci + 1) / Ui if 
+	  connections to the server with the shortest expected delay. The
+	  expected delay that the job will experience is (Ci + 1) / Ui if
 	  sent to the ith server, in which Ci is the number of connections
 	  on the ith server and Ui is the fixed service rate (weight)
 	  of the ith server.
-- 
2.7.4



^ permalink raw reply related

* [PATCH net] tcp: Reset bytes_acked and bytes_received when disconnecting
From: Christoph Paasch @ 2019-07-06 23:13 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Eric Dumazet

If an app is playing tricks to reuse a socket via tcp_disconnect(),
bytes_acked/received needs to be reset to 0. Otherwise tcp_info will
report the sum of the current and the old connection..

Cc: Eric Dumazet <edumazet@google.com>
Fixes: 0df48c26d841 ("tcp: add tcpi_bytes_acked to tcp_info")
Fixes: bdd1f9edacb5 ("tcp: add tcpi_bytes_received to tcp_info")
Signed-off-by: Christoph Paasch <cpaasch@apple.com>
---
 net/ipv4/tcp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 7dc9ab84bb69..2eebd092c3c1 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2614,6 +2614,8 @@ int tcp_disconnect(struct sock *sk, int flags)
 	tcp_saved_syn_free(tp);
 	tp->compressed_ack = 0;
 	tp->bytes_sent = 0;
+	tp->bytes_acked = 0;
+	tp->bytes_received = 0;
 	tp->bytes_retrans = 0;
 	tp->duplicate_sack[0].start_seq = 0;
 	tp->duplicate_sack[0].end_seq = 0;
-- 
2.21.0


^ permalink raw reply related

* Re: INFO: rcu detected stall in ext4_write_checks
From: Paul E. McKenney @ 2019-07-07  1:16 UTC (permalink / raw)
  To: Theodore Ts'o, Dmitry Vyukov, syzbot, Andreas Dilger,
	David Miller, eladr, Ido Schimmel, Jiri Pirko, John Stultz,
	linux-ext4, LKML, netdev, syzkaller-bugs, Thomas Gleixner,
	Peter Zijlstra, Ingo Molnar
In-Reply-To: <20190706180311.GW26519@linux.ibm.com>

On Sat, Jul 06, 2019 at 11:03:11AM -0700, Paul E. McKenney wrote:
> On Sat, Jul 06, 2019 at 11:02:26AM -0400, Theodore Ts'o wrote:
> > On Fri, Jul 05, 2019 at 11:16:31PM -0700, Paul E. McKenney wrote:
> > > I suppose RCU could take the dueling-banjos approach and use increasingly
> > > aggressive scheduler policies itself, up to and including SCHED_DEADLINE,
> > > until it started getting decent forward progress.  However, that
> > > sounds like the something that just might have unintended consequences,
> > > particularly if other kernel subsystems were to also play similar
> > > games of dueling banjos.
> > 
> > So long as the RCU threads are well-behaved, using SCHED_DEADLINE
> > shouldn't have much of an impact on the system --- and the scheduling
> > parameters that you can specify on SCHED_DEADLINE allows you to
> > specify the worst-case impact on the system while also guaranteeing
> > that the SCHED_DEADLINE tasks will urn in the first place.  After all,
> > that's the whole point of SCHED_DEADLINE.
> > 
> > So I wonder if the right approach is during the the first userspace
> > system call to shced_setattr to enable a (any) real-time priority
> > scheduler (SCHED_DEADLINE, SCHED_FIFO or SCHED_RR) on a userspace
> > thread, before that's allowed to proceed, the RCU kernel threads are
> > promoted to be SCHED_DEADLINE with appropriately set deadline
> > parameters.  That way, a root user won't be able to shoot the system
> > in the foot, and since the vast majority of the time, there shouldn't
> > be any processes running with real-time priorities, we won't be
> > changing the behavior of a normal server system.
> 
> It might well be.  However, running the RCU kthreads at real-time
> priority does not come for free.  For example, it tends to crank up the
> context-switch rate.
> 
> Plus I have taken several runs at computing SCHED_DEADLINE parameters,
> but things like the rcuo callback-offload threads have computational
> requirements that are controlled not by RCU, and not just by the rest of
> the kernel, but also by userspace (keeping in mind the example of opening
> and closing a file in a tight loop, each pass of which queues a callback).
> I suspect that RCU is not the only kernel subsystem whose computational
> requirements are set not by the subsystem, but rather by external code.
> 
> OK, OK, I suppose I could just set insanely large SCHED_DEADLINE
> parameters, following syzkaller's example, and then trust my ability to
> keep the RCU code from abusing the resulting awesome power.  But wouldn't
> a much nicer approach be to put SCHED_DEADLINE between SCHED_RR/SCHED_FIFO
> priorities 98 and 99 or some such?  Then the same (admittedly somewhat
> scary) result could be obtained much more simply via SCHED_FIFO or
> SCHED_RR priority 99.
> 
> Some might argue that this is one of those situations where simplicity
> is not necessarily an advantage, but then again, you can find someone
> who will complain about almost anything.  ;-)
> 
> > (I suspect there might be some audio applications that might try to
> > set real-time priorities, but for desktop systems, it's probably more
> > important that the system not tie its self into knots since the
> > average desktop user isn't going to be well equipped to debug the
> > problem.)
> 
> Not only that, but if core counts continue to increase, and if reliance
> on cloud computing continues to grow, there are going to be an increasing
> variety of mixed workloads in increasingly less-controlled environments.
> 
> So, yes, it would be good to solve this problem in some reasonable way.
> 
> I don't see this as urgent just yet, but I am sure you all will let
> me know if I am mistaken on that point.
> 
> > > Alternatively, is it possible to provide stricter admission control?
> > 
> > I think that's an orthogonal issue; better admission control would be
> > nice, but it looks to me that it's going to be fundamentally an issue
> > of tweaking hueristics, and a fool-proof solution that will protect
> > against all malicious userspace applications (including syzkaller) is
> > going to require solving the halting problem.  So while it would be
> > nice to improve the admission control, I don't think that's a going to
> > be a general solution.
> 
> Agreed, and my earlier point about the need to trust the coding abilities
> of those writing ultimate-priority code is all too consistent with your
> point about needing to solve the halting problem.  Nevertheless,  I believe
> that we could make something that worked reasonably well in practice.
> 
> Here are a few components of a possible solution, in practice, but
> of course not in theory:
> 
> 1.	We set limits to SCHED_DEADLINE parameters, perhaps novel ones.
> 	For one example, insist on (say) 10 milliseconds of idle time
> 	every second on each CPU.  Yes, you can configure beyond that
> 	given sufficient permissions, but if you do so, you just voided
> 	your warranty.
> 
> 2.	Only allow SCHED_DEADLINE on nohz_full CPUs.  (Partial solution,
> 	given that such a CPU might be running in the kernel or have
> 	more than one runnable task.  Just for fun, I will suggest the
> 	option of disabling SCHED_DEADLINE during such times.)
> 
> 3.	RCU detects slowdowns, and does something TBD to increase its
> 	priority, but only while the slowdown persists.  This likely
> 	relies on scheduling-clock interrupts to detect the slowdowns,
> 	so there might be additional challenges on a fully nohz_full
> 	system.

4.	SCHED_DEADLINE treats the other three scheduling classes as each
	having a period, deadline, and a modest CPU consumption budget
	for the members of the class in aggregate.  But this has to have
	been discussed before.  How did that go?

> 5.	Your idea here.

							Thanx, Paul


^ permalink raw reply

* Re: [PATCH 1/2] proc: revalidate directories created with proc_net_mkdir()
From: Al Viro @ 2019-07-07  1:03 UTC (permalink / raw)
  To: Alexey Dobriyan; +Cc: davem, netdev, Per.Hallsmark
In-Reply-To: <20190706165201.GA10550@avx2>

On Sat, Jul 06, 2019 at 07:52:02PM +0300, Alexey Dobriyan wrote:
> +struct proc_dir_entry *_proc_mkdir(const char *name, umode_t mode,
> +				   struct proc_dir_entry **parent, void *data)

	Two underscores, please...

> +	parent->nlink++;
> +	pde = proc_register(parent, pde);
> +	if (!pde)
> +		parent->nlink++;

	Really?

^ permalink raw reply

* Re: [PATCH][next] 6lowpan: fix off-by-one comparison of index id with LOWPAN_IPHC_CTX_TABLE_SIZE
From: Colin Ian King @ 2019-07-06 23:23 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Alexander Aring, Jukka Rissanen, David S. Miller, linux-bluetooth,
	linux-wpan, netdev, kernel-janitors, linux-kernel
In-Reply-To: <B6A1CB42-C239-42CA-B14E-483A02B930EB@holtmann.org>

On 06/07/2019 11:51, Marcel Holtmann wrote:
> Hi Colin,
> 
>> The WARN_ON_ONCE check on id is off-by-one, it should be greater or equal
>> to LOWPAN_IPHC_CTX_TABLE_SIZE and not greater than. Fix this.
>>
>> Signed-off-by: Colin Ian King <colin.king@canonical.com>
>> ---
>> net/6lowpan/debugfs.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/net/6lowpan/debugfs.c b/net/6lowpan/debugfs.c
>> index 1c140af06d52..a510bed8165b 100644
>> --- a/net/6lowpan/debugfs.c
>> +++ b/net/6lowpan/debugfs.c
>> @@ -170,7 +170,7 @@ static void lowpan_dev_debugfs_ctx_init(struct net_device *dev,
>> 	struct dentry *root;
>> 	char buf[32];
>>
>> -	WARN_ON_ONCE(id > LOWPAN_IPHC_CTX_TABLE_SIZE);
>> +	WARN_ON_ONCE(id >= LOWPAN_IPHC_CTX_TABLE_SIZE);
> 
> this patch no longer applied cleanly to bluetooth-next. Can you send me an updated version.

I'm confused by this, I just applied it OK on bluetooth-next [1] on the
head 9ce67c3235be71e8cf922a9b3d0b7359ed3f4ce5, am I applying this to the
wrong repo/branch?

[1]
git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git


Colin

> 
> Regards
> 
> Marcel
> 


^ permalink raw reply

* More complex PBR rules
From: Markus Moeller @ 2019-07-06 23:06 UTC (permalink / raw)
  To: netdev

Hi Network developers

I am new to this group and wonder if you can advise how I could implement 
more complex PBR rules to achieve for example load balancing. The 
requirement I have is to route based on e.g. a hash like:

  hash(src-ip+dst-ip) mod N  routes via  gwX    0<X<=N   ( load balance over 
N gateways )

  This would help in situations where I can not use a MAC for identifying a 
gateway  ( e.g. in cloud environments) .

   Could someone point me to the kernel source code where PBR is performed ?

Thank you
Markus 



^ permalink raw reply

* Re: [PATCH net-next 0/4] bnxt_en: Add XDP_REDIRECT support.
From: David Miller @ 2019-07-06 22:26 UTC (permalink / raw)
  To: michael.chan; +Cc: gospo, netdev, hawk, ast
In-Reply-To: <1562398578-26020-1-git-send-email-michael.chan@broadcom.com>

From: Michael Chan <michael.chan@broadcom.com>
Date: Sat,  6 Jul 2019 03:36:14 -0400

> This patch series adds XDP_REDIRECT support by Andy Gospodarek.

I'll give Jesper et al. a chance to review this.

^ permalink raw reply

* Re: pull-request: wireless-drivers-next 2019-07-06
From: David Miller @ 2019-07-06 22:20 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <878stbabkb.fsf@kamboji.qca.qualcomm.com>

From: Kalle Valo <kvalo@codeaurora.org>
Date: Sat, 06 Jul 2019 10:04:20 +0300

> here's a pull request to net-next tree for v5.3, more info below. I will
> be offline from Sunday to Thursday, but Johannes should be able to help
> during that time.

Pulled, thanks Kalle.

^ permalink raw reply

* Re: [PATCH net-next] tipc: use rcu dereference functions properly
From: David Miller @ 2019-07-06 22:15 UTC (permalink / raw)
  To: lucien.xin; +Cc: netdev, jon.maloy, ying.xue, tipc-discussion
In-Reply-To: <CADvbK_eDnUMSaoT65hco2PF5-f1PO=CKBeMPz3sTRZvg5qKGVA@mail.gmail.com>

From: Xin Long <lucien.xin@gmail.com>
Date: Sat, 6 Jul 2019 14:48:48 +0800

> Hi, David, I saw this patch in "Changes Requested".

I just put it back to Under Review, thanks.

^ permalink raw reply

* [PATCH iproute2-next] ip: bond: add peer notification delay support
From: Vincent Bernat @ 2019-07-06 21:11 UTC (permalink / raw)
  To: netdev, Stephen Hemminger; +Cc: Vincent Bernat

Ability to tweak the delay between gratuitous ND/ARP packets has been
added in kernel commit 07a4ddec3ce9 ("bonding: add an option to
specify a delay between peer notifications"), through
IFLA_BOND_PEER_NOTIF_DELAY attribute. Add support to set and show this
value.

Example:

    $ ip -d link set bond0 type bond peer_notif_delay 1000
    $ ip -d link l dev bond0
    2: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue
    state UP mode DEFAULT group default qlen 1000
        link/ether 50:54:33:00:00:01 brd ff:ff:ff:ff:ff:ff
        bond mode active-backup active_slave eth0 miimon 100 updelay 0
    downdelay 0 peer_notif_delay 1000 use_carrier 1 arp_interval 0
    arp_validate none arp_all_targets any primary eth0
    primary_reselect always fail_over_mac active xmit_hash_policy
    layer2 resend_igmp 1 num_grat_arp 5 all_slaves_active 0 min_links
    0 lp_interval 1 packets_per_slave 1 lacp_rate slow ad_select
    stable tlb_dynamic_lb 1 addrgenmode eu

Signed-off-by: Vincent Bernat <vincent@bernat.ch>
---
 include/uapi/linux/if_link.h |  1 +
 ip/iplink_bond.c             | 14 +++++++++++++-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index b59554dd55cb..d36919fb4024 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -634,6 +634,7 @@ enum {
 	IFLA_BOND_AD_USER_PORT_KEY,
 	IFLA_BOND_AD_ACTOR_SYSTEM,
 	IFLA_BOND_TLB_DYNAMIC_LB,
+	IFLA_BOND_PEER_NOTIF_DELAY,
 	__IFLA_BOND_MAX,
 };
 
diff --git a/ip/iplink_bond.c b/ip/iplink_bond.c
index c60f0e8ad0a0..fb62c955631e 100644
--- a/ip/iplink_bond.c
+++ b/ip/iplink_bond.c
@@ -120,6 +120,7 @@ static void print_explain(FILE *f)
 		"Usage: ... bond [ mode BONDMODE ] [ active_slave SLAVE_DEV ]\n"
 		"                [ clear_active_slave ] [ miimon MIIMON ]\n"
 		"                [ updelay UPDELAY ] [ downdelay DOWNDELAY ]\n"
+		"                [ peer_notif_delay DELAY ]\n"
 		"                [ use_carrier USE_CARRIER ]\n"
 		"                [ arp_interval ARP_INTERVAL ]\n"
 		"                [ arp_validate ARP_VALIDATE ]\n"
@@ -165,7 +166,7 @@ static int bond_parse_opt(struct link_util *lu, int argc, char **argv,
 	__u8 xmit_hash_policy, num_peer_notif, all_slaves_active;
 	__u8 lacp_rate, ad_select, tlb_dynamic_lb;
 	__u16 ad_user_port_key, ad_actor_sys_prio;
-	__u32 miimon, updelay, downdelay, arp_interval, arp_validate;
+	__u32 miimon, updelay, downdelay, peer_notif_delay, arp_interval, arp_validate;
 	__u32 arp_all_targets, resend_igmp, min_links, lp_interval;
 	__u32 packets_per_slave;
 	unsigned int ifindex;
@@ -200,6 +201,11 @@ static int bond_parse_opt(struct link_util *lu, int argc, char **argv,
 			if (get_u32(&downdelay, *argv, 0))
 				invarg("invalid downdelay", *argv);
 			addattr32(n, 1024, IFLA_BOND_DOWNDELAY, downdelay);
+		} else if (matches(*argv, "peer_notif_delay") == 0) {
+			NEXT_ARG();
+			if (get_u32(&peer_notif_delay, *argv, 0))
+				invarg("invalid peer_notif_delay", *argv);
+			addattr32(n, 1024, IFLA_BOND_PEER_NOTIF_DELAY, peer_notif_delay);
 		} else if (matches(*argv, "use_carrier") == 0) {
 			NEXT_ARG();
 			if (get_u8(&use_carrier, *argv, 0))
@@ -410,6 +416,12 @@ static void bond_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
 			   "downdelay %u ",
 			   rta_getattr_u32(tb[IFLA_BOND_DOWNDELAY]));
 
+	if (tb[IFLA_BOND_PEER_NOTIF_DELAY])
+		print_uint(PRINT_ANY,
+			   "peer_notif_delay",
+			   "peer_notif_delay %u ",
+			   rta_getattr_u32(tb[IFLA_BOND_PEER_NOTIF_DELAY]));
+
 	if (tb[IFLA_BOND_USE_CARRIER])
 		print_uint(PRINT_ANY,
 			   "use_carrier",
-- 
2.20.1


^ permalink raw reply related

* [net-next] bonding: fix value exported by Netlink for peer_notif_delay
From: Vincent Bernat @ 2019-07-06 21:01 UTC (permalink / raw)
  To: Jay Vosburgh, Veaceslav Falico, Andy Gospodarek, David S. Miller,
	netdev
  Cc: Vincent Bernat

IFLA_BOND_PEER_NOTIF_DELAY was set to the value of downdelay instead
of peer_notif_delay. After this change, the correct value is exported.

Fixes: 07a4ddec3ce9 ("bonding: add an option to specify a delay between peer notifications")
Signed-off-by: Vincent Bernat <vincent@bernat.ch>
---
 drivers/net/bonding/bond_netlink.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
index a259860a7208..b43b51646b11 100644
--- a/drivers/net/bonding/bond_netlink.c
+++ b/drivers/net/bonding/bond_netlink.c
@@ -547,7 +547,7 @@ static int bond_fill_info(struct sk_buff *skb,
 		goto nla_put_failure;
 
 	if (nla_put_u32(skb, IFLA_BOND_PEER_NOTIF_DELAY,
-			bond->params.downdelay * bond->params.miimon))
+			bond->params.peer_notif_delay * bond->params.miimon))
 		goto nla_put_failure;
 
 	if (nla_put_u8(skb, IFLA_BOND_USE_CARRIER, bond->params.use_carrier))
-- 
2.20.1


^ permalink raw reply related

* [PATCH] net, skbuff: Handle devmap managed page when skb->head_frag is true
From: Ujjal Roy @ 2019-07-06 19:57 UTC (permalink / raw)
  To: Kernel, David S. Miller

When head_frag is true we have page in the SKB head. So, for devm
managed page we need to inform the device driver through callback.

Signed-off-by: Ujjal Roy <royujjal@gmail.com>
---
 net/core/skbuff.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index c8cd99c3603f..0d303e694efa 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -582,10 +582,16 @@ static void skb_free_head(struct sk_buff *skb)
{
unsigned char *head = skb->head;

- if (skb->head_frag)
+ if (skb->head_frag) {
+ struct page *page = virt_to_head_page(head);
+
+ if (put_devmap_managed_page(page))
+ return;
+
  skb_free_frag(head);
- else
+ } else {
  kfree(head);
+ }
 }

 static void skb_release_data(struct sk_buff *skb)
-- 
2.11.0

^ permalink raw reply related

* Re: [PATCH bpf-next v2 4/6] xdp: Add devmap_hash map type for looking up devices by hashed index
From: Y Song @ 2019-07-06 19:14 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen
  Cc: Daniel Borkmann, Alexei Starovoitov, netdev, David Miller,
	Jesper Dangaard Brouer, Jakub Kicinski, Björn Töpel
In-Reply-To: <156240283595.10171.8867063497268976931.stgit@alrua-x1>

On Sat, Jul 6, 2019 at 1:48 AM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>
> From: Toke Høiland-Jørgensen <toke@redhat.com>
>
> A common pattern when using xdp_redirect_map() is to create a device map
> where the lookup key is simply ifindex. Because device maps are arrays,
> this leaves holes in the map, and the map has to be sized to fit the
> largest ifindex, regardless of how many devices actually are actually
> needed in the map.
>
> This patch adds a second type of device map where the key is looked up
> using a hashmap, instead of being used as an array index. This allows maps
> to be densely packed, so they can be smaller.
>
> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
> ---
>  include/linux/bpf.h        |    7 ++
>  include/linux/bpf_types.h  |    1
>  include/trace/events/xdp.h |    3 -
>  kernel/bpf/devmap.c        |  192 ++++++++++++++++++++++++++++++++++++++++++++
>  kernel/bpf/verifier.c      |    2
>  net/core/filter.c          |    9 ++
>  6 files changed, 211 insertions(+), 3 deletions(-)
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index bfdb54dd2ad1..f9a506147c8a 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -713,6 +713,7 @@ struct xdp_buff;
>  struct sk_buff;
>
>  struct bpf_dtab_netdev *__dev_map_lookup_elem(struct bpf_map *map, u32 key);
> +struct bpf_dtab_netdev *__dev_map_hash_lookup_elem(struct bpf_map *map, u32 key);
>  void __dev_map_flush(struct bpf_map *map);
>  int dev_map_enqueue(struct bpf_dtab_netdev *dst, struct xdp_buff *xdp,
>                     struct net_device *dev_rx);
> @@ -799,6 +800,12 @@ static inline struct net_device  *__dev_map_lookup_elem(struct bpf_map *map,
>         return NULL;
>  }
>
> +static inline struct net_device  *__dev_map_hash_lookup_elem(struct bpf_map *map,
> +                                                            u32 key)
> +{
> +       return NULL;
> +}
> +
>  static inline void __dev_map_flush(struct bpf_map *map)
>  {
>  }
> diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
> index eec5aeeeaf92..36a9c2325176 100644
> --- a/include/linux/bpf_types.h
> +++ b/include/linux/bpf_types.h
> @@ -62,6 +62,7 @@ BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY_OF_MAPS, array_of_maps_map_ops)
>  BPF_MAP_TYPE(BPF_MAP_TYPE_HASH_OF_MAPS, htab_of_maps_map_ops)
>  #ifdef CONFIG_NET
>  BPF_MAP_TYPE(BPF_MAP_TYPE_DEVMAP, dev_map_ops)
> +BPF_MAP_TYPE(BPF_MAP_TYPE_DEVMAP_HASH, dev_map_hash_ops)
>  BPF_MAP_TYPE(BPF_MAP_TYPE_SK_STORAGE, sk_storage_map_ops)
>  #if defined(CONFIG_BPF_STREAM_PARSER)
>  BPF_MAP_TYPE(BPF_MAP_TYPE_SOCKMAP, sock_map_ops)
> diff --git a/include/trace/events/xdp.h b/include/trace/events/xdp.h
> index 68899fdc985b..8c8420230a10 100644
> --- a/include/trace/events/xdp.h
> +++ b/include/trace/events/xdp.h
> @@ -175,7 +175,8 @@ struct _bpf_dtab_netdev {
>  #endif /* __DEVMAP_OBJ_TYPE */
>
>  #define devmap_ifindex(fwd, map)                               \
> -       ((map->map_type == BPF_MAP_TYPE_DEVMAP) ?               \
> +       ((map->map_type == BPF_MAP_TYPE_DEVMAP ||               \
> +         map->map_type == BPF_MAP_TYPE_DEVMAP_HASH) ?          \
>           ((struct _bpf_dtab_netdev *)fwd)->dev->ifindex : 0)
>
>  #define _trace_xdp_redirect_map(dev, xdp, fwd, map, idx)               \
> diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
> index a2fe16362129..341af02f049d 100644
> --- a/kernel/bpf/devmap.c
> +++ b/kernel/bpf/devmap.c
> @@ -37,6 +37,12 @@
>   * notifier hook walks the map we know that new dev references can not be
>   * added by the user because core infrastructure ensures dev_get_by_index()
>   * calls will fail at this point.
> + *
> + * The devmap_hash type is a map type which interprets keys as ifindexes and
> + * indexes these using a hashmap. This allows maps that use ifindex as key to be
> + * densely packed instead of having holes in the lookup array for unused
> + * ifindexes. The setup and packet enqueue/send code is shared between the two
> + * types of devmap; only the lookup and insertion is different.
>   */
>  #include <linux/bpf.h>
>  #include <net/xdp.h>
> @@ -59,6 +65,7 @@ struct xdp_bulk_queue {
>
>  struct bpf_dtab_netdev {
>         struct net_device *dev; /* must be first member, due to tracepoint */
> +       struct hlist_node index_hlist;
>         struct bpf_dtab *dtab;
>         unsigned int idx; /* keep track of map index for tracepoint */
>         struct xdp_bulk_queue __percpu *bulkq;
> @@ -70,11 +77,29 @@ struct bpf_dtab {
>         struct bpf_dtab_netdev **netdev_map;
>         struct list_head __percpu *flush_list;
>         struct list_head list;
> +
> +       /* these are only used for DEVMAP_HASH type maps */
> +       unsigned int items;
> +       struct hlist_head *dev_index_head;
> +       spinlock_t index_lock;
>  };
>
>  static DEFINE_SPINLOCK(dev_map_lock);
>  static LIST_HEAD(dev_map_list);
>
> +static struct hlist_head *dev_map_create_hash(void)
> +{
> +       int i;
> +       struct hlist_head *hash;
> +
> +       hash = kmalloc_array(NETDEV_HASHENTRIES, sizeof(*hash), GFP_KERNEL);
> +       if (hash != NULL)
> +               for (i = 0; i < NETDEV_HASHENTRIES; i++)
> +                       INIT_HLIST_HEAD(&hash[i]);
> +
> +       return hash;
> +}
> +
>  static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr,
>                             bool check_memlock)
>  {
> @@ -98,6 +123,9 @@ static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr,
>         cost = (u64) dtab->map.max_entries * sizeof(struct bpf_dtab_netdev *);
>         cost += sizeof(struct list_head) * num_possible_cpus();
>
> +       if (attr->map_type == BPF_MAP_TYPE_DEVMAP_HASH)
> +               cost += sizeof(struct hlist_head) * NETDEV_HASHENTRIES;
> +
>         /* if map size is larger than memlock limit, reject it */
>         err = bpf_map_charge_init(&dtab->map.memory, cost);
>         if (err)
> @@ -116,8 +144,18 @@ static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr,
>         if (!dtab->netdev_map)
>                 goto free_percpu;
>
> +       if (attr->map_type == BPF_MAP_TYPE_DEVMAP_HASH) {
> +               dtab->dev_index_head = dev_map_create_hash();
> +               if (!dtab->dev_index_head)
> +                       goto free_map_area;
> +
> +               spin_lock_init(&dtab->index_lock);
> +       }
> +
>         return 0;
>
> +free_map_area:
> +       bpf_map_area_free(dtab->netdev_map);
>  free_percpu:
>         free_percpu(dtab->flush_list);
>  free_charge:
> @@ -199,6 +237,7 @@ static void dev_map_free(struct bpf_map *map)
>
>         free_percpu(dtab->flush_list);
>         bpf_map_area_free(dtab->netdev_map);
> +       kfree(dtab->dev_index_head);
>         kfree(dtab);
>  }
>
> @@ -219,6 +258,70 @@ static int dev_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
>         return 0;
>  }
>
> +static inline struct hlist_head *dev_map_index_hash(struct bpf_dtab *dtab,
> +                                                   int idx)
> +{
> +       return &dtab->dev_index_head[idx & (NETDEV_HASHENTRIES - 1)];
> +}
> +
> +struct bpf_dtab_netdev *__dev_map_hash_lookup_elem(struct bpf_map *map, u32 key)
> +{
> +       struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
> +       struct hlist_head *head = dev_map_index_hash(dtab, key);
> +       struct bpf_dtab_netdev *dev;
> +
> +       hlist_for_each_entry_rcu(dev, head, index_hlist)
> +               if (dev->idx == key)
> +                       return dev;
> +
> +       return NULL;
> +}
> +
> +static int dev_map_hash_get_next_key(struct bpf_map *map, void *key,
> +                                   void *next_key)
> +{
> +       struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
> +       u32 idx, *next = next_key;
> +       struct bpf_dtab_netdev *dev, *next_dev;
> +       struct hlist_head *head;
> +       int i = 0;
> +
> +       if (!key)
> +               goto find_first;
> +
> +       idx = *(u32 *)key;
> +
> +       dev = __dev_map_hash_lookup_elem(map, idx);
> +       if (!dev)
> +               goto find_first;
> +
> +       next_dev = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(&dev->index_hlist)),
> +                                   struct bpf_dtab_netdev, index_hlist);

Just want to get a better understanding. Why do you want
hlist_entry_safe instead of hlist_entry?
Also, maybe rcu_dereference instead of rcu_dereference_raw?
dev_map_hash_get_next_key() is called in syscall.c within rcu_read_lock region.

> +
> +       if (next_dev) {
> +               *next = next_dev->idx;
> +               return 0;
> +       }
> +
> +       i = idx & (NETDEV_HASHENTRIES - 1);
> +       i++;
> +
> + find_first:
> +       for (; i < NETDEV_HASHENTRIES; i++) {
> +               head = dev_map_index_hash(dtab, i);
> +
> +               next_dev = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(head)),
> +                                           struct bpf_dtab_netdev,
> +                                           index_hlist);

ditto. The same question as the above.

> +               if (next_dev) {
> +                       *next = next_dev->idx;
> +                       return 0;
> +               }
> +       }
> +
> +       return -ENOENT;
> +}
> +
>  static int bq_xmit_all(struct xdp_bulk_queue *bq, u32 flags,
>                        bool in_napi_ctx)
>  {
> @@ -374,6 +477,15 @@ static void *dev_map_lookup_elem(struct bpf_map *map, void *key)
>         return dev ? &dev->ifindex : NULL;
>  }
>
> +static void *dev_map_hash_lookup_elem(struct bpf_map *map, void *key)
> +{
> +       struct bpf_dtab_netdev *obj = __dev_map_hash_lookup_elem(map,
> +                                                               *(u32 *)key);
> +       struct net_device *dev = obj ? obj->dev : NULL;

When obj->dev could be NULL?

> +
> +       return dev ? &dev->ifindex : NULL;
> +}
> +
>  static void dev_map_flush_old(struct bpf_dtab_netdev *dev)
>  {
>         if (dev->dev->netdev_ops->ndo_xdp_xmit) {
> @@ -423,6 +535,27 @@ static int dev_map_delete_elem(struct bpf_map *map, void *key)
>         return 0;
>  }
>
> +static int dev_map_hash_delete_elem(struct bpf_map *map, void *key)
> +{
> +       struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
> +       struct bpf_dtab_netdev *old_dev;
> +       int k = *(u32 *)key;
> +
> +       old_dev = __dev_map_hash_lookup_elem(map, k);
> +       if (!old_dev)
> +               return 0;
> +
> +       spin_lock(&dtab->index_lock);
> +       if (!hlist_unhashed(&old_dev->index_hlist)) {
> +               dtab->items--;
> +               hlist_del_init_rcu(&old_dev->index_hlist);
> +       }
> +       spin_unlock(&dtab->index_lock);
> +
> +       call_rcu(&old_dev->rcu, __dev_map_entry_free);
> +       return 0;
> +}
> +
>  static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net,
>                                                     struct bpf_dtab *dtab,
>                                                     u32 ifindex,
> @@ -503,6 +636,55 @@ static int dev_map_update_elem(struct bpf_map *map, void *key, void *value,
>                                      map, key, value, map_flags);
>  }
>
> +static int __dev_map_hash_update_elem(struct net *net, struct bpf_map *map,
> +                                    void *key, void *value, u64 map_flags)
> +{
> +       struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
> +       struct bpf_dtab_netdev *dev, *old_dev;
> +       u32 ifindex = *(u32 *)value;
> +       u32 idx = *(u32 *)key;
> +
> +       if (unlikely(map_flags > BPF_EXIST || !ifindex))
> +               return -EINVAL;
> +
> +       old_dev = __dev_map_hash_lookup_elem(map, idx);
> +       if (old_dev && (map_flags & BPF_NOEXIST))
> +               return -EEXIST;
> +
> +       dev = __dev_map_alloc_node(net, dtab, ifindex, idx);
> +       if (IS_ERR(dev))
> +               return PTR_ERR(dev);
> +
> +       spin_lock(&dtab->index_lock);
> +
> +       if (old_dev) {
> +               hlist_del_rcu(&old_dev->index_hlist);
> +       } else {
> +               if (dtab->items >= dtab->map.max_entries) {
> +                       spin_unlock(&dtab->index_lock);
> +                       call_rcu(&dev->rcu, __dev_map_entry_free);
> +                       return -ENOSPC;
> +               }
> +               dtab->items++;
> +       }
> +
> +       hlist_add_head_rcu(&dev->index_hlist,
> +                          dev_map_index_hash(dtab, idx));
> +       spin_unlock(&dtab->index_lock);
> +
> +       if (old_dev)
> +               call_rcu(&old_dev->rcu, __dev_map_entry_free);
> +
> +       return 0;
> +}
> +
> +static int dev_map_hash_update_elem(struct bpf_map *map, void *key, void *value,
> +                                  u64 map_flags)
> +{
> +       return __dev_map_hash_update_elem(current->nsproxy->net_ns,
> +                                        map, key, value, map_flags);
> +}
> +
>  const struct bpf_map_ops dev_map_ops = {
>         .map_alloc = dev_map_alloc,
>         .map_free = dev_map_free,
> @@ -513,6 +695,16 @@ const struct bpf_map_ops dev_map_ops = {
>         .map_check_btf = map_check_no_btf,
>  };
>
> +const struct bpf_map_ops dev_map_hash_ops = {
> +       .map_alloc = dev_map_alloc,
> +       .map_free = dev_map_free,
> +       .map_get_next_key = dev_map_hash_get_next_key,
> +       .map_lookup_elem = dev_map_hash_lookup_elem,
> +       .map_update_elem = dev_map_hash_update_elem,
> +       .map_delete_elem = dev_map_hash_delete_elem,
> +       .map_check_btf = map_check_no_btf,
> +};
> +
>  static int dev_map_notification(struct notifier_block *notifier,
>                                 ulong event, void *ptr)
>  {
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index a2e763703c30..231b9e22827c 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -3460,6 +3460,7 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
>                         goto error;
>                 break;
>         case BPF_MAP_TYPE_DEVMAP:
> +       case BPF_MAP_TYPE_DEVMAP_HASH:
>                 if (func_id != BPF_FUNC_redirect_map &&
>                     func_id != BPF_FUNC_map_lookup_elem)
>                         goto error;
> @@ -3542,6 +3543,7 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
>                 break;
>         case BPF_FUNC_redirect_map:
>                 if (map->map_type != BPF_MAP_TYPE_DEVMAP &&
> +                   map->map_type != BPF_MAP_TYPE_DEVMAP_HASH &&
>                     map->map_type != BPF_MAP_TYPE_CPUMAP &&
>                     map->map_type != BPF_MAP_TYPE_XSKMAP)
>                         goto error;
> diff --git a/net/core/filter.c b/net/core/filter.c
> index 089aaea0ccc6..276961c4e0d4 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -3517,7 +3517,8 @@ static int __bpf_tx_xdp_map(struct net_device *dev_rx, void *fwd,
>         int err;
>
>         switch (map->map_type) {
> -       case BPF_MAP_TYPE_DEVMAP: {
> +       case BPF_MAP_TYPE_DEVMAP:
> +       case BPF_MAP_TYPE_DEVMAP_HASH: {
>                 struct bpf_dtab_netdev *dst = fwd;
>
>                 err = dev_map_enqueue(dst, xdp, dev_rx);
> @@ -3554,6 +3555,7 @@ void xdp_do_flush_map(void)
>         if (map) {
>                 switch (map->map_type) {
>                 case BPF_MAP_TYPE_DEVMAP:
> +               case BPF_MAP_TYPE_DEVMAP_HASH:
>                         __dev_map_flush(map);
>                         break;
>                 case BPF_MAP_TYPE_CPUMAP:
> @@ -3574,6 +3576,8 @@ static inline void *__xdp_map_lookup_elem(struct bpf_map *map, u32 index)
>         switch (map->map_type) {
>         case BPF_MAP_TYPE_DEVMAP:
>                 return __dev_map_lookup_elem(map, index);
> +       case BPF_MAP_TYPE_DEVMAP_HASH:
> +               return __dev_map_hash_lookup_elem(map, index);
>         case BPF_MAP_TYPE_CPUMAP:
>                 return __cpu_map_lookup_elem(map, index);
>         case BPF_MAP_TYPE_XSKMAP:
> @@ -3655,7 +3659,8 @@ static int xdp_do_generic_redirect_map(struct net_device *dev,
>         ri->tgt_value = NULL;
>         WRITE_ONCE(ri->map, NULL);
>
> -       if (map->map_type == BPF_MAP_TYPE_DEVMAP) {
> +       if (map->map_type == BPF_MAP_TYPE_DEVMAP ||
> +           map->map_type == BPF_MAP_TYPE_DEVMAP_HASH) {
>                 struct bpf_dtab_netdev *dst = fwd;
>
>                 err = dev_map_generic_redirect(dst, skb, xdp_prog);
>

^ permalink raw reply

* Re: [PATCH bpf-next v2 2/6] xdp: Refactor devmap allocation code for reuse
From: Y Song @ 2019-07-06 19:02 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen
  Cc: Daniel Borkmann, Alexei Starovoitov, netdev, David Miller,
	Jesper Dangaard Brouer, Jakub Kicinski, Björn Töpel
In-Reply-To: <156240283578.10171.1470306115442701328.stgit@alrua-x1>

On Sat, Jul 6, 2019 at 1:47 AM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>
> From: Toke Høiland-Jørgensen <toke@redhat.com>
>
> The subsequent patch to add a new devmap sub-type can re-use much of the
> initialisation and allocation code, so refactor it into separate functions.
>
> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>

Acked-by: Yonghong Song <yhs@fb.com>

> ---
>  kernel/bpf/devmap.c |  137 +++++++++++++++++++++++++++++++--------------------
>  1 file changed, 84 insertions(+), 53 deletions(-)
>
> diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
> index d83cf8ccc872..a2fe16362129 100644
> --- a/kernel/bpf/devmap.c
> +++ b/kernel/bpf/devmap.c
> @@ -60,7 +60,7 @@ struct xdp_bulk_queue {
>  struct bpf_dtab_netdev {
>         struct net_device *dev; /* must be first member, due to tracepoint */
>         struct bpf_dtab *dtab;
> -       unsigned int bit;
> +       unsigned int idx; /* keep track of map index for tracepoint */
>         struct xdp_bulk_queue __percpu *bulkq;
>         struct rcu_head rcu;
>  };
> @@ -75,28 +75,22 @@ struct bpf_dtab {
>  static DEFINE_SPINLOCK(dev_map_lock);
>  static LIST_HEAD(dev_map_list);
>
> -static struct bpf_map *dev_map_alloc(union bpf_attr *attr)
> +static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr,
> +                           bool check_memlock)
>  {
> -       struct bpf_dtab *dtab;
>         int err, cpu;
>         u64 cost;
>
> -       if (!capable(CAP_NET_ADMIN))
> -               return ERR_PTR(-EPERM);
> -
>         /* check sanity of attributes */
>         if (attr->max_entries == 0 || attr->key_size != 4 ||
>             attr->value_size != 4 || attr->map_flags & ~DEV_CREATE_FLAG_MASK)
> -               return ERR_PTR(-EINVAL);
> +               return -EINVAL;
>
>         /* Lookup returns a pointer straight to dev->ifindex, so make sure the
>          * verifier prevents writes from the BPF side
>          */
>         attr->map_flags |= BPF_F_RDONLY_PROG;
>
> -       dtab = kzalloc(sizeof(*dtab), GFP_USER);
> -       if (!dtab)
> -               return ERR_PTR(-ENOMEM);
>
>         bpf_map_init_from_attr(&dtab->map, attr);
>
> @@ -107,9 +101,7 @@ static struct bpf_map *dev_map_alloc(union bpf_attr *attr)
>         /* if map size is larger than memlock limit, reject it */
>         err = bpf_map_charge_init(&dtab->map.memory, cost);
>         if (err)
> -               goto free_dtab;
> -
> -       err = -ENOMEM;
> +               return -EINVAL;
>
>         dtab->flush_list = alloc_percpu(struct list_head);
>         if (!dtab->flush_list)
> @@ -124,19 +116,38 @@ static struct bpf_map *dev_map_alloc(union bpf_attr *attr)
>         if (!dtab->netdev_map)
>                 goto free_percpu;
>
> -       spin_lock(&dev_map_lock);
> -       list_add_tail_rcu(&dtab->list, &dev_map_list);
> -       spin_unlock(&dev_map_lock);
> -
> -       return &dtab->map;
> +       return 0;
>
>  free_percpu:
>         free_percpu(dtab->flush_list);
>  free_charge:
>         bpf_map_charge_finish(&dtab->map.memory);
> -free_dtab:
> -       kfree(dtab);
> -       return ERR_PTR(err);
> +       return -ENOMEM;
> +}
> +
[...]

^ permalink raw reply

* Re: [PATCH bpf-next v2 1/6] include/bpf.h: Remove map_insert_ctx() stubs
From: Y Song @ 2019-07-06 18:59 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen
  Cc: Daniel Borkmann, Alexei Starovoitov, netdev, David Miller,
	Jesper Dangaard Brouer, Jakub Kicinski, Björn Töpel
In-Reply-To: <156240283571.10171.11997723639222073086.stgit@alrua-x1>

On Sat, Jul 6, 2019 at 1:47 AM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>
> From: Toke Høiland-Jørgensen <toke@redhat.com>
>
> When we changed the device and CPU maps to use linked lists instead of
> bitmaps, we also removed the need for the map_insert_ctx() helpers to keep
> track of the bitmaps inside each map. However, it seems I forgot to remove
> the function definitions stubs, so remove those here.
>
> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>

Acked-by: Yonghong Song <yhs@fb.com>

^ permalink raw reply

* Re: [PATCH bpf-next v2 0/6] xdp: Add devmap_hash map type
From: Y Song @ 2019-07-06 18:58 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen
  Cc: Daniel Borkmann, Alexei Starovoitov, netdev, David Miller,
	Jesper Dangaard Brouer, Jakub Kicinski, Björn Töpel
In-Reply-To: <156240283550.10171.1727292671613975908.stgit@alrua-x1>

On Sat, Jul 6, 2019 at 1:47 AM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>
> This series adds a new map type, devmap_hash, that works like the existing
> devmap type, but using a hash-based indexing scheme. This is useful for the use
> case where a devmap is indexed by ifindex (for instance for use with the routing
> table lookup helper). For this use case, the regular devmap needs to be sized
> after the maximum ifindex number, not the number of devices in it. A hash-based
> indexing scheme makes it possible to size the map after the number of devices it
> should contain instead.
>
> This was previously part of my patch series that also turned the regular
> bpf_redirect() helper into a map-based one; for this series I just pulled out
> the patches that introduced the new map type.
>
> Changelog:
>
> v2:
>
> - Split commit adding the new map type so uapi and tools changes are separate.
>
> Changes to these patches since the previous series:
>
> - Rebase on top of the other devmap changes (makes this one simpler!)
> - Don't enforce key==val, but allow arbitrary indexes.
> - Rename the type to devmap_hash to reflect the fact that it's just a hashmap now.
>
> ---
>
> Toke Høiland-Jørgensen (6):
>       include/bpf.h: Remove map_insert_ctx() stubs
>       xdp: Refactor devmap allocation code for reuse
>       uapi/bpf: Add new devmap_hash type
>       xdp: Add devmap_hash map type for looking up devices by hashed index
>       tools/libbpf_probes: Add new devmap_hash type
>       tools: Add definitions for devmap_hash map type

Thanks for re-organize the patch. I guess this can be tweaked a little more
to better suit for syncing between kernel and libbpf repo.

Let me provide a little bit background here. The below is
a sync done by Andrii from kernel/tools to libbpf repo.

=============
commit 39de6711795f6d1583ae96ed8d13892bc4475ac1
Author: Andrii Nakryiko <andriin@fb.com>
Date:   Tue Jun 11 09:56:11 2019 -0700

    sync: latest libbpf changes from kernel

    Syncing latest libbpf commits from kernel repository.
    Baseline commit:   e672db03ab0e43e41ab6f8b2156a10d6e40f243d
    Checkpoint commit: 5e2ac390fbd08b2a462db66cef2663e4db0d5191

    Andrii Nakryiko (9):
      libbpf: fix detection of corrupted BPF instructions section
      libbpf: preserve errno before calling into user callback
      libbpf: simplify endianness check
      libbpf: check map name retrieved from ELF
      libbpf: fix error code returned on corrupted ELF
      libbpf: use negative fd to specify missing BTF
      libbpf: simplify two pieces of logic
      libbpf: typo and formatting fixes
      libbpf: reduce unnecessary line wrapping

    Hechao Li (1):
      bpf: add a new API libbpf_num_possible_cpus()

    Jonathan Lemon (2):
      bpf/tools: sync bpf.h
      libbpf: remove qidconf and better support external bpf programs.

    Quentin Monnet (1):
      libbpf: prevent overwriting of log_level in bpf_object__load_progs()

     include/uapi/linux/bpf.h |   4 +
     src/libbpf.c             | 207 ++++++++++++++++++++++-----------------
     src/libbpf.h             |  16 +++
     src/libbpf.map           |   1 +
     src/xsk.c                | 103 ++++++-------------
     5 files changed, 167 insertions(+), 164 deletions(-)
==========

You can see the commits at tools/lib/bpf and
commits at tools/include/uapi/{linux/[bpf.h, btf.h], ...}
are sync'ed to libbpf repo.

So we would like kernel commits to be aligned that way for better
automatic syncing.

Therefore, your current patch set could be changed from
   >       include/bpf.h: Remove map_insert_ctx() stubs
   >       xdp: Refactor devmap allocation code for reuse
   >       uapi/bpf: Add new devmap_hash type
   >       xdp: Add devmap_hash map type for looking up devices by hashed index
   >       tools/libbpf_probes: Add new devmap_hash type
   >       tools: Add definitions for devmap_hash map type
to
      1. include/bpf.h: Remove map_insert_ctx() stubs
      2. xdp: Refactor devmap allocation code for reuse
      3. kernel non-tools changes (the above patch #3 and #4)
      4. tools/include/uapi change (part of the above patch #6)
      5. tools/libbpf_probes change
      6. other tools/ change (the above patch #6 - new patch #4).

Thanks!

Yonghong

>
>
>  include/linux/bpf.h                     |   11 -
>  include/linux/bpf_types.h               |    1
>  include/trace/events/xdp.h              |    3
>  include/uapi/linux/bpf.h                |    1
>  kernel/bpf/devmap.c                     |  325 ++++++++++++++++++++++++++-----
>  kernel/bpf/verifier.c                   |    2
>  net/core/filter.c                       |    9 +
>  tools/bpf/bpftool/map.c                 |    1
>  tools/include/uapi/linux/bpf.h          |    1
>  tools/lib/bpf/libbpf_probes.c           |    1
>  tools/testing/selftests/bpf/test_maps.c |   16 ++
>  11 files changed, 310 insertions(+), 61 deletions(-)
>

^ permalink raw reply

* RE: [PATCH net-next v3 1/3] devlink: Introduce PCI PF port flavour and port attribute
From: Parav Pandit @ 2019-07-06 18:38 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev@vger.kernel.org, Jiri Pirko, Saeed Mahameed,
	jakub.kicinski@netronome.com
In-Reply-To: <20190706062611.GA2264@nanopsycho>



> -----Original Message-----
> From: Jiri Pirko <jiri@resnulli.us>
> Sent: Saturday, July 6, 2019 11:56 AM
> To: Parav Pandit <parav@mellanox.com>
> Cc: netdev@vger.kernel.org; Jiri Pirko <jiri@mellanox.com>; Saeed Mahameed
> <saeedm@mellanox.com>; jakub.kicinski@netronome.com
> Subject: Re: [PATCH net-next v3 1/3] devlink: Introduce PCI PF port flavour and
> port attribute
> 
> Sat, Jul 06, 2019 at 08:16:24AM CEST, parav@mellanox.com wrote:
> >In an eswitch, PCI PF may have port which is normally represented using
> >a representor netdevice.
> >To have better visibility of eswitch port, its association with PF and
> >a representor netdevice, introduce a PCI PF port flavour and port
> >attriute.
> >
> >When devlink port flavour is PCI PF, fill up PCI PF attributes of the
> >port.
> >
> >Extend port name creation using PCI PF number on best effort basis.
> >So that vendor drivers can skip defining their own scheme.
> >
> >$ devlink port show
> >pci/0000:05:00.0/0: type eth netdev eth0 flavour pcipf pfnum 0
> >
> >Signed-off-by: Parav Pandit <parav@mellanox.com>
> >
> >---
> >Changelog:
> >v2->v3:
> > - Address comments from Jakub.
> > - Made port_number and split_port_number applicable only to
> >   physical port flavours by having in union.
> >v1->v2:
> > - Limited port_num attribute to physical ports
> > - Updated PCI PF attribute set API to not have port_number
> >---
> > include/net/devlink.h        | 21 +++++++-
> > include/uapi/linux/devlink.h |  5 ++
> > net/core/devlink.c           | 97 ++++++++++++++++++++++++++++--------
> > 3 files changed, 100 insertions(+), 23 deletions(-)
> >
> >diff --git a/include/net/devlink.h b/include/net/devlink.h index
> >6625ea068d5e..1455f60e4069 100644
> >--- a/include/net/devlink.h
> >+++ b/include/net/devlink.h
> >@@ -38,13 +38,27 @@ struct devlink {
> > 	char priv[0] __aligned(NETDEV_ALIGN);  };
> >
> >+struct devlink_port_phys_attrs {
> >+	u32 port_number; /* same value as "split group".
> 
> "Same" with capital letter.
> 
Done in v4.

> >+			  * A physical port which is visible to the user
> >+			  * for a given port flavour.
> >+			  */
> >+	u32 split_subport_number;
> >+};
> >+
> >+struct devlink_port_pci_pf_attrs {
> >+	u16 pf;	/* Associated PCI PF for this port. */
> >+};
> >+
> > struct devlink_port_attrs {
> > 	u8 set:1,
> > 	   split:1,
> > 	   switch_port:1;
> > 	enum devlink_port_flavour flavour;
> >-	u32 port_number; /* same value as "split group" */
> >-	u32 split_subport_number;
> >+	union {
> >+		struct devlink_port_phys_attrs phys_port;
> >+		struct devlink_port_pci_pf_attrs pci_pf;
> 
> Be consistent in naming: "phys", "pci_pf".
> 
Done in v4 as "physical".

> 
> >+	};
> > 	struct netdev_phys_item_id switch_id; };
> >
> >@@ -590,6 +604,9 @@ void devlink_port_attrs_set(struct devlink_port
> *devlink_port,
> > 			    u32 split_subport_number,
> > 			    const unsigned char *switch_id,
> > 			    unsigned char switch_id_len);
> >+void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port,
> >+				   const unsigned char *switch_id,
> >+				   unsigned char switch_id_len, u16 pf);
> > int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
> > 			u32 size, u16 ingress_pools_count,
> > 			u16 egress_pools_count, u16 ingress_tc_count, diff --
> git
> >a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index
> >5287b42c181f..f7323884c3fe 100644
> >--- a/include/uapi/linux/devlink.h
> >+++ b/include/uapi/linux/devlink.h
> >@@ -169,6 +169,10 @@ enum devlink_port_flavour {
> > 	DEVLINK_PORT_FLAVOUR_DSA, /* Distributed switch architecture
> > 				   * interconnect port.
> > 				   */
> >+	DEVLINK_PORT_FLAVOUR_PCI_PF, /* Represents eswitch port for
> >+				      * the PCI PF. It is an internal
> >+				      * port that faces the PCI PF.
> >+				      */
> > };
> >
> > enum devlink_param_cmode {
> >@@ -337,6 +341,7 @@ enum devlink_attr {
> > 	DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,	/* u64 */
> > 	DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,	/* u64 */
> >
> >+	DEVLINK_ATTR_PORT_PCI_PF_NUMBER,	/* u16 */
> > 	/* add new attributes above here, update the policy in devlink.c */
> >
> > 	__DEVLINK_ATTR_MAX,
> >diff --git a/net/core/devlink.c b/net/core/devlink.c index
> >89c533778135..9aa36104b471 100644
> >--- a/net/core/devlink.c
> >+++ b/net/core/devlink.c
> >@@ -506,6 +506,14 @@ static void devlink_notify(struct devlink *devlink,
> enum devlink_command cmd)
> > 				msg, 0, DEVLINK_MCGRP_CONFIG,
> GFP_KERNEL);  }
> >
> >+static bool
> >+is_devlink_phy_port_num_supported(const struct devlink_port *dl_port)
> >+{
> >+	return (dl_port->attrs.flavour == DEVLINK_PORT_FLAVOUR_PHYSICAL
> ||
> >+		dl_port->attrs.flavour == DEVLINK_PORT_FLAVOUR_CPU ||
> >+		dl_port->attrs.flavour == DEVLINK_PORT_FLAVOUR_DSA); }
> >+
> > static int devlink_nl_port_attrs_put(struct sk_buff *msg,
> > 				     struct devlink_port *devlink_port)  { @@ -
> 515,14 +523,23 @@
> >static int devlink_nl_port_attrs_put(struct sk_buff *msg,
> > 		return 0;
> > 	if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
> > 		return -EMSGSIZE;
> >-	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER, attrs-
> >port_number))
> >+	if (devlink_port->attrs.flavour == DEVLINK_PORT_FLAVOUR_PCI_PF) {
> >+		if (nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
> >+				attrs->pci_pf.pf))
> >+			return -EMSGSIZE;
> >+	}
> >+	if (!is_devlink_phy_port_num_supported(devlink_port))
> 
> Please do the check here. No need for helper (the name with "is" and
> "supported" is weird anyway.
> 
Done in v4.
> 
> >+		return 0;
> >+	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
> >+			attrs->phys_port.port_number))
> > 		return -EMSGSIZE;
> > 	if (!attrs->split)
> > 		return 0;
> >-	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP, attrs-
> >port_number))
> >+	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
> >+			attrs->phys_port.port_number))
> 
> Better to split this into 2 patches. One pushing phys things into separate struct,
> the second the rest.
> 
Done in v4.
> 
> > 		return -EMSGSIZE;
> > 	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
> >-			attrs->split_subport_number))
> >+			attrs->phys_port.split_subport_number))
> > 		return -EMSGSIZE;
> > 	return 0;
> > }
> >@@ -5738,6 +5755,30 @@ void devlink_port_type_clear(struct devlink_port
> >*devlink_port)  }  EXPORT_SYMBOL_GPL(devlink_port_type_clear);
> >
> >+static void __devlink_port_attrs_set(struct devlink_port *devlink_port,
> >+				     enum devlink_port_flavour flavour,
> >+				     u32 port_number,
> >+				     const unsigned char *switch_id,
> >+				     unsigned char switch_id_len)
> >+{
> >+	struct devlink_port_attrs *attrs = &devlink_port->attrs;
> >+
> >+	if (WARN_ON(devlink_port->registered))
> >+		return;
> >+	attrs->set = true;
> >+	attrs->flavour = flavour;
> >+	attrs->phys_port.port_number = port_number;
> >+	if (switch_id) {
> >+		attrs->switch_port = true;
> >+		if (WARN_ON(switch_id_len > MAX_PHYS_ITEM_ID_LEN))
> >+			switch_id_len = MAX_PHYS_ITEM_ID_LEN;
> >+		memcpy(attrs->switch_id.id, switch_id, switch_id_len);
> >+		attrs->switch_id.id_len = switch_id_len;
> >+	} else {
> >+		attrs->switch_port = false;
> >+	}
> >+}
> >+
> > /**
> >  *	devlink_port_attrs_set - Set port attributes
> >  *
> >@@ -5761,25 +5802,34 @@ void devlink_port_attrs_set(struct devlink_port
> >*devlink_port,  {
> > 	struct devlink_port_attrs *attrs = &devlink_port->attrs;
> >
> >-	if (WARN_ON(devlink_port->registered))
> >-		return;
> >-	attrs->set = true;
> >-	attrs->flavour = flavour;
> >-	attrs->port_number = port_number;
> >+	__devlink_port_attrs_set(devlink_port, flavour, port_number,
> >+				 switch_id, switch_id_len);
> > 	attrs->split = split;
> >-	attrs->split_subport_number = split_subport_number;
> >-	if (switch_id) {
> >-		attrs->switch_port = true;
> >-		if (WARN_ON(switch_id_len > MAX_PHYS_ITEM_ID_LEN))
> >-			switch_id_len = MAX_PHYS_ITEM_ID_LEN;
> >-		memcpy(attrs->switch_id.id, switch_id, switch_id_len);
> >-		attrs->switch_id.id_len = switch_id_len;
> >-	} else {
> >-		attrs->switch_port = false;
> >-	}
> >+	attrs->phys_port.split_subport_number = split_subport_number;
> > }
> > EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
> >
> >+/**
> >+ *	devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
> >+ *
> >+ *	@devlink_port: devlink port
> >+ *	@pf: associated PF for the devlink port instance
> >+ *	@switch_id: if the port is part of switch, this is buffer with ID,
> >+ *	            otwerwise this is NULL
> >+ *	@switch_id_len: length of the switch_id buffer
> >+ */
> >+void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port,
> >+				   const unsigned char *switch_id,
> >+				   unsigned char switch_id_len, u16 pf) {
> >+	struct devlink_port_attrs *attrs = &devlink_port->attrs;
> >+
> >+	__devlink_port_attrs_set(devlink_port,
> DEVLINK_PORT_FLAVOUR_PCI_PF,
> >+				 0, switch_id, switch_id_len);
> 
> Please have this done differently. __devlink_port_attrs_set() sets
> attrs->phys_port.port_number which does not make sense there.
> 
Changed in v4.

> 
> >+	attrs->pci_pf.pf = pf;
> >+}
> >+EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
> >+
> > static int __devlink_port_phys_port_name_get(struct devlink_port
> *devlink_port,
> > 					     char *name, size_t len)
> > {
> >@@ -5792,10 +5842,12 @@ static int
> __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
> > 	switch (attrs->flavour) {
> > 	case DEVLINK_PORT_FLAVOUR_PHYSICAL:
> > 		if (!attrs->split)
> >-			n = snprintf(name, len, "p%u", attrs->port_number);
> >+			n = snprintf(name, len, "p%u",
> >+				     attrs->phys_port.port_number);
> > 		else
> >-			n = snprintf(name, len, "p%us%u", attrs->port_number,
> >-				     attrs->split_subport_number);
> >+			n = snprintf(name, len, "p%us%u",
> >+				     attrs->phys_port.port_number,
> >+				     attrs->phys_port.split_subport_number);
> > 		break;
> > 	case DEVLINK_PORT_FLAVOUR_CPU:
> > 	case DEVLINK_PORT_FLAVOUR_DSA:
> >@@ -5804,6 +5856,9 @@ static int
> __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
> > 		 */
> > 		WARN_ON(1);
> > 		return -EINVAL;
> >+	case DEVLINK_PORT_FLAVOUR_PCI_PF:
> >+		n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
> >+		break;
> > 	}
> >
> > 	if (n >= len)
> >--
> >2.19.2
> >

^ permalink raw reply

* [PATCH net-next v4 4/4] net/mlx5e: Register devlink ports for physical link, PCI PF, VFs
From: Parav Pandit @ 2019-07-06 18:23 UTC (permalink / raw)
  To: netdev; +Cc: jiri, saeedm, jakub.kicinski, Parav Pandit
In-Reply-To: <20190706182350.11929-1-parav@mellanox.com>

Register devlink port of physical port, PCI PF and PCI VF flavour
for each PF, VF when a given devlink instance is in switchdev mode.

Implement ndo_get_devlink_port callback API to make use of registered
devlink ports.
This eliminates ndo_get_phys_port_name() and ndo_get_port_parent_id()
callbacks. Hence, remove them.

An example output with 2 VFs, without a PF and single uplink port is
below.

$devlink port show
pci/0000:06:00.0/65535: type eth netdev ens2f0 flavour physical
pci/0000:05:00.0/1: type eth netdev eth1 flavour pcivf pfnum 0 vfnum 0
pci/0000:05:00.0/2: type eth netdev eth2 flavour pcivf pfnum 0 vfnum 1

Reviewed-by: Roi Dayan <roid@mellanox.com>
Signed-off-by: Parav Pandit <parav@mellanox.com>
---
 .../net/ethernet/mellanox/mlx5/core/en_rep.c  | 108 +++++++++++++-----
 .../net/ethernet/mellanox/mlx5/core/en_rep.h  |   1 +
 2 files changed, 78 insertions(+), 31 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 529f8e4b32c6..6810b9fa0705 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -37,6 +37,7 @@
 #include <net/act_api.h>
 #include <net/netevent.h>
 #include <net/arp.h>
+#include <net/devlink.h>
 
 #include "eswitch.h"
 #include "en.h"
@@ -1119,32 +1120,6 @@ static int mlx5e_rep_close(struct net_device *dev)
 	return ret;
 }
 
-static int mlx5e_rep_get_phys_port_name(struct net_device *dev,
-					char *buf, size_t len)
-{
-	struct mlx5e_priv *priv = netdev_priv(dev);
-	struct mlx5e_rep_priv *rpriv = priv->ppriv;
-	struct mlx5_eswitch_rep *rep = rpriv->rep;
-	unsigned int fn;
-	int ret;
-
-	fn = PCI_FUNC(priv->mdev->pdev->devfn);
-	if (fn >= MLX5_MAX_PORTS)
-		return -EOPNOTSUPP;
-
-	if (rep->vport == MLX5_VPORT_UPLINK)
-		ret = snprintf(buf, len, "p%d", fn);
-	else if (rep->vport == MLX5_VPORT_PF)
-		ret = snprintf(buf, len, "pf%d", fn);
-	else
-		ret = snprintf(buf, len, "pf%dvf%d", fn, rep->vport - 1);
-
-	if (ret >= len)
-		return -EOPNOTSUPP;
-
-	return 0;
-}
-
 static int
 mlx5e_rep_setup_tc_cls_flower(struct mlx5e_priv *priv,
 			      struct tc_cls_flower_offload *cls_flower, int flags)
@@ -1298,17 +1273,24 @@ static int mlx5e_uplink_rep_set_vf_vlan(struct net_device *dev, int vf, u16 vlan
 	return 0;
 }
 
+static struct devlink_port *mlx5e_get_devlink_port(struct net_device *dev)
+{
+	struct mlx5e_priv *priv = netdev_priv(dev);
+	struct mlx5e_rep_priv *rpriv = priv->ppriv;
+
+	return &rpriv->dl_port;
+}
+
 static const struct net_device_ops mlx5e_netdev_ops_rep = {
 	.ndo_open                = mlx5e_rep_open,
 	.ndo_stop                = mlx5e_rep_close,
 	.ndo_start_xmit          = mlx5e_xmit,
-	.ndo_get_phys_port_name  = mlx5e_rep_get_phys_port_name,
 	.ndo_setup_tc            = mlx5e_rep_setup_tc,
+	.ndo_get_devlink_port = mlx5e_get_devlink_port,
 	.ndo_get_stats64         = mlx5e_rep_get_stats,
 	.ndo_has_offload_stats	 = mlx5e_rep_has_offload_stats,
 	.ndo_get_offload_stats	 = mlx5e_rep_get_offload_stats,
 	.ndo_change_mtu          = mlx5e_rep_change_mtu,
-	.ndo_get_port_parent_id	 = mlx5e_rep_get_port_parent_id,
 };
 
 static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
@@ -1316,8 +1298,8 @@ static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
 	.ndo_stop                = mlx5e_close,
 	.ndo_start_xmit          = mlx5e_xmit,
 	.ndo_set_mac_address     = mlx5e_uplink_rep_set_mac,
-	.ndo_get_phys_port_name  = mlx5e_rep_get_phys_port_name,
 	.ndo_setup_tc            = mlx5e_rep_setup_tc,
+	.ndo_get_devlink_port = mlx5e_get_devlink_port,
 	.ndo_get_stats64         = mlx5e_get_stats,
 	.ndo_has_offload_stats	 = mlx5e_rep_has_offload_stats,
 	.ndo_get_offload_stats	 = mlx5e_rep_get_offload_stats,
@@ -1330,7 +1312,6 @@ static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
 	.ndo_get_vf_config       = mlx5e_get_vf_config,
 	.ndo_get_vf_stats        = mlx5e_get_vf_stats,
 	.ndo_set_vf_vlan         = mlx5e_uplink_rep_set_vf_vlan,
-	.ndo_get_port_parent_id	 = mlx5e_rep_get_port_parent_id,
 	.ndo_set_features        = mlx5e_set_features,
 };
 
@@ -1731,6 +1712,55 @@ static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
 	.max_tc			= MLX5E_MAX_NUM_TC,
 };
 
+static bool
+is_devlink_port_supported(const struct mlx5_core_dev *dev,
+			  const struct mlx5e_rep_priv *rpriv)
+{
+	return rpriv->rep->vport == MLX5_VPORT_UPLINK ||
+	       rpriv->rep->vport == MLX5_VPORT_PF ||
+	       mlx5_eswitch_is_vf_vport(dev->priv.eswitch, rpriv->rep->vport);
+}
+
+static int register_devlink_port(struct mlx5_core_dev *dev,
+				 struct mlx5e_rep_priv *rpriv)
+{
+	struct devlink *devlink = priv_to_devlink(dev);
+	struct mlx5_eswitch_rep *rep = rpriv->rep;
+	struct netdev_phys_item_id ppid = {};
+	int ret;
+
+	if (!is_devlink_port_supported(dev, rpriv))
+		return 0;
+
+	ret = mlx5e_rep_get_port_parent_id(rpriv->netdev, &ppid);
+	if (ret)
+		return ret;
+
+	if (rep->vport == MLX5_VPORT_UPLINK)
+		devlink_port_attrs_set(&rpriv->dl_port,
+				       DEVLINK_PORT_FLAVOUR_PHYSICAL,
+				       PCI_FUNC(dev->pdev->devfn), false, 0,
+				       &ppid.id[0], ppid.id_len);
+	else if (rep->vport == MLX5_VPORT_PF)
+		devlink_port_attrs_pci_pf_set(&rpriv->dl_port,
+					      &ppid.id[0], ppid.id_len,
+					      dev->pdev->devfn);
+	else if (mlx5_eswitch_is_vf_vport(dev->priv.eswitch, rpriv->rep->vport))
+		devlink_port_attrs_pci_vf_set(&rpriv->dl_port,
+					      &ppid.id[0], ppid.id_len,
+					      dev->pdev->devfn,
+					      rep->vport - 1);
+
+	return devlink_port_register(devlink, &rpriv->dl_port, rep->vport);
+}
+
+static void unregister_devlink_port(struct mlx5_core_dev *dev,
+				    struct mlx5e_rep_priv *rpriv)
+{
+	if (is_devlink_port_supported(dev, rpriv))
+		devlink_port_unregister(&rpriv->dl_port);
+}
+
 /* e-Switch vport representors */
 static int
 mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
@@ -1782,15 +1812,27 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
 		goto err_detach_netdev;
 	}
 
+	err = register_devlink_port(dev, rpriv);
+	if (err) {
+		esw_warn(dev, "Failed to register devlink port %d\n",
+			 rep->vport);
+		goto err_neigh_cleanup;
+	}
+
 	err = register_netdev(netdev);
 	if (err) {
 		pr_warn("Failed to register representor netdev for vport %d\n",
 			rep->vport);
-		goto err_neigh_cleanup;
+		goto err_devlink_cleanup;
 	}
 
+	if (is_devlink_port_supported(dev, rpriv))
+		devlink_port_type_eth_set(&rpriv->dl_port, netdev);
 	return 0;
 
+err_devlink_cleanup:
+	unregister_devlink_port(dev, rpriv);
+
 err_neigh_cleanup:
 	mlx5e_rep_neigh_cleanup(rpriv);
 
@@ -1813,9 +1855,13 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
 	struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
 	struct net_device *netdev = rpriv->netdev;
 	struct mlx5e_priv *priv = netdev_priv(netdev);
+	struct mlx5_core_dev *dev = priv->mdev;
 	void *ppriv = priv->ppriv;
 
+	if (is_devlink_port_supported(dev, rpriv))
+		devlink_port_type_clear(&rpriv->dl_port);
 	unregister_netdev(netdev);
+	unregister_devlink_port(dev, rpriv);
 	mlx5e_rep_neigh_cleanup(rpriv);
 	mlx5e_detach_netdev(priv);
 	if (rep->vport == MLX5_VPORT_UPLINK)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
index d4585f3b8cb2..c56e6ee4350c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
@@ -86,6 +86,7 @@ struct mlx5e_rep_priv {
 	struct mlx5_flow_handle *vport_rx_rule;
 	struct list_head       vport_sqs_list;
 	struct mlx5_rep_uplink_priv uplink_priv; /* valid for uplink rep */
+	struct devlink_port dl_port;
 };
 
 static inline
-- 
2.19.2


^ 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