Netdev List
 help / color / mirror / Atom feed
* [PATCH v2] net: sh_eth: fix driver dependencies
From: Bartlomiej Zolnierkiewicz @ 2014-09-01 14:25 UTC (permalink / raw)
  To: David S. Miller
  Cc: Simon Horman, Magnus Damm, Kyungmin Park, netdev, linux-sh,
	linux-kernel

Renesas SuperH Ethernet support should be available only on
Renesas ARM SoCs and SuperH architecture.

Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Simon Horman <horms@verge.net.au>
Cc: Magnus Damm <magnus.damm@gmail.com>
---
v2:
- s/ARCH_SH/SUPERH/ (thanks to Sergei Shtylyov)

 drivers/net/ethernet/renesas/Kconfig |    1 +
 1 file changed, 1 insertion(+)

Index: b/drivers/net/ethernet/renesas/Kconfig
===================================================================
--- a/drivers/net/ethernet/renesas/Kconfig	2014-07-30 14:31:20.479522692 +0200
+++ b/drivers/net/ethernet/renesas/Kconfig	2014-09-01 14:45:36.160544016 +0200
@@ -5,6 +5,7 @@
 config SH_ETH
 	tristate "Renesas SuperH Ethernet support"
 	depends on HAS_DMA
+	depends on ARCH_SHMOBILE || SUPERH || COMPILE_TEST
 	select CRC32
 	select MII
 	select MDIO_BITBANG


^ permalink raw reply

* Re: Sending undersized ARP packets with VXLAN L3 interface
From: Martin Rusko @ 2014-09-01 14:26 UTC (permalink / raw)
  To: Vlad Yasevich, Stephen Hemminger; +Cc: netdev
In-Reply-To: <CAMYYbY7vCqpW7pqy=a7O=9YnPM=R1Ta2gfXdZEqrmyK-P-Akdw@mail.gmail.com>

>>>>>
>>>>> No. The short frame is perfectly valid, over the VXLAN.
>>>>> The system doing the decap and forwarding should be where any padding is added if necessary.
>>>>>
>>>
>>> Well, RFC 7348 is not dealing with padding at all. Both deployment
>>> scenarios listed in RFC, as well as most of the existing real life
>>> deployments today (in my opinion) use VXLAN for bridged traffic. In
>>> other words, frame encapsulated by VTEP is received first over some
>>> ethernet interface (physical or virtual) which implies that the frame
>>> is at least 64 bytes long already.
>>>
>>> Perhaps we're going to see more VXLAN interfaces in L3 mode, yet it
>>> might be safer not to count on receiving VTEP doing the right thing
>>> (pad small packets with zeros).
>>>
>>>>
>>>> If that's the case, then Martin is most likely seeing a HW bug on the switch.
>>>> I wonder how common such a bug might be?
>>>>
>>>> -vlad
>>>>
>>>
>>> I see this on Vmware distributed virtual switch. Perhaps soon I will
>>> be able to test it against HP 5930 switch. I'm going to try how Linux
>>> bridge copes with it, now.
>>
>> Linux bridge will do just fine as it will pass the frame off to the hw driver
>> which should pad things appropriately.
>>
>> -vlad
>>
>
> I can confirm that, now.

I also tried a setup with Xen hypervisor and HVM guest connected to
bridge with vxlan interface. In any combination I tried, it pretty
much didn't care about the ethernet packet size.

Haven't had chance to test it with hardware switch yet, so it's only
causing problems with Vmware so far, when inner ethernet frame is not
padded.

>
> Vlad, I'm going to recompile 3.16.1 kernel with your patch.
>

Vlad's patch works perfectly. I asked the authors of RFC 7348 to
eventually clarify if any padding should be required for the inner
frames. Shall the patch be included in the mainline kernel or not?

/Martin

^ permalink raw reply

* [PATCH net] bnx2x: Configure device endianity on driver load and reset endianity on removal.
From: Manish Chopra @ 2014-09-01 14:17 UTC (permalink / raw)
  To: davem; +Cc: netdev, Ariel.Elior, Yuval.Mintz

Some hosts can be both little and big endian.
In certain scenarios a big endian kernel can kexec a little endian kernel.

This patch fixes this case from both ends:
1) Return endianity to original values on shutdown (in case little endian kernel boots after we shutdown).
2) Do not rely on HW reset values when loading driver in little endian kernel
   but configure them explicitly (in case previous kernel was big endian and did not reset the HW).

Signed-off-by: Manish Chopra <manish.chopra@qlogic.com>
Signed-off-by: Ariel Elior <Ariel.Elior@qlogic.com>
---

Hi David,

Please consider applying this patch to `net'

Thanks,
Manish

---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c |   54 +++++++++++++++-------
 1 files changed, 37 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 900cab4..418d798 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -6849,6 +6849,37 @@ static void bnx2x__common_init_phy(struct bnx2x *bp)
 	bnx2x_release_phy_lock(bp);
 }
 
+static void bnx2x_config_endianity(struct bnx2x *bp, u32 val)
+{
+	REG_WR(bp, PXP2_REG_RQ_QM_ENDIAN_M, val);
+	REG_WR(bp, PXP2_REG_RQ_TM_ENDIAN_M, val);
+	REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, val);
+	REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, val);
+	REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, val);
+
+	/* make sure this value is 0 */
+	REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 0);
+
+	REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, val);
+	REG_WR(bp, PXP2_REG_RD_TM_SWAP_MODE, val);
+	REG_WR(bp, PXP2_REG_RD_SRC_SWAP_MODE, val);
+	REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, val);
+}
+
+static inline void bnx2x_set_endianity(struct bnx2x *bp)
+{
+#ifdef __BIG_ENDIAN
+	bnx2x_config_endianity(bp, 1);
+#else
+	bnx2x_config_endianity(bp, 0);
+#endif
+}
+
+static inline void bnx2x_reset_endianity(struct bnx2x *bp)
+{
+	bnx2x_config_endianity(bp, 0);
+}
+
 /**
  * bnx2x_init_hw_common - initialize the HW at the COMMON phase.
  *
@@ -6915,23 +6946,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp)
 
 	bnx2x_init_block(bp, BLOCK_PXP2, PHASE_COMMON);
 	bnx2x_init_pxp(bp);
-
-#ifdef __BIG_ENDIAN
-	REG_WR(bp, PXP2_REG_RQ_QM_ENDIAN_M, 1);
-	REG_WR(bp, PXP2_REG_RQ_TM_ENDIAN_M, 1);
-	REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, 1);
-	REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, 1);
-	REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, 1);
-	/* make sure this value is 0 */
-	REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 0);
-
-/*	REG_WR(bp, PXP2_REG_RD_PBF_SWAP_MODE, 1); */
-	REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, 1);
-	REG_WR(bp, PXP2_REG_RD_TM_SWAP_MODE, 1);
-	REG_WR(bp, PXP2_REG_RD_SRC_SWAP_MODE, 1);
-	REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1);
-#endif
-
+	bnx2x_set_endianity(bp);
 	bnx2x_ilt_init_page_size(bp, INITOP_SET);
 
 	if (CHIP_REV_IS_FPGA(bp) && CHIP_IS_E1H(bp))
@@ -13172,6 +13187,11 @@ static void __bnx2x_remove(struct pci_dev *pdev,
 	if (IS_PF(bp))
 		bnx2x_set_power_state(bp, PCI_D0);
 
+	/* Set endianity registers to reset values in case next driver
+	 * boots in different endianty environment.
+	 */
+	bnx2x_reset_endianity(bp);
+
 	/* Disable MSI/MSI-X */
 	bnx2x_disable_msi(bp);
 
-- 
1.7.1

^ permalink raw reply related

* Re: [PATCH v3] ethernet: arc: Add support for Rockchip SoC layer device tree bindings
From: Heiko Stübner @ 2014-09-01 15:32 UTC (permalink / raw)
  To: Romain Perier; +Cc: linux-rockchip, linux-arm-kernel, netdev, arnd
In-Reply-To: <1409560407-5447-1-git-send-email-romain.perier@gmail.com>

Am Montag, 1. September 2014, 08:33:27 schrieb Romain Perier:
> This patch defines a platform glue layer for Rockchip SoCs which
> support arc-emac driver. It ensures that regulator for the rmii is on
> before trying to connect to the ethernet controller. It applies right
> speed and mode changes to the grf when ethernet settings change.
> 
> Signed-off-by: Romain Perier <romain.perier@gmail.com>

As we already talked about in irc, the dt-binding document is missing


> ---
>  drivers/net/ethernet/arc/Kconfig         |  10 ++
>  drivers/net/ethernet/arc/Makefile        |   1 +
>  drivers/net/ethernet/arc/emac.h          |   4 +-
>  drivers/net/ethernet/arc/emac_main.c     |   2 +
>  drivers/net/ethernet/arc/emac_rockchip.c | 224
> +++++++++++++++++++++++++++++++ 5 files changed, 240 insertions(+), 1
> deletion(-)
>  create mode 100644 drivers/net/ethernet/arc/emac_rockchip.c
> 
> diff --git a/drivers/net/ethernet/arc/Kconfig
> b/drivers/net/ethernet/arc/Kconfig index 89e04fd..0c0063b 100644
> --- a/drivers/net/ethernet/arc/Kconfig
> +++ b/drivers/net/ethernet/arc/Kconfig
> @@ -32,4 +32,14 @@ config ARC_EMAC
>  	  non-standard on-chip ethernet device ARC EMAC 10/100 is used.
>  	  Say Y here if you have such a board.  If unsure, say N.
> 
> +config EMAC_ROCKCHIP
> +       tristate "Rockchip EMAC support"
> +       select ARC_EMAC_CORE
> +       depends on OF_IRQ && OF_NET && REGULATOR
> +       ---help---
> +         Support for Rockchip RK3066/RK3188 EMAC ethernet controllers.
> +         This selects Rockchip SoC glue layer support for the
> +         emac device driver. This driver is used for RK3066/RK3188
> +         EMAC ethernet controller.
> +

the other entries use tabs for the initial indentation here


>  endif # NET_VENDOR_ARC
> diff --git a/drivers/net/ethernet/arc/Makefile
> b/drivers/net/ethernet/arc/Makefile index 241bb80..79108af 100644
> --- a/drivers/net/ethernet/arc/Makefile
> +++ b/drivers/net/ethernet/arc/Makefile
> @@ -5,3 +5,4 @@
>  arc_emac-objs := emac_main.o emac_mdio.o
>  obj-$(CONFIG_ARC_EMAC_CORE) += arc_emac.o
>  obj-$(CONFIG_ARC_EMAC) += emac_arc.o
> +obj-$(CONFIG_EMAC_ROCKCHIP) += emac_rockchip.o
> diff --git a/drivers/net/ethernet/arc/emac.h
> b/drivers/net/ethernet/arc/emac.h index eb2ba67..dae1ac3 100644
> --- a/drivers/net/ethernet/arc/emac.h
> +++ b/drivers/net/ethernet/arc/emac.h
> @@ -123,9 +123,11 @@ struct buffer_state {
>   * @speed:	PHY's last set speed.
>   */
>  struct arc_emac_priv {
> -	/* Devices */
>  	const char *drv_name;
>  	const char *drv_version;
> +	void (*set_mac_speed)(void *priv, unsigned int speed);
> +
> +	/* Devices */
>  	struct device *dev;
>  	struct phy_device *phy_dev;
>  	struct mii_bus *bus;
> diff --git a/drivers/net/ethernet/arc/emac_main.c
> b/drivers/net/ethernet/arc/emac_main.c index b35c69e..a08f343 100644
> --- a/drivers/net/ethernet/arc/emac_main.c
> +++ b/drivers/net/ethernet/arc/emac_main.c
> @@ -48,6 +48,8 @@ static void arc_emac_adjust_link(struct net_device *ndev)
>  	if (priv->speed != phy_dev->speed) {
>  		priv->speed = phy_dev->speed;
>  		state_changed = 1;
> +		if (priv->set_mac_speed)
> +			priv->set_mac_speed(priv, priv->speed);
>  	}
> 
>  	if (priv->duplex != phy_dev->duplex) {
> diff --git a/drivers/net/ethernet/arc/emac_rockchip.c
> b/drivers/net/ethernet/arc/emac_rockchip.c new file mode 100644
> index 0000000..d1d367a
> --- /dev/null
> +++ b/drivers/net/ethernet/arc/emac_rockchip.c
> @@ -0,0 +1,224 @@
> +/**
> + * emac-rockchip.c - Rockchip EMAC specific glue layer
> + *
> + * Copyright (C) 2014 Romain Perier
> + *
> + * Romain Perier  <romain.perier@gmail.com>

these 3 could simply be one line:

Copyright (C) 2014 Romain Perier <romain.perier@gmail.com>

> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/etherdevice.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of_net.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/consumer.h>
> +
> +#include "emac.h"
> +
> +#define DRV_NAME        "rockchip_emac"
> +#define DRV_VERSION     "1.0"
> +
> +#define GRF_MODE_MII         (1UL << 0)
> +#define GRF_MODE_RMII        (0UL << 0)
> +#define GRF_SPEED_10M        (0UL << 1)
> +#define GRF_SPEED_100M       (1UL << 1)
> +#define GRF_SPEED_ENABLE_BIT (1UL << 17)
> +#define GRF_MODE_ENABLE_BIT  (1UL << 16)

personally I'd use tabs here to align the two columns


> +
> +struct emac_rockchip_soc_data {
> +	int grf_offset;
> +};
> +
> +struct rockchip_priv_data {
> +	struct arc_emac_priv emac;
> +	struct regmap *grf;
> +	const struct emac_rockchip_soc_data *soc_data;
> +	struct regulator *regulator;
> +	struct clk *refclk;
> +};
> +
> +static const struct emac_rockchip_soc_data emac_rockchip_dt_data[] = {
> +	{ .grf_offset = 0x154 }, /* rk3066 */
> +	{ .grf_offset = 0x0a4 }, /* rk3188 */
> +};
> +
> +static const struct of_device_id emac_rockchip_dt_ids[] = {
> +	{ .compatible = "rockchip,rk3066-emac", .data = &emac_rockchip_dt_data[0]},
> +	{ .compatible = "rockchip,rk3188-emac", .data = &emac_rockchip_dt_data[1]},

space before closing "}"


> +	{ /* Sentinel */ }
> +};
> +
> +static void emac_rockchip_set_mac_speed(void *priv, unsigned int speed)
> +{
> +	struct rockchip_priv_data *emac = priv;
> +	u32 data;
> +	int err = 0;
> +
> +	/* write-enable bits */
> +	data = GRF_SPEED_ENABLE_BIT;
> +
> +	switch(speed) {
> +	case 10:
> +		data |= GRF_SPEED_10M;
> +		break;
> +	case 100:
> +		data |= GRF_SPEED_100M;
> +		break;
> +	default:
> +		pr_err("speed %u not supported\n", speed);
> +		return;
> +	}
> +
> +	err = regmap_write(emac->grf, emac->soc_data->grf_offset, data);
> +	if (err)
> +		pr_err("unable to apply speed %u to grf (%d)\n", speed, err);
> +}
> +
> +static int emac_rockchip_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct net_device *ndev;
> +	struct rockchip_priv_data *priv;
> +	const struct of_device_id *match;
> +	u32 data;
> +	int err, interface;
> +
> +	if (!pdev->dev.of_node)
> +		return -ENODEV;
> +
> +	ndev = alloc_etherdev(sizeof(struct rockchip_priv_data));
> +	if (!ndev)
> +		return -ENOMEM;
> +	platform_set_drvdata(pdev, ndev);
> +	SET_NETDEV_DEV(ndev, dev);
> +
> +	priv = netdev_priv(ndev);
> +	priv->emac.drv_name = DRV_NAME;
> +	priv->emac.drv_version = DRV_VERSION;
> +	priv->emac.set_mac_speed = emac_rockchip_set_mac_speed;
> +
> +	interface = of_get_phy_mode(dev->of_node);
> +
> +	/* RK3066 and RK3188 SoCs only support RMII */
> +	if (interface != PHY_INTERFACE_MODE_RMII) {
> +		dev_err(dev, "unsupported phy interface mode %d\n", interface);
> +		err = -ENOTSUPP;
> +		goto out_netdev;
> +	}
> +
> +	priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
> +	if (IS_ERR(priv->grf)) {
> +		dev_err(dev, "failed to retrieve global register file from the device
> tree (%ld)\n", PTR_ERR(priv->grf)); +		err = PTR_ERR(priv->grf);
> +		goto out_netdev;
> +	}
> +
> +	match = of_match_node(emac_rockchip_dt_ids, dev->of_node);
> +	priv->soc_data = match->data;
> +
> +	priv->emac.clk = devm_clk_get(dev, "hclk");
> +	if (IS_ERR(priv->emac.clk)) {
> +		dev_err(dev, "failed to retrieve host clock from device tree (%ld)\n",
> PTR_ERR(priv->emac.clk)); +		err = PTR_ERR(priv->emac.clk);
> +		goto out_netdev;
> +	}
> +
> +	priv->refclk = devm_clk_get(dev, "macref");
> +	if (IS_ERR(priv->refclk)) {
> +		dev_err(dev, "failed to retrieve reference clock from device tree
> (%ld)\n", PTR_ERR(priv->refclk)); +		err = PTR_ERR(priv->refclk);
> +		goto out_netdev;
> +	}
> +
> +	err = clk_prepare_enable(priv->refclk);
> +	if (err) {
> +		dev_err(dev, "failed to enable reference clock (%d)\n", err);
> +		goto out_netdev;
> +	}
> +
> +        /* Optional regulator for PHY */

spaces as indentation here, please use a tab instead


> +	priv->regulator = devm_regulator_get_optional(dev, "phy");
> +	if (IS_ERR(priv->regulator)) {
> +		if (PTR_ERR(priv->regulator) == -EPROBE_DEFER)
> +			return -EPROBE_DEFER;
> +		dev_err(dev, "no regulator found\n");
> +		priv->regulator = NULL;
> +	}
> +
> +	if (priv->regulator) {
> +		err = regulator_enable(priv->regulator);
> +		if (err) {
> +			dev_err(dev, "failed to enable phy-supply (%d)\n", err);
> +			goto out_netdev;

goto out_clk_disable;

> +		}
> +	}
> +
> +	err = arc_emac_probe(ndev, interface);
> +	if (err)
> +		goto out_netdev;

goto out_reg_disable;

> +
> +	/* write-enable bits */
> +	data = GRF_MODE_ENABLE_BIT | GRF_SPEED_ENABLE_BIT;
> +
> +	data |= GRF_SPEED_100M;
> +	data |= GRF_MODE_RMII;
> +
> +	err = regmap_write(priv->grf, priv->soc_data->grf_offset, data);
> +	if (err) {
> +		dev_err(dev, "unable to apply initial settings to grf (%d)\n", err);
> +		goto out_netdev;

goto out_reg_disable;

> +	}
> +
> +	/* RMII interface needs always a rate of 50MHz */
> +	err = clk_set_rate(priv->refclk, 50000000);
> +	if (err)
> +		dev_err(dev, "failed to change reference clock rate (%d)\n", err);
> +

	err = clk_set_rate(priv->refclk, 50000000);
	if (err) {
		dev_err(dev, "failed to change reference clock rate (%d)\n", err);
		goto out_reg_disable;
	}

	return 0;

out_reg_disable:
	if (priv->regulator)
		regulator_disable(priv->regulator);
out_clk_disable:
	clk_disable_unprepare(priv->refclk);
out_netdev:
	free_netdev(ndev);
	return err;



> +out_netdev:
> +	if (err)
> +		free_netdev(ndev);
> +	return err;
> +}
> +
> +static int emac_rockchip_remove(struct platform_device *pdev)
> +{
> +	struct net_device *ndev = platform_get_drvdata(pdev);
> +	struct rockchip_priv_data *priv = netdev_priv(ndev);
> +	int err;
> +
> +	clk_disable_unprepare(priv->refclk);
> +
> +	if (priv->regulator)
> +		regulator_disable(priv->regulator);

blank line

> +	err = arc_emac_remove(ndev);
> +	free_netdev(ndev);
> +	return err;
> +}
> +
> +MODULE_DEVICE_TABLE(of, emac_rockchip_dt_ids);
> +
> +static struct platform_driver emac_rockchip_driver = {
> +	.probe = emac_rockchip_probe,
> +	.remove = emac_rockchip_remove,
> +	.driver = {
> +		.name = DRV_NAME,
> +		.of_match_table  = emac_rockchip_dt_ids,
> +	},
> +};
> +
> +module_platform_driver(emac_rockchip_driver);
> +
> +MODULE_AUTHOR("Romain Perier <romain.perier@gmail.com>");
> +MODULE_DESCRIPTION("Rockchip EMAC platform driver");
> +MODULE_LICENSE("GPL");

^ permalink raw reply

* RE: [PATCH net] bnx2x: Configure device endianity on driver load and reset endianity on removal.
From: Manish Chopra @ 2014-09-01 15:33 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Ariel Elior, Yuval Mintz
In-Reply-To: <1409581043-25357-1-git-send-email-manish.chopra@qlogic.com>

> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org]
> On Behalf Of Manish Chopra
> Sent: Monday, September 01, 2014 7:47 PM
> To: David Miller
> Cc: netdev; Ariel Elior; Yuval Mintz
> Subject: [PATCH net] bnx2x: Configure device endianity on driver load and reset
> endianity on removal.
> 
> Some hosts can be both little and big endian.
> In certain scenarios a big endian kernel can kexec a little endian kernel.
> 
> This patch fixes this case from both ends:
> 1) Return endianity to original values on shutdown (in case little endian kernel
> boots after we shutdown).
> 2) Do not rely on HW reset values when loading driver in little endian kernel
>    but configure them explicitly (in case previous kernel was big endian and did
> not reset the HW).
> 
> Signed-off-by: Manish Chopra <manish.chopra@qlogic.com>
> Signed-off-by: Ariel Elior <Ariel.Elior@qlogic.com>
> ---
> 
> Hi David,
> 
> Please consider applying this patch to `net'
> 
> Thanks,
> Manish

David, Please drop this patch as it might create issue for VFs.
I will send updated V2 patch with proper fix. 

Thanks,
Manish 
 

^ permalink raw reply

* [PATCH] net: calxedaxgmac: fix driver dependencies
From: Bartlomiej Zolnierkiewicz @ 2014-09-01 15:39 UTC (permalink / raw)
  To: David S. Miller; +Cc: Rob Herring, Kyungmin Park, netdev, linux-kernel

Calxeda 1G/10G XGMAC Ethernet support should be available only on
Calxeda ECX-1000/2000 (Highbank/Midway) platforms.

Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Rob Herring <robh@kernel.org>
---
 drivers/net/ethernet/calxeda/Kconfig |    1 +
 1 file changed, 1 insertion(+)

Index: b/drivers/net/ethernet/calxeda/Kconfig
===================================================================
--- a/drivers/net/ethernet/calxeda/Kconfig	2014-07-30 14:31:12.159522474 +0200
+++ b/drivers/net/ethernet/calxeda/Kconfig	2014-09-01 17:33:49.232810483 +0200
@@ -1,6 +1,7 @@
 config NET_CALXEDA_XGMAC
 	tristate "Calxeda 1G/10G XGMAC Ethernet driver"
 	depends on HAS_IOMEM && HAS_DMA
+	depends on ARCH_HIGHBANK || COMPILE_TEST
 	select CRC32
 	help
 	  This is the driver for the XGMAC Ethernet IP block found on Calxeda

^ permalink raw reply

* Re: [PATCH v2] net: sh_eth: fix driver dependencies
From: Sergei Shtylyov @ 2014-09-01 16:13 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, David S. Miller
  Cc: Simon Horman, Magnus Damm, Kyungmin Park, netdev, linux-sh,
	linux-kernel
In-Reply-To: <1749721.1a6rN6K2Gg@amdc1032>

On 09/01/2014 06:25 PM, Bartlomiej Zolnierkiewicz wrote:

> Renesas SuperH Ethernet support should be available only on
> Renesas ARM SoCs and SuperH architecture.

> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> Cc: Simon Horman <horms@verge.net.au>
> Cc: Magnus Damm <magnus.damm@gmail.com>

Acked-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

WBR, Sergei


^ permalink raw reply

* Re: [PATCH v2] net: sh_eth: fix driver dependencies
From: Geert Uytterhoeven @ 2014-09-01 16:36 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: David S. Miller, Simon Horman, Magnus Damm, Kyungmin Park,
	netdev@vger.kernel.org, Linux-sh list,
	linux-kernel@vger.kernel.org
In-Reply-To: <1749721.1a6rN6K2Gg@amdc1032>

On Mon, Sep 1, 2014 at 4:25 PM, Bartlomiej Zolnierkiewicz
<b.zolnierkie@samsung.com> wrote:
> Renesas SuperH Ethernet support should be available only on
> Renesas ARM SoCs and SuperH architecture.
>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> Cc: Simon Horman <horms@verge.net.au>
> Cc: Magnus Damm <magnus.damm@gmail.com>
> ---
> v2:
> - s/ARCH_SH/SUPERH/ (thanks to Sergei Shtylyov)

Acked-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: [patch net-next RFC 10/12] openvswitch: add support for datapath hardware offload
From: Jamal Hadi Salim @ 2014-09-01 16:37 UTC (permalink / raw)
  To: Simon Horman
  Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w, ronye-VPRAkNaXOzVWk0Htik3J/w,
	jasowang-H+wXaHxf7aLQT0dZR+AlfA,
	john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
	Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ, Eric Dumazet, Andy Gospodarek,
	dev-yBygre7rU0TnMu66kgdUjQ@public.gmane.org,
	nbd-p3rKhJxN3npAfugRpC6u6w, Florian Fainelli, Andy Gospodarek,
	Shrijeet Mukherjee, John Fastabend,
	jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w, ogerlitz,
	ben-/+tVBieCtBitmTQ+vhA3Yw, buytenh-OLH4Qvv75CYX/NnBR394Jw,
	Jiri Pirko, Roopa Prabhu, aviadr-VPRAkNaXOzVWk0Htik3J/w,
	Nicolas Dichtel, vyasevic-H+wXaHxf7aLQT0dZR+AlfA, Neil Horman,
	netdev, Stephen Hemminger, dborkman, Eric W. Biederman
In-Reply-To: <20140901081343.GC12731-IxS8c3vjKQDk1uMJSBkQmQ@public.gmane.org>

On 09/01/14 04:13, Simon Horman wrote:
> On Fri, Aug 29, 2014 at 10:20:55AM -0400, Jamal Hadi Salim wrote:

>> I actually have no issues with whatever classifier someone decides
>> to use. To each their poison. But I do take issue mandating the
>> specified classifer it as THE CLASSIFIER as in this case,
>> is where i start taking issue. I have a few things that i offload
>> to hardware with speacilized classifiers such that i object strongly
>> to the approach this driver has taken.
>
> My reading of this thread is that allowing different classifiers
> is not under dispute.


I am not sure how you reached that conclusion by reading this thread;->
But i would be glad if that was the conclusion and i missed it.

cheers,
jamal

^ permalink raw reply

* Re: [PATCH] brcmfmac: BRCMFMAC should depend on HAS_DMA
From: Geert Uytterhoeven @ 2014-09-01 16:51 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Brett Rudley, John W. Linville, David S. Miller, linux-wireless,
	brcm80211-dev-list, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <54046CA1.4040108@broadcom.com>

Hi Arend,

On Mon, Sep 1, 2014 at 2:54 PM, Arend van Spriel <arend@broadcom.com> wrote:
> On 09/01/14 10:44, Geert Uytterhoeven wrote:
>> On Mon, Sep 1, 2014 at 10:21 AM, Arend van Spriel<arend@broadcom.com>
>> wrote:
>>>>
>>>>    config BRCMFMAC
>>>>          tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
>>>> -       depends on CFG80211
>>>> +       depends on CFG80211A&&   HAS_DMA
>>>
>>> Not sure what happened here, but CFG80211 kconfig option did was not
>>> renamed
>>> as far as I know. Anyway, I would like to propose a different solution.
>>> Will get back to you when I have it ready.

> I added Kconfig options for the proto layer which are selected by the host
> interface selection. So the HAS_DMA dependency is checked for BRCMFMAC_PCIE.

Thanks!

> I am wondering whether GENERIC_IO should also be checked.

Probably not. Let's see if anyone complains ;-)

> Can you verify the patch below works with your configuration?

Yes, it compiles and links fine now (after applying it manually due to
whitespace mess-up).

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: [PATCH] packet.7: fix include file
From: Michael Kerrisk (man-pages) @ 2014-09-01 17:25 UTC (permalink / raw)
  To: Sorin Dumitru, linux-man-u79uwXL29TY76Z2rM5mHXA
  Cc: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w,
	netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1409318406-5217-1-git-send-email-sdumitru-+zzKsuq53OdBDgjK7y7TUQ@public.gmane.org>

On 08/29/2014 03:20 PM, Sorin Dumitru wrote:
> It looks like most of the socket options from this man pages
> are not defined in <netpacket/packet.h>. They are defined in
> <linux/if_packet.h> so we should include that one.

Hello Sorin,

It looks like <netpacket/packet.h> was based on some ancient
version of <linux/if_packet.h> that has not been updated.
Since linux/if_packet.h is under the "uapi" tree the
proposed patch seems the best fix. Thanks for sending it.
I've applied it.

Cheers,

Michael





> Signed-off-by: Sorin Dumitru <sdumitru-+zzKsuq53OdBDgjK7y7TUQ@public.gmane.org>
> ---
>  man7/packet.7 | 14 +-------------
>  1 file changed, 1 insertion(+), 13 deletions(-)
> 
> diff --git a/man7/packet.7 b/man7/packet.7
> index 57cd3ca..7b6f20d 100644
> --- a/man7/packet.7
> +++ b/man7/packet.7
> @@ -16,7 +16,7 @@ packet \- packet interface on device level
>  .nf
>  .B #include <sys/socket.h>
>  .br
> -.B #include <netpacket/packet.h>
> +.B #include <linux/if_packet.h>
>  .br
>  .B #include <net/ethernet.h>     /* the L2 protocols */
>  .sp
> @@ -535,18 +535,6 @@ is a new feature in Linux 2.2.
>  Earlier Linux versions supported only
>  .BR SOCK_PACKET .
>  .PP
> -The include file
> -.I <netpacket/packet.h>
> -is present since glibc 2.1.
> -Older systems need:
> -.sp
> -.in +4n
> -.nf
> -#include <asm/types.h>
> -#include <linux/if_packet.h>
> -#include <linux/if_ether.h>  /* The L2 protocols */
> -.fi
> -.in
>  .SH NOTES
>  For portable programs it is suggested to use
>  .B AF_PACKET
> 


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH net-next 1/2] ipv6: add sysctl_mld_qrv to configure query robustness variable
From: Flavio Leitner @ 2014-09-01 18:08 UTC (permalink / raw)
  To: Hannes Frederic Sowa; +Cc: netdev
In-Reply-To: <1880a888c65dff7b7c73aa53eabbb841a65a74ce.1409366462.git.hannes@stressinduktion.org>

On Sat, Aug 30, 2014 at 04:42:53AM +0200, Hannes Frederic Sowa wrote:
> This patch adds a new sysctl_mld_qrv knob to configure the mldv1/v2 query
> robustness variable. It sepcifies how many retransmit of unsolicited mld
                          ^^^^^^^^^
typo

> retransmit should happen. Admins might want to tune this on lossy links.
> 
> Also reset mld state on interface down/up, so we pick up new sysctl
> settings during interface up event.
> 
> IPv6 certification requests this knob to be available.
> 
> I didn't make this knob netns specific, as it is mostly a setting in a
> physical environment and should be per host.
> 
> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
> ---
>  Documentation/networking/ip-sysctl.txt |  3 +++
>  include/net/ipv6.h                     |  1 +
>  net/ipv6/mcast.c                       | 20 ++++++++++++--------
>  net/ipv6/sysctl_net_ipv6.c             | 10 ++++++++++
>  4 files changed, 26 insertions(+), 8 deletions(-)
> 
> diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
> index 3cce8ea..b7fe844 100644
> --- a/Documentation/networking/ip-sysctl.txt
> +++ b/Documentation/networking/ip-sysctl.txt
> @@ -1152,6 +1152,9 @@ anycast_src_echo_reply - BOOLEAN
>  	FALSE: disabled
>  	Default: FALSE
>  
> +mld_qrv - INTEGER
> +	Controls the MLD query robustness variable (see RFC3810 9.1).
> +
>  IPv6 Fragmentation:
>  
>  ip6frag_high_thresh - INTEGER
> diff --git a/include/net/ipv6.h b/include/net/ipv6.h
> index a2db816..7e247e9 100644
> --- a/include/net/ipv6.h
> +++ b/include/net/ipv6.h
> @@ -121,6 +121,7 @@ struct frag_hdr {
>  
>  /* sysctls */
>  extern int sysctl_mld_max_msf;
> +extern int sysctl_mld_qrv;
>  
>  #define _DEVINC(net, statname, modifier, idev, field)			\
>  ({									\
> diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
> index 7088179..6efb0e5 100644
> --- a/net/ipv6/mcast.c
> +++ b/net/ipv6/mcast.c
> @@ -121,6 +121,7 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
>  #define IPV6_MLD_MAX_MSF	64
>  
>  int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF;
> +int sysctl_mld_qrv __read_mostly = MLD_QRV_DEFAULT;
>  
>  /*
>   *	socket join on multicast group
> @@ -1196,7 +1197,7 @@ static void mld_update_qrv(struct inet6_dev *idev,
>  	if (mlh2->mld2q_qrv > 0)
>  		idev->mc_qrv = mlh2->mld2q_qrv;
>  
> -	if (unlikely(idev->mc_qrv < 2)) {
> +	if (unlikely(idev->mc_qrv < MLD_QRV_DEFAULT)) {
>  		net_warn_ratelimited("IPv6: MLD: clamping QRV from %u to %u!\n",
>  				     idev->mc_qrv, MLD_QRV_DEFAULT);
>  		idev->mc_qrv = MLD_QRV_DEFAULT;
> @@ -2478,6 +2479,14 @@ void ipv6_mc_down(struct inet6_dev *idev)
>  	mld_clear_delrec(idev);
>  }
>  
> +static void ipv6_mc_reset(struct inet6_dev *idev)
> +{
> +	idev->mc_qrv = sysctl_mld_qrv;
> +	idev->mc_qi = MLD_QI_DEFAULT;
> +	idev->mc_qri = MLD_QRI_DEFAULT;
> +	idev->mc_v1_seen = 0;
> +	idev->mc_maxdelay = unsolicited_report_interval(idev);
> +}
>  
>  /* Device going up */
>  
> @@ -2488,6 +2497,7 @@ void ipv6_mc_up(struct inet6_dev *idev)
>  	/* Install multicast list, except for all-nodes (already installed) */
>  
>  	read_lock_bh(&idev->lock);
> +	ipv6_mc_reset(idev);
>  	for (i = idev->mc_list; i; i = i->next)
>  		igmp6_group_added(i);
>  	read_unlock_bh(&idev->lock);
> @@ -2508,13 +2518,7 @@ void ipv6_mc_init_dev(struct inet6_dev *idev)
>  			(unsigned long)idev);
>  	setup_timer(&idev->mc_dad_timer, mld_dad_timer_expire,
>  		    (unsigned long)idev);
> -
> -	idev->mc_qrv = MLD_QRV_DEFAULT;
> -	idev->mc_qi = MLD_QI_DEFAULT;
> -	idev->mc_qri = MLD_QRI_DEFAULT;
> -
> -	idev->mc_maxdelay = unsolicited_report_interval(idev);
> -	idev->mc_v1_seen = 0;
> +	ipv6_mc_reset(idev);
>  	write_unlock_bh(&idev->lock);
>  }
>  
> diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
> index 0c56c93..c5c10fa 100644
> --- a/net/ipv6/sysctl_net_ipv6.c
> +++ b/net/ipv6/sysctl_net_ipv6.c
> @@ -16,6 +16,8 @@
>  #include <net/addrconf.h>
>  #include <net/inet_frag.h>
>  
> +static int one = 1;
> +

Why not stick the minimum to '2' as defined in the RFC?

It would be nice to use something more descriptive:
static int min_mlq_qrv = 1;

Perhaps also limit the maximum to avoid accidents?

fbl

>  static struct ctl_table ipv6_table_template[] = {
>  	{
>  		.procname	= "bindv6only",
> @@ -63,6 +65,14 @@ static struct ctl_table ipv6_rotable[] = {
>  		.mode		= 0644,
>  		.proc_handler	= proc_dointvec
>  	},
> +	{
> +		.procname	= "mld_qrv",
> +		.data		= &sysctl_mld_qrv,
> +		.maxlen		= sizeof(int),
> +		.mode		= 0644,
> +		.proc_handler	= proc_dointvec_minmax,
> +		.extra1		= &one
> +	},
>  	{ }
>  };
>  
> -- 
> 1.9.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* Re: RTNL: assertion failed at net/ipv6/addrconf.c (1699)
From: Hannes Frederic Sowa @ 2014-09-01 19:22 UTC (permalink / raw)
  To: Sabrina Dubroca
  Cc: Cong Wang, Tommi Rantala, David S. Miller, Alexey Kuznetsov,
	James Morris, Hideaki YOSHIFUJI, Patrick McHardy, netdev, LKML,
	trinity, Dave Jones
In-Reply-To: <20140830105821.GB18155@kria>

Hi,

On Sa, 2014-08-30 at 12:58 +0200, Sabrina Dubroca wrote:
> 2014-08-30, 03:51:29 +0200, Hannes Frederic Sowa wrote:
> > Hi Sabrina,
> > 
> > [...]
> > 
> > Sorry, just had time to look at this.
> > 
> > The reason is not to have list corruption but that the calls down to
> > ndo_set_rx_mode expect rtnl to be locked by the drivers. Filter lists
> > are locked by addr_list_lock and that's why I think we never saw any
> > problems with that, but drivers expect rtnl locked for those calls.
> > 
> > But this problem also affects multicast join, so patch seems incomplete
> > to me (and for that matter ssm multicast join, too).
> > 
> > Also rtnl_lock and rcu_read_lock compose in that order, so we don't need
> > to change dev_get_by_flags, but as this is the only user it sure is
> > possible. RCU locked version is just easier composeable, so I wouldn't
> > touch that if needed in future, just also take rcu lock as before.
> > 
> > So just adding rtnl_lock add appropriate places seems to be ok to me,
> > but still need to review parts of the ssm code.
> > 
> > Also we should move ASSERT_RTNL checks from addrconf_join_solict to
> > ipv6_dev_mc_inc/dec.
> > 
> > Thanks,
> > Hannes
> 
> Thanks for explaining.
> 
> I had a look at what you suggested.
> 
> 
> So, for anycast, on top of the previous patch, we'd have:
> 
> ---
> diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
> index 210183244689..61dd3046b804 100644
> --- a/net/ipv6/anycast.c
> +++ b/net/ipv6/anycast.c
>  static void aca_put(struct ifacaddr6 *ac)
> @@ -233,6 +235,8 @@ int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr)
>  	struct rt6_info *rt;
>  	int err;
>  
> +	ASSERT_RTNL();
> +
>  	idev = in6_dev_get(dev);
>  
>  	if (idev == NULL)
> @@ -302,6 +306,8 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr)
>  {
>  	struct ifacaddr6 *aca, *prev_aca;
>  
> +	ASSERT_RTNL();
> +
>  	write_lock_bh(&idev->lock);
>  	prev_aca = NULL;
>  	for (aca = idev->ac_list; aca; aca = aca->aca_next) {
> @@ -336,6 +342,8 @@ static int ipv6_dev_ac_dec(struct net_device *dev, const struct in6_addr *addr)
>  {
>  	struct inet6_dev *idev = __in6_dev_get(dev);
>  
> +	ASSERT_RTNL();
> +
>  	if (idev == NULL)
>  		return -ENODEV;
>  	return __ipv6_dev_ac_dec(idev, addr);

ASSERT_RTNL() still performs a runtime check. While those are not really
fast paths, I still think it is better to keep them to a minimum and
place them only at places where we know all code which needs to be
guarded passes by:

I would suggest to move ASSERT_RTNL to ipv6_dev_mc_inc and
__ipv6_dev_mc_dec and even remove the checks from addrconf_join_solict
and addrconf_leave_solict. Does that cover all code paths and makes
sense?

> ---
> 
> 
> And for multicast:
>  - locking order in the patch below: rtnl -> rcu -> ipv6_sk_mc_lock
>  - ipv6_sock_mc_join: maybe move all the _unlock()'s together at the end of the function
>  - do we need to modify rcu_dereference_protected in ipv6_sock_mc_drop/ipv6_sock_mc_close
>  - I had a look at the other codepaths that call ipv6_dev_mc_inc/dec
>    - ipv6_mc_destroy_dev, dev_forward_change, ipv6_add_dev,
>      addrconf_join_solict -- all take rtnl or already have an
>      ASSERT_RTNL()
>    - pndisc_destructor, called from pneigh_ifdown/pneigh_delete
>    - pndisc_constructor, called from pneigh_lookup -- pneigh_lookup
>      has ASSERT_RTNL(), but pneigh_lookup is called from ip6_forward and
>      ndisc_recv_na
>    - (hope I didn't miss any callers)
> 
> As far as I could see, apart maybe from pndisc_constructor, it seems
> okay, but I'd like to hear your comments.

The rest of the patch looks good.

Can you or Cong post a final patch with the adapted ac_join/drop
changes?

Thanks,
Hannes

^ permalink raw reply

* Re: [PATCH net-next 1/2] ipv6: add sysctl_mld_qrv to configure query robustness variable
From: Hannes Frederic Sowa @ 2014-09-01 19:41 UTC (permalink / raw)
  To: Flavio Leitner; +Cc: netdev
In-Reply-To: <20140901180806.GA2779@t520.home>

Hi Flavio,

On Mo, 2014-09-01 at 15:08 -0300, Flavio Leitner wrote:
> On Sat, Aug 30, 2014 at 04:42:53AM +0200, Hannes Frederic Sowa wrote:
> > This patch adds a new sysctl_mld_qrv knob to configure the mldv1/v2 query
> > robustness variable. It sepcifies how many retransmit of unsolicited mld
>                           ^^^^^^^^^
> typo

Thanks, will fix it up in the next version.

> > retransmit should happen. Admins might want to tune this on lossy links.
> > 
> > Also reset mld state on interface down/up, so we pick up new sysctl
> > settings during interface up event.
> > 
> > IPv6 certification requests this knob to be available.
> > 
> > I didn't make this knob netns specific, as it is mostly a setting in a
> > physical environment and should be per host.
> > 
> > Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
> > ---
> >  Documentation/networking/ip-sysctl.txt |  3 +++
> >  include/net/ipv6.h                     |  1 +
> >  net/ipv6/mcast.c                       | 20 ++++++++++++--------
> >  net/ipv6/sysctl_net_ipv6.c             | 10 ++++++++++
> >  4 files changed, 26 insertions(+), 8 deletions(-)
> > 
> > diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
> > index 3cce8ea..b7fe844 100644
> > --- a/Documentation/networking/ip-sysctl.txt
> > +++ b/Documentation/networking/ip-sysctl.txt
> > @@ -1152,6 +1152,9 @@ anycast_src_echo_reply - BOOLEAN
> >  	FALSE: disabled
> >  	Default: FALSE
> >  
> > +mld_qrv - INTEGER
> > +	Controls the MLD query robustness variable (see RFC3810 9.1).
> > +
> >  IPv6 Fragmentation:
> >  
> >  ip6frag_high_thresh - INTEGER
> > diff --git a/include/net/ipv6.h b/include/net/ipv6.h
> > index a2db816..7e247e9 100644
> > --- a/include/net/ipv6.h
> > +++ b/include/net/ipv6.h
> > @@ -121,6 +121,7 @@ struct frag_hdr {
> >  
> >  /* sysctls */
> >  extern int sysctl_mld_max_msf;
> > +extern int sysctl_mld_qrv;
> >  
> >  #define _DEVINC(net, statname, modifier, idev, field)			\
> >  ({									\
> > diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
> > index 7088179..6efb0e5 100644
> > --- a/net/ipv6/mcast.c
> > +++ b/net/ipv6/mcast.c
> > @@ -121,6 +121,7 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
> >  #define IPV6_MLD_MAX_MSF	64
> >  
> >  int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF;
> > +int sysctl_mld_qrv __read_mostly = MLD_QRV_DEFAULT;
> >  
> >  /*
> >   *	socket join on multicast group
> > @@ -1196,7 +1197,7 @@ static void mld_update_qrv(struct inet6_dev *idev,
> >  	if (mlh2->mld2q_qrv > 0)
> >  		idev->mc_qrv = mlh2->mld2q_qrv;
> >  
> > -	if (unlikely(idev->mc_qrv < 2)) {
> > +	if (unlikely(idev->mc_qrv < MLD_QRV_DEFAULT)) {
> >  		net_warn_ratelimited("IPv6: MLD: clamping QRV from %u to %u!\n",
> >  				     idev->mc_qrv, MLD_QRV_DEFAULT);
> >  		idev->mc_qrv = MLD_QRV_DEFAULT;
> > @@ -2478,6 +2479,14 @@ void ipv6_mc_down(struct inet6_dev *idev)
> >  	mld_clear_delrec(idev);
> >  }
> >  
> > +static void ipv6_mc_reset(struct inet6_dev *idev)
> > +{
> > +	idev->mc_qrv = sysctl_mld_qrv;
> > +	idev->mc_qi = MLD_QI_DEFAULT;
> > +	idev->mc_qri = MLD_QRI_DEFAULT;
> > +	idev->mc_v1_seen = 0;
> > +	idev->mc_maxdelay = unsolicited_report_interval(idev);
> > +}
> >  
> >  /* Device going up */
> >  
> > @@ -2488,6 +2497,7 @@ void ipv6_mc_up(struct inet6_dev *idev)
> >  	/* Install multicast list, except for all-nodes (already installed) */
> >  
> >  	read_lock_bh(&idev->lock);
> > +	ipv6_mc_reset(idev);
> >  	for (i = idev->mc_list; i; i = i->next)
> >  		igmp6_group_added(i);
> >  	read_unlock_bh(&idev->lock);
> > @@ -2508,13 +2518,7 @@ void ipv6_mc_init_dev(struct inet6_dev *idev)
> >  			(unsigned long)idev);
> >  	setup_timer(&idev->mc_dad_timer, mld_dad_timer_expire,
> >  		    (unsigned long)idev);
> > -
> > -	idev->mc_qrv = MLD_QRV_DEFAULT;
> > -	idev->mc_qi = MLD_QI_DEFAULT;
> > -	idev->mc_qri = MLD_QRI_DEFAULT;
> > -
> > -	idev->mc_maxdelay = unsolicited_report_interval(idev);
> > -	idev->mc_v1_seen = 0;
> > +	ipv6_mc_reset(idev);
> >  	write_unlock_bh(&idev->lock);
> >  }
> >  
> > diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
> > index 0c56c93..c5c10fa 100644
> > --- a/net/ipv6/sysctl_net_ipv6.c
> > +++ b/net/ipv6/sysctl_net_ipv6.c
> > @@ -16,6 +16,8 @@
> >  #include <net/addrconf.h>
> >  #include <net/inet_frag.h>
> >  
> > +static int one = 1;
> > +
> 
> Why not stick the minimum to '2' as defined in the RFC?

I did so in the first place, but while googling around there are also
some RFCs suggesting to reduce QRV to 1:
http://tools.ietf.org/html/rfc6636#section-4.5

> 
> It would be nice to use something more descriptive:
> static int min_mlq_qrv = 1;

By just calling it one this variable is reusable for other
proc_dointvec_minmax users, see e.g. sysctl_net_ipv4.c. I used the same
style for ipv6.

> Perhaps also limit the maximum to avoid accidents?

I thought so, too, but in the end decided against that. There is no
upper limit specified by any of the RFCs, the maximum setting does not
kill the box and just transmits the reports with randomized time
intervals in between until the first igmp queries stop the timer, so I
decided to just leave it alone.

I just saw a problem in the IPv4 version of the patch, as it breaks
compilation with CONFIG_IP_MULTICAST disabled, will send new versions
soon.

Thanks for the review,
Hannes

^ permalink raw reply

* [PATCH 2/2] ipv4: implement igmp_qrv sysctl to tune igmp robustness variable
From: Hannes Frederic Sowa @ 2014-09-01 19:55 UTC (permalink / raw)
  To: netdev; +Cc: Flavio Leitner
In-Reply-To: <aa72acbd19015e6db6b2d425fb6ebf6a8fa9c3b5.1409601046.git.hannes@stressinduktion.org>

As in IPv6 people might increase the igmp query robustness variable to
make sure unsolicited state change reports aren't lost on the network. Add
and document this new knob to igmp code.

RFCs allow tuning this parameter back to first IGMP RFC, so we also use
this setting for all counters, including source specific multicast.

Also take over sysctl value when upping the interface and don't reuse
the last one seen on the interface.

Cc: Flavio Leitner <fbl@redhat.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
v2) Guard sysctl_igmp_qrv with CONFIG_IP_MULTICAST so we don't use
    IGMP_Query_Robustness_Variable without it being defined.

 Documentation/networking/ip-sysctl.txt |  3 +++
 include/linux/igmp.h                   |  1 +
 net/ipv4/igmp.c                        | 31 +++++++++++++++----------------
 net/ipv4/sysctl_net_ipv4.c             | 10 ++++++++++
 4 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index b7fe844..a5adddc 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -844,6 +844,9 @@ igmp_max_memberships - INTEGER
 
 	conf/all/*	  is special, changes the settings for all interfaces
 
+igmp_qrv - INTEGER
+	 Controls the IGMP query robustness variable (see RFC2236 8.1).
+
 log_martians - BOOLEAN
 	Log packets with impossible addresses to kernel log.
 	log_martians for the interface will be enabled if at least one of
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
index f47550d..2c677af 100644
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -39,6 +39,7 @@ static inline struct igmpv3_query *
 
 extern int sysctl_igmp_max_memberships;
 extern int sysctl_igmp_max_msf;
+extern int sysctl_igmp_qrv;
 
 struct ip_sf_socklist {
 	unsigned int		sl_max;
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 890c425..4146153 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -117,7 +117,7 @@
 #define IGMP_V2_Unsolicited_Report_Interval	(10*HZ)
 #define IGMP_V3_Unsolicited_Report_Interval	(1*HZ)
 #define IGMP_Query_Response_Interval		(10*HZ)
-#define IGMP_Unsolicited_Report_Count		2
+#define IGMP_Query_Robustness_Variable		2
 
 
 #define IGMP_Initial_Report_Delay		(1)
@@ -756,8 +756,7 @@ static void igmp_ifc_event(struct in_device *in_dev)
 {
 	if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev))
 		return;
-	in_dev->mr_ifc_count = in_dev->mr_qrv ? in_dev->mr_qrv :
-		IGMP_Unsolicited_Report_Count;
+	in_dev->mr_ifc_count = in_dev->mr_qrv ?: sysctl_igmp_qrv;
 	igmp_ifc_start_timer(in_dev, 1);
 }
 
@@ -1086,8 +1085,7 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im)
 	pmc->interface = im->interface;
 	in_dev_hold(in_dev);
 	pmc->multiaddr = im->multiaddr;
-	pmc->crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
-		IGMP_Unsolicited_Report_Count;
+	pmc->crcount = in_dev->mr_qrv ?: sysctl_igmp_qrv;
 	pmc->sfmode = im->sfmode;
 	if (pmc->sfmode == MCAST_INCLUDE) {
 		struct ip_sf_list *psf;
@@ -1226,8 +1224,7 @@ static void igmp_group_added(struct ip_mc_list *im)
 	}
 	/* else, v3 */
 
-	im->crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
-		IGMP_Unsolicited_Report_Count;
+	im->crcount = in_dev->mr_qrv ?: sysctl_igmp_qrv;
 	igmp_ifc_event(in_dev);
 #endif
 }
@@ -1322,7 +1319,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
 	spin_lock_init(&im->lock);
 #ifdef CONFIG_IP_MULTICAST
 	setup_timer(&im->timer, igmp_timer_expire, (unsigned long)im);
-	im->unsolicit_count = IGMP_Unsolicited_Report_Count;
+	im->unsolicit_count = sysctl_igmp_qrv;
 #endif
 
 	im->next_rcu = in_dev->mc_list;
@@ -1460,7 +1457,7 @@ void ip_mc_init_dev(struct in_device *in_dev)
 			(unsigned long)in_dev);
 	setup_timer(&in_dev->mr_ifc_timer, igmp_ifc_timer_expire,
 			(unsigned long)in_dev);
-	in_dev->mr_qrv = IGMP_Unsolicited_Report_Count;
+	in_dev->mr_qrv = sysctl_igmp_qrv;
 #endif
 
 	spin_lock_init(&in_dev->mc_tomb_lock);
@@ -1474,6 +1471,9 @@ void ip_mc_up(struct in_device *in_dev)
 
 	ASSERT_RTNL();
 
+#ifdef CONFIG_IP_MULTICAST
+	in_dev->mr_qrv = sysctl_igmp_qrv;
+#endif
 	ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS);
 
 	for_each_pmc_rtnl(in_dev, pmc)
@@ -1540,7 +1540,9 @@ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr)
  */
 int sysctl_igmp_max_memberships __read_mostly = IP_MAX_MEMBERSHIPS;
 int sysctl_igmp_max_msf __read_mostly = IP_MAX_MSF;
-
+#ifdef CONFIG_IP_MULTICAST
+int sysctl_igmp_qrv __read_mostly = IGMP_Query_Robustness_Variable;
+#endif
 
 static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
 	__be32 *psfsrc)
@@ -1575,8 +1577,7 @@ static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
 #ifdef CONFIG_IP_MULTICAST
 		if (psf->sf_oldin &&
 		    !IGMP_V1_SEEN(in_dev) && !IGMP_V2_SEEN(in_dev)) {
-			psf->sf_crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
-				IGMP_Unsolicited_Report_Count;
+			psf->sf_crcount = in_dev->mr_qrv ?: sysctl_igmp_qrv;
 			psf->sf_next = pmc->tomb;
 			pmc->tomb = psf;
 			rv = 1;
@@ -1639,8 +1640,7 @@ static int ip_mc_del_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
 		/* filter mode change */
 		pmc->sfmode = MCAST_INCLUDE;
 #ifdef CONFIG_IP_MULTICAST
-		pmc->crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
-			IGMP_Unsolicited_Report_Count;
+		pmc->crcount = in_dev->mr_qrv ?: sysctl_igmp_qrv;
 		in_dev->mr_ifc_count = pmc->crcount;
 		for (psf = pmc->sources; psf; psf = psf->sf_next)
 			psf->sf_crcount = 0;
@@ -1818,8 +1818,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
 #ifdef CONFIG_IP_MULTICAST
 		/* else no filters; keep old mode for reports */
 
-		pmc->crcount = in_dev->mr_qrv ? in_dev->mr_qrv :
-			IGMP_Unsolicited_Report_Count;
+		pmc->crcount = in_dev->mr_qrv ?: sysctl_igmp_qrv;
 		in_dev->mr_ifc_count = pmc->crcount;
 		for (psf = pmc->sources; psf; psf = psf->sf_next)
 			psf->sf_crcount = 0;
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 79a007c..45d156d 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -450,6 +450,16 @@ static struct ctl_table ipv4_table[] = {
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec
 	},
+#ifdef CONFIG_IP_MULTICAST
+	{
+		.procname	= "igmp_qrv",
+		.data		= &sysctl_igmp_qrv,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &one
+	},
+#endif
 	{
 		.procname	= "inet_peer_threshold",
 		.data		= &inet_peer_threshold,
-- 
1.9.3

^ permalink raw reply related

* [PATCH 1/2] ipv6: add sysctl_mld_qrv to configure query robustness variable
From: Hannes Frederic Sowa @ 2014-09-01 19:55 UTC (permalink / raw)
  To: netdev; +Cc: Flavio Leitner

This patch adds a new sysctl_mld_qrv knob to configure the mldv1/v2 query
robustness variable. It specifies how many retransmit of unsolicited mld
retransmit should happen. Admins might want to tune this on lossy links.

Also reset mld state on interface down/up, so we pick up new sysctl
settings during interface up event.

IPv6 certification requests this knob to be available.

I didn't make this knob netns specific, as it is mostly a setting in a
physical environment and should be per host.

Cc: Flavio Leitner <fbl@redhat.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
v2) no changes to original version

 Documentation/networking/ip-sysctl.txt |  3 +++
 include/net/ipv6.h                     |  1 +
 net/ipv6/mcast.c                       | 20 ++++++++++++--------
 net/ipv6/sysctl_net_ipv6.c             | 10 ++++++++++
 4 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 3cce8ea..b7fe844 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1152,6 +1152,9 @@ anycast_src_echo_reply - BOOLEAN
 	FALSE: disabled
 	Default: FALSE
 
+mld_qrv - INTEGER
+	Controls the MLD query robustness variable (see RFC3810 9.1).
+
 IPv6 Fragmentation:
 
 ip6frag_high_thresh - INTEGER
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index a2db816..7e247e9 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -121,6 +121,7 @@ struct frag_hdr {
 
 /* sysctls */
 extern int sysctl_mld_max_msf;
+extern int sysctl_mld_qrv;
 
 #define _DEVINC(net, statname, modifier, idev, field)			\
 ({									\
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 7088179..6efb0e5 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -121,6 +121,7 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
 #define IPV6_MLD_MAX_MSF	64
 
 int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF;
+int sysctl_mld_qrv __read_mostly = MLD_QRV_DEFAULT;
 
 /*
  *	socket join on multicast group
@@ -1196,7 +1197,7 @@ static void mld_update_qrv(struct inet6_dev *idev,
 	if (mlh2->mld2q_qrv > 0)
 		idev->mc_qrv = mlh2->mld2q_qrv;
 
-	if (unlikely(idev->mc_qrv < 2)) {
+	if (unlikely(idev->mc_qrv < MLD_QRV_DEFAULT)) {
 		net_warn_ratelimited("IPv6: MLD: clamping QRV from %u to %u!\n",
 				     idev->mc_qrv, MLD_QRV_DEFAULT);
 		idev->mc_qrv = MLD_QRV_DEFAULT;
@@ -2478,6 +2479,14 @@ void ipv6_mc_down(struct inet6_dev *idev)
 	mld_clear_delrec(idev);
 }
 
+static void ipv6_mc_reset(struct inet6_dev *idev)
+{
+	idev->mc_qrv = sysctl_mld_qrv;
+	idev->mc_qi = MLD_QI_DEFAULT;
+	idev->mc_qri = MLD_QRI_DEFAULT;
+	idev->mc_v1_seen = 0;
+	idev->mc_maxdelay = unsolicited_report_interval(idev);
+}
 
 /* Device going up */
 
@@ -2488,6 +2497,7 @@ void ipv6_mc_up(struct inet6_dev *idev)
 	/* Install multicast list, except for all-nodes (already installed) */
 
 	read_lock_bh(&idev->lock);
+	ipv6_mc_reset(idev);
 	for (i = idev->mc_list; i; i = i->next)
 		igmp6_group_added(i);
 	read_unlock_bh(&idev->lock);
@@ -2508,13 +2518,7 @@ void ipv6_mc_init_dev(struct inet6_dev *idev)
 			(unsigned long)idev);
 	setup_timer(&idev->mc_dad_timer, mld_dad_timer_expire,
 		    (unsigned long)idev);
-
-	idev->mc_qrv = MLD_QRV_DEFAULT;
-	idev->mc_qi = MLD_QI_DEFAULT;
-	idev->mc_qri = MLD_QRI_DEFAULT;
-
-	idev->mc_maxdelay = unsolicited_report_interval(idev);
-	idev->mc_v1_seen = 0;
+	ipv6_mc_reset(idev);
 	write_unlock_bh(&idev->lock);
 }
 
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 0c56c93..c5c10fa 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -16,6 +16,8 @@
 #include <net/addrconf.h>
 #include <net/inet_frag.h>
 
+static int one = 1;
+
 static struct ctl_table ipv6_table_template[] = {
 	{
 		.procname	= "bindv6only",
@@ -63,6 +65,14 @@ static struct ctl_table ipv6_rotable[] = {
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec
 	},
+	{
+		.procname	= "mld_qrv",
+		.data		= &sysctl_mld_qrv,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &one
+	},
 	{ }
 };
 
-- 
1.9.3

^ permalink raw reply related

* Re: [PATCH 1/2] ipv6: add sysctl_mld_qrv to configure query robustness variable
From: Hannes Frederic Sowa @ 2014-09-01 19:57 UTC (permalink / raw)
  To: netdev; +Cc: Flavio Leitner
In-Reply-To: <aa72acbd19015e6db6b2d425fb6ebf6a8fa9c3b5.1409601046.git.hannes@stressinduktion.org>

On Mo, 2014-09-01 at 21:55 +0200, Hannes Frederic Sowa wrote:
> Subject: [PATCH 1/2] ipv6: add sysctl_mld_qrv to configure query robustness variable

Sorry, both patches "net-next v2" of course. I was Ctrl-R'ing too fast. ;)

Bye,
Hannes

^ permalink raw reply

* Re: [PATCH 0/2] Get rid of ndo_xmit_flush
From: Hannes Frederic Sowa @ 2014-09-01 20:05 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, therbert, jhs, edumazet, jeffrey.t.kirsher, rusty,
	dborkman, brouer, john.r.fastabend
In-Reply-To: <20140829.202210.1424256004723217664.davem@davemloft.net>

On Fr, 2014-08-29 at 20:22 -0700, David Miller wrote:
> From: Hannes Frederic Sowa <hannes@stressinduktion.org>
> Date: Thu, 28 Aug 2014 03:42:54 +0200
> 
> > I wonder if we still might need a separate call for tx_flush, e.g. for
> > af_packet if one wants to allow user space control of batching, MSG_MORE
> > with tx hangcheck (also in case user space has control over it) or
> > implement TCP_CORK alike option in af_packet.
> 
> I disagree with allowing the user to hold a device TX queue hostage
> across system calls, therefore the user should provide the entire
> batch in such a case.

Ok, granted. In regards to syscall latency this also is a stupid idea.
mmaped tx approaches won't even pass these functions, so we don't care
here.

But as soon as we try to make Qdiscs absolutely lockless, we don't have
any guard that we don't concurrently dequeue skbs from it and suddenly
one Qdisc dequeue processing entity couldn't notify the driver that the
end of the batching was reached. I think this could become a problem
depending on how much of the locking is removed?

Bye,
Hannes

^ permalink raw reply

* Re: [patch net-next RFC 10/12] openvswitch: add support for datapath hardware offload
From: Jiri Pirko @ 2014-09-01 20:28 UTC (permalink / raw)
  To: Jamal Hadi Salim
  Cc: Simon Horman, Thomas Graf, Alexei Starovoitov, Andy Gospodarek,
	Roopa Prabhu, John Fastabend, Scott Feldman, netdev, David Miller,
	Neil Horman, Andy Gospodarek, dborkman, ogerlitz, Jesse Gross,
	Pravin Shelar, Andy Zhou, ben, Stephen Hemminger,
	jeffrey.t.kirsher, vyasevic, Cong Wang, john.r.fastabend,
	Eric Dumazet, Florian Fainelli, John 
In-Reply-To: <5404A0B1.1030009@mojatatu.com>

Mon, Sep 01, 2014 at 06:37:05PM CEST, jhs@mojatatu.com wrote:
>On 09/01/14 04:13, Simon Horman wrote:
>>On Fri, Aug 29, 2014 at 10:20:55AM -0400, Jamal Hadi Salim wrote:
>
>>>I actually have no issues with whatever classifier someone decides
>>>to use. To each their poison. But I do take issue mandating the
>>>specified classifer it as THE CLASSIFIER as in this case,
>>>is where i start taking issue. I have a few things that i offload
>>>to hardware with speacilized classifiers such that i object strongly
>>>to the approach this driver has taken.
>>
>>My reading of this thread is that allowing different classifiers
>>is not under dispute.
>
>
>I am not sure how you reached that conclusion by reading this thread;->
>But i would be glad if that was the conclusion and i missed it.

Jamal, please be ensured that no one I know of is against future
different classifiers.

^ permalink raw reply

* [PATCH] ipv6: fix rtnl locking in setsockopt for anycast and multicast
From: Sabrina Dubroca @ 2014-09-01 21:05 UTC (permalink / raw)
  To: Hannes Frederic Sowa
  Cc: Cong Wang, Tommi Rantala, David S. Miller, Alexey Kuznetsov,
	James Morris, Hideaki YOSHIFUJI, Patrick McHardy, netdev, LKML,
	trinity, Dave Jones
In-Reply-To: <1409599348.21965.6.camel@localhost>

Calling setsockopt with IPV6_JOIN_ANYCAST or IPV6_LEAVE_ANYCAST
triggers the assertion in addrconf_join_solict()/addrconf_leave_solict()

ipv6_sock_ac_join(), ipv6_sock_ac_drop(), ipv6_sock_ac_close() need to
take RTNL before calling ipv6_dev_ac_inc/dec. Same thing with
ipv6_sock_mc_join(), ipv6_sock_mc_drop(), ipv6_sock_mc_close() before
calling ipv6_dev_mc_inc/dec.

This patch moves ASSERT_RTNL() up a level in the call stack.

Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reported-by: Tommi Rantala <tt.rantala@gmail.com>
---
I included Cong's Signed-off-by for the first part of the patch,
I hope that's OK.

This patch is based on -next, but since the assertion can also be
triggered on a current kernel (tested on a 3.16), I think it should
also go in stable.

 include/linux/netdevice.h |  4 ++--
 net/core/dev.c            | 11 ++++++-----
 net/ipv6/addrconf.c       | 15 +++++----------
 net/ipv6/anycast.c        | 30 +++++++++++++++++++-----------
 net/ipv6/mcast.c          | 16 ++++++++++++++++
 5 files changed, 48 insertions(+), 28 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 429801370d0c..1ae0e745b1b1 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2077,8 +2077,8 @@ void __dev_remove_pack(struct packet_type *pt);
 void dev_add_offload(struct packet_offload *po);
 void dev_remove_offload(struct packet_offload *po);
 
-struct net_device *dev_get_by_flags_rcu(struct net *net, unsigned short flags,
-					unsigned short mask);
+struct net_device *dev_get_by_flags(struct net *net, unsigned short flags,
+				    unsigned short mask);
 struct net_device *dev_get_by_name(struct net *net, const char *name);
 struct net_device *dev_get_by_name_rcu(struct net *net, const char *name);
 struct net_device *__dev_get_by_name(struct net *net, const char *name);
diff --git a/net/core/dev.c b/net/core/dev.c
index 443b814db05b..8fede6ef4a39 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -897,23 +897,24 @@ struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type)
 EXPORT_SYMBOL(dev_getfirstbyhwtype);
 
 /**
- *	dev_get_by_flags_rcu - find any device with given flags
+ *	dev_get_by_flags - find any device with given flags
  *	@net: the applicable net namespace
  *	@if_flags: IFF_* values
  *	@mask: bitmask of bits in if_flags to check
  *
  *	Search for any interface with the given flags. Returns NULL if a device
  *	is not found or a pointer to the device. Must be called inside
- *	rcu_read_lock(), and result refcount is unchanged.
+ *	rtnl_lock(), and result refcount is unchanged.
  */
 
-struct net_device *dev_get_by_flags_rcu(struct net *net, unsigned short if_flags,
+struct net_device *dev_get_by_flags(struct net *net, unsigned short if_flags,
 				    unsigned short mask)
 {
 	struct net_device *dev, *ret;
 
+	ASSERT_RTNL();
 	ret = NULL;
-	for_each_netdev_rcu(net, dev) {
+	for_each_netdev(net, dev) {
 		if (((dev->flags ^ if_flags) & mask) == 0) {
 			ret = dev;
 			break;
@@ -921,7 +922,7 @@ struct net_device *dev_get_by_flags_rcu(struct net *net, unsigned short if_flags
 	}
 	return ret;
 }
-EXPORT_SYMBOL(dev_get_by_flags_rcu);
+EXPORT_SYMBOL(dev_get_by_flags);
 
 /**
  *	dev_valid_name - check if name is okay for network device
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 267ce3caee24..7ada65937d23 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1690,14 +1690,12 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
 	addrconf_mod_dad_work(ifp, 0);
 }
 
-/* Join to solicited addr multicast group. */
-
+/* Join to solicited addr multicast group.
+ * caller must hold RTNL */
 void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr)
 {
 	struct in6_addr maddr;
 
-	ASSERT_RTNL();
-
 	if (dev->flags&(IFF_LOOPBACK|IFF_NOARP))
 		return;
 
@@ -1705,12 +1703,11 @@ void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr)
 	ipv6_dev_mc_inc(dev, &maddr);
 }
 
+/* caller must hold RTNL */
 void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr)
 {
 	struct in6_addr maddr;
 
-	ASSERT_RTNL();
-
 	if (idev->dev->flags&(IFF_LOOPBACK|IFF_NOARP))
 		return;
 
@@ -1718,12 +1715,11 @@ void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr)
 	__ipv6_dev_mc_dec(idev, &maddr);
 }
 
+/* caller must hold RTNL */
 static void addrconf_join_anycast(struct inet6_ifaddr *ifp)
 {
 	struct in6_addr addr;
 
-	ASSERT_RTNL();
-
 	if (ifp->prefix_len >= 127) /* RFC 6164 */
 		return;
 	ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
@@ -1732,12 +1728,11 @@ static void addrconf_join_anycast(struct inet6_ifaddr *ifp)
 	ipv6_dev_ac_inc(ifp->idev->dev, &addr);
 }
 
+/* caller must hold RTNL */
 static void addrconf_leave_anycast(struct inet6_ifaddr *ifp)
 {
 	struct in6_addr addr;
 
-	ASSERT_RTNL();
-
 	if (ifp->prefix_len >= 127) /* RFC 6164 */
 		return;
 	ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 210183244689..572c2faede55 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -77,7 +77,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 	pac->acl_next = NULL;
 	pac->acl_addr = *addr;
 
-	rcu_read_lock();
+	rtnl_lock();
 	if (ifindex == 0) {
 		struct rt6_info *rt;
 
@@ -90,11 +90,11 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 			goto error;
 		} else {
 			/* router, no matching interface: just pick one */
-			dev = dev_get_by_flags_rcu(net, IFF_UP,
-						   IFF_UP | IFF_LOOPBACK);
+			dev = dev_get_by_flags(net, IFF_UP,
+					       IFF_UP | IFF_LOOPBACK);
 		}
 	} else
-		dev = dev_get_by_index_rcu(net, ifindex);
+		dev = __dev_get_by_index(net, ifindex);
 
 	if (dev == NULL) {
 		err = -ENODEV;
@@ -136,7 +136,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 	}
 
 error:
-	rcu_read_unlock();
+	rtnl_unlock();
 	if (pac)
 		sock_kfree_s(sk, pac, sizeof(*pac));
 	return err;
@@ -171,13 +171,15 @@ int ipv6_sock_ac_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
 
 	spin_unlock_bh(&ipv6_sk_ac_lock);
 
-	rcu_read_lock();
-	dev = dev_get_by_index_rcu(net, pac->acl_ifindex);
+	rtnl_lock();
+	dev = __dev_get_by_index(net, pac->acl_ifindex);
 	if (dev)
 		ipv6_dev_ac_dec(dev, &pac->acl_addr);
-	rcu_read_unlock();
+	rtnl_unlock();
 
 	sock_kfree_s(sk, pac, sizeof(*pac));
+	if (!dev)
+		return -ENODEV;
 	return 0;
 }
 
@@ -198,12 +200,12 @@ void ipv6_sock_ac_close(struct sock *sk)
 	spin_unlock_bh(&ipv6_sk_ac_lock);
 
 	prev_index = 0;
-	rcu_read_lock();
+	rtnl_lock();
 	while (pac) {
 		struct ipv6_ac_socklist *next = pac->acl_next;
 
 		if (pac->acl_ifindex != prev_index) {
-			dev = dev_get_by_index_rcu(net, pac->acl_ifindex);
+			dev = __dev_get_by_index(net, pac->acl_ifindex);
 			prev_index = pac->acl_ifindex;
 		}
 		if (dev)
@@ -211,7 +213,7 @@ void ipv6_sock_ac_close(struct sock *sk)
 		sock_kfree_s(sk, pac, sizeof(*pac));
 		pac = next;
 	}
-	rcu_read_unlock();
+	rtnl_unlock();
 }
 
 static void aca_put(struct ifacaddr6 *ac)
@@ -233,6 +235,8 @@ int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr)
 	struct rt6_info *rt;
 	int err;
 
+	ASSERT_RTNL();
+
 	idev = in6_dev_get(dev);
 
 	if (idev == NULL)
@@ -302,6 +306,8 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr)
 {
 	struct ifacaddr6 *aca, *prev_aca;
 
+	ASSERT_RTNL();
+
 	write_lock_bh(&idev->lock);
 	prev_aca = NULL;
 	for (aca = idev->ac_list; aca; aca = aca->aca_next) {
@@ -336,6 +342,8 @@ static int ipv6_dev_ac_dec(struct net_device *dev, const struct in6_addr *addr)
 {
 	struct inet6_dev *idev = __in6_dev_get(dev);
 
+	ASSERT_RTNL();
+
 	if (idev == NULL)
 		return -ENODEV;
 	return __ipv6_dev_ac_dec(idev, addr);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 70881795da96..d73ac1ef65f2 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -172,6 +172,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 	mc_lst->next = NULL;
 	mc_lst->addr = *addr;
 
+	rtnl_lock();
 	rcu_read_lock();
 	if (ifindex == 0) {
 		struct rt6_info *rt;
@@ -185,6 +186,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 
 	if (dev == NULL) {
 		rcu_read_unlock();
+		rtnl_unlock();
 		sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
 		return -ENODEV;
 	}
@@ -202,6 +204,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 
 	if (err) {
 		rcu_read_unlock();
+		rtnl_unlock();
 		sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
 		return err;
 	}
@@ -212,6 +215,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 	spin_unlock(&ipv6_sk_mc_lock);
 
 	rcu_read_unlock();
+	rtnl_unlock();
 
 	return 0;
 }
@@ -229,6 +233,7 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
 	if (!ipv6_addr_is_multicast(addr))
 		return -EINVAL;
 
+	rtnl_lock();
 	spin_lock(&ipv6_sk_mc_lock);
 	for (lnk = &np->ipv6_mc_list;
 	     (mc_lst = rcu_dereference_protected(*lnk,
@@ -252,12 +257,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
 			} else
 				(void) ip6_mc_leave_src(sk, mc_lst, NULL);
 			rcu_read_unlock();
+			rtnl_unlock();
+
 			atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc);
 			kfree_rcu(mc_lst, rcu);
 			return 0;
 		}
 	}
 	spin_unlock(&ipv6_sk_mc_lock);
+	rtnl_unlock();
 
 	return -EADDRNOTAVAIL;
 }
@@ -302,6 +310,7 @@ void ipv6_sock_mc_close(struct sock *sk)
 	if (!rcu_access_pointer(np->ipv6_mc_list))
 		return;
 
+	rtnl_lock();
 	spin_lock(&ipv6_sk_mc_lock);
 	while ((mc_lst = rcu_dereference_protected(np->ipv6_mc_list,
 				lockdep_is_held(&ipv6_sk_mc_lock))) != NULL) {
@@ -328,6 +337,7 @@ void ipv6_sock_mc_close(struct sock *sk)
 		spin_lock(&ipv6_sk_mc_lock);
 	}
 	spin_unlock(&ipv6_sk_mc_lock);
+	rtnl_unlock();
 }
 
 int ip6_mc_source(int add, int omode, struct sock *sk,
@@ -845,6 +855,8 @@ int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr)
 	struct ifmcaddr6 *mc;
 	struct inet6_dev *idev;
 
+	ASSERT_RTNL();
+
 	/* we need to take a reference on idev */
 	idev = in6_dev_get(dev);
 
@@ -916,6 +928,8 @@ int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr)
 {
 	struct ifmcaddr6 *ma, **map;
 
+	ASSERT_RTNL();
+
 	write_lock_bh(&idev->lock);
 	for (map = &idev->mc_list; (ma = *map) != NULL; map = &ma->next) {
 		if (ipv6_addr_equal(&ma->mca_addr, addr)) {
@@ -942,6 +956,8 @@ int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr)
 	struct inet6_dev *idev;
 	int err;
 
+	ASSERT_RTNL();
+
 	rcu_read_lock();
 
 	idev = __in6_dev_get(dev);
-- 
2.1.0

^ permalink raw reply related

* Re: [PATCH net-next] sock: consistent errqueue errors and signals
From: Hannes Frederic Sowa @ 2014-09-01 21:25 UTC (permalink / raw)
  To: Willem de Bruijn; +Cc: netdev, davem
In-Reply-To: <1409534896-372-1-git-send-email-willemb@google.com>

On So, 2014-08-31 at 21:28 -0400, Willem de Bruijn wrote:
> When a socket error is pending, send()/recv() must abort their normal
> operation and return the error. An error means having non-zero
> sk->sk_err or having non-empty sk->sk_error_queue.
> 
> Currently, the behavior for the second is inconsistent depending on
> whether an error has previously been dequeued. In all cases,
> recv()/send() test sk->sk_err. This is not modified on enqueue onto
> the error queue, so may be 0. It is modified on dequeue, however, to
> match the queued skb's errno. I observed the following when two errors
> were queued:
> 
>   ret = poll(pollfd, 1, -1);
>   assert(ret == 1);
>   assert(pollfd.revents == POLLERR);
> 
>   ret = recv(fd, buf, size, MSG_NONBLOCK);
>   assert(ret == -1 && errno == EAGAIN);		/* <-- A */
> 
>   ret = recv(fd, buf, size, MSG_ERRQUEUE);
>   assert(ret > 0);
> 
>   ret = recv(fd, buf, size, MSG_NONBLOCK);
>   assert(ret == -1 && errno == ENOMSG);		/* <-- B */
> 
>   ret = recv(fd, buf, size, MSG_ERRQUEUE);
>   assert(ret > 0);
> 
> The recv call in B returns the error code embedded in
> SKB_EXT_ERR(skb), in this case ENOMSG, because I am working with
> timestamps. The recv call in A should have returned the
> same.
> 
> Implement this behavior. This may surprise existing applications.
> 
> Also make the wake-up signal when data is ready on the error queue
> consistent between enqueue and dequeue: use sk_error_report in both
> cases.
> 
> Signed-off-by: Willem de Bruijn <willemb@google.com>
> 
> ---
> 
> This approach leaves one issue:
> The states of sk->sk_err and sk->sk_error_queue are related, but only
> loosely. Error queue enqueue, dequeue and other code may overwrite
> sk->sk_err unconditionally. For one, sock_error will reset
> sk->sk_err to 0 even if sk->sk_error_queue is not empty. If socket
> calls should abort on all errors, then should be change to test
> sk_error_queue.qlen. But, doing so requires taking a lock in a busy
> data path.
> ---
>  net/core/skbuff.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index 163b673..f7a280b 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -3485,8 +3485,11 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
>  	skb_dst_force(skb);
>  
>  	skb_queue_tail(&sk->sk_error_queue, skb);
> +	sk->sk_err = SKB_EXT_ERR(skb)->ee.ee_errno;
> +
>  	if (!sock_flag(sk, SOCK_DEAD))
> -		sk->sk_data_ready(sk);
> +		sk->sk_error_report(sk);
> +
>  	return 0;
>  }
>  EXPORT_SYMBOL(sock_queue_err_skb);

>From my experience in IPv6 code, we only do sk->sk_err updates directly
in protocol error handling code. In case of UDP IPv6 errors for example
we now notify sk_error_report two times with this patch (before the
patch we did sk_data_ready (this is what you changed) and
sk_error_report).

I really wonder if setting sk->sk_err in this function is the right
thing to do. It also depends on socket state bits (e.g. np->recverr) if
the update happens. So we still cannot get rid of the protocol dependent
sk->sk_err updates.

It looks like we have to check all error handling functions in the
protocols. Maybe timestamp code needs to adapt?

Thanks,
Hannes

^ permalink raw reply

* Re: [PATCH 0/3] Basic deferred TX queue flushing infrastructure.
From: David Miller @ 2014-09-01 21:40 UTC (permalink / raw)
  To: brouer
  Cc: cwang, netdev, therbert, jhs, hannes, edumazet, jeffrey.t.kirsher,
	rusty
In-Reply-To: <20140901094032.5f0afdbd@redhat.com>

From: Jesper Dangaard Brouer <brouer@redhat.com>
Date: Mon, 1 Sep 2014 09:40:32 +0200

> 
> On Mon, 25 Aug 2014 15:31:46 -0700 (PDT) David Miller <davem@davemloft.net> wrote:
> 
>> It occurs to me that perhaps the thing to do is to pass sk_buff ** to
>> dev_hard_start_xmit().
> 
> Is this to send an array of skb's to dev_hard_start_xmit()?

It's one possible mechanism.

I have a patch set that rearchitects the send path here which I'll
post in a little bit, which takes a slightly different approach
based upon suggestions by Eric Dumazet and Tom Herbert.

^ permalink raw reply

* Re: [PATCH net] bnx2x: Configure device endianity on driver load and reset endianity on removal.
From: David Miller @ 2014-09-01 21:53 UTC (permalink / raw)
  To: manish.chopra; +Cc: netdev, Ariel.Elior, Yuval.Mintz
In-Reply-To: <31AFFC7280259C4184970ABA9AFE8B93E0800207@avmb3.qlogic.org>

From: Manish Chopra <manish.chopra@qlogic.com>
Date: Mon, 1 Sep 2014 15:33:20 +0000

>> -----Original Message-----
>> This patch fixes this case from both ends:
>> 1) Return endianity to original values on shutdown (in case little endian kernel
>> boots after we shutdown).
>> 2) Do not rely on HW reset values when loading driver in little endian kernel
>>    but configure them explicitly (in case previous kernel was big endian and did
>> not reset the HW).
 ...
> David, Please drop this patch as it might create issue for VFs.
> I will send updated V2 patch with proper fix. 

I think part #2 is the only reasonable part of this patch, and that's
what you'll have to backport to -stable kernels to sort this out
properly.

Adding "unconfiguration" hacks into a driver to deal with driver bugs
is really not kosher, sorry.

^ permalink raw reply

* Re: [PATCH 0/2] Get rid of ndo_xmit_flush
From: David Miller @ 2014-09-01 21:56 UTC (permalink / raw)
  To: hannes
  Cc: netdev, therbert, jhs, edumazet, jeffrey.t.kirsher, rusty,
	dborkman, brouer, john.r.fastabend
In-Reply-To: <1409601942.21965.23.camel@localhost>

From: Hannes Frederic Sowa <hannes@stressinduktion.org>
Date: Mon, 01 Sep 2014 22:05:42 +0200

> But as soon as we try to make Qdiscs absolutely lockless, we don't have
> any guard that we don't concurrently dequeue skbs from it and suddenly
> one Qdisc dequeue processing entity couldn't notify the driver that the
> end of the batching was reached. I think this could become a problem
> depending on how much of the locking is removed?

I am certain that batching will require taking the device transmit
lock over the ->ndo_start_xmit() invocations, and therefore the
deferral decisions must atomically be made inside of that context.

^ permalink raw reply

* [PATCH 0/9] Make dev_hard_start_xmit() work fundamentall on lists
From: David Miller @ 2014-09-01 22:24 UTC (permalink / raw)
  To: netdev


After this patch set, dev_hard_start_xmit() will work fundemantally
on any and all SKB lists.

This opens the path for a clean implementation of pulling multiple
packets out during qdisc_restart(), and then passing that blob
in one shot to dev_hard_start_xmit().

There were two main architectural blockers to this:

1) The GSO handling, we kept the original GSO head SKB around
   simply because dev_hard_start_xmit() had no way to communicate
   to the caller how far into the segmented list it was able to
   go.  Now it can, so the head GSO can be liberated immediately.

   All of the special GSO head SKB destructor et al. handling goes
   away too.

2) Validate of VLAN, CSUM, and segmentation characteristics was being
   performed inside of dev_hard_start_xmit().  If want to truly batch,
   we have to let the higher levels to this.  In particular, this is
   now dequeue_skb()'s job.

And with those two issues out of the way, it should now be trivial to
build experiments on top of this patch set, all of the framework
should be there now.  You could do something as simple as:

	skb = q->dequeue(q);
	if (skb)
		skb = validate_xmit_skb(skb, qdisc_dev(q));
	if (skb) {
		struct sk_buff *new, *head = skb;
		int limit = 5;

		do {
			new = q->dequeue(q);
			if (new)
				new = validate_xmit_skb(new, qdisc_dev(q));
			if (new) {
				skb->next = new;
				skb = new;
			}
		} while (new && --limit);
		skb = head;
	}

inside of the else branch of dequeue_skb().

Signed-off-by: David S. Miller <davem@davemloft.net>

^ permalink raw reply


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