Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH v2] PCI: Reprogram bridge prefetch registers on resume
From: Daniel Drake @ 2018-09-12  9:37 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Linux PCI, Linux Upstreaming Team, nouveau,
	Linux PM, Peter Wu, kherbst, Rafael Wysocki, Keith Busch,
	Mika Westerberg, Jon Derrick, Thomas Martitz, David Miller,
	Heiner Kallweit, netdev, nic_swsd, rchang
In-Reply-To: <CAJZ5v0j6VcFbO_R3fGLi2Ec1DmWsVA-0mzDG3LrA-3D5CrsPbw@mail.gmail.com>

On Wed, Sep 12, 2018 at 5:05 PM, Rafael J. Wysocki <rafael@kernel.org> wrote:
> Passing the extra bool around is somewhat clumsy, but I haven't found
> a cleaner way to do it, so

Thanks, according to your suggestion (which I plan to follow after
this) we will remove this parameter for v4.20+ and have all the
register writes be forced regardless of current value.

Daniel

^ permalink raw reply

* Re: [PATCH 00/25] Change tty_port(standard)_install's return type
From: Alan Cox @ 2018-09-12 14:41 UTC (permalink / raw)
  To: Jaejoong Kim
  Cc: linux-um, netdev, linux-mmc, linux-s390, devel, greybus-dev,
	linuxppc-dev, linux-serial, sparclinux, linux-usb,
	linux-bluetooth, linux-kernel, Greg Kroah-Hartman, Jiri Slaby
In-Reply-To: <1536029091-4426-1-git-send-email-climbbb.kim@gmail.com>

On Tue,  4 Sep 2018 11:44:26 +0900
Jaejoong Kim <climbbb.kim@gmail.com> wrote:

> Many drivers with tty use the tty_stand_install(). But, there is no
> need to handle the error, since it always returns 0.


And what happens if another change means it can fail again. It's just a
property of the current implementation that it can't. It used to fail.

This seems to be a ton of unneccessary churn that will end up just having
to be reversed again some day in the future.

Alan

^ permalink raw reply

* [PATCH v2 3/3] clk: x86: Stop marking clocks as CLK_IS_CRITICAL
From: Hans de Goede @ 2018-09-12  9:34 UTC (permalink / raw)
  To: David S . Miller, Heiner Kallweit, Michael Turquette,
	Stephen Boyd, Andy Shevchenko, Pierre-Louis Bossart
  Cc: Hans de Goede, linux-wireless, netdev, Johannes Stezenbach,
	Carlo Caione, linux-clk
In-Reply-To: <20180912093456.23400-1-hdegoede@redhat.com>

Commit d31fd43c0f9a ("clk: x86: Do not gate clocks enabled by the
firmware"), which added the code to mark clocks as CLK_IS_CRITICAL, causes
all unclaimed PMC clocks on Cherry Trail devices to be on all the time,
resulting on the device not being able to reach S0i3 when suspended.

The reason for this commit is that on some Bay Trail / Cherry Trail devices
the r8169 ethernet controller uses pmc_plt_clk_4. Now that the clk-pmc-atom
driver exports an "ether_clk" alias for pmc_plt_clk_4 and the r8169 driver
has been modified to get and enable this clock (if present) the marking of
the clocks as CLK_IS_CRITICAL is no longer necessary.

This commit removes the CLK_IS_CRITICAL marking, fixing Cherry Trail
devices not being able to reach S0i3 greatly decreasing their battery
drain when suspended.

Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=193891#c102
Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=196861
Cc: Johannes Stezenbach <js@sig21.net>
Cc: Carlo Caione <carlo@endlessm.com>
Reported-by: Johannes Stezenbach <js@sig21.net>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-Tweaked the commit msg a bit
-Added: Stephen's Acked-by, Andy's Reviewed-by
---
 drivers/clk/x86/clk-pmc-atom.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/clk/x86/clk-pmc-atom.c b/drivers/clk/x86/clk-pmc-atom.c
index 75151901ff7d..d977193842df 100644
--- a/drivers/clk/x86/clk-pmc-atom.c
+++ b/drivers/clk/x86/clk-pmc-atom.c
@@ -187,13 +187,6 @@ static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id,
 	pclk->reg = base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE;
 	spin_lock_init(&pclk->lock);
 
-	/*
-	 * If the clock was already enabled by the firmware mark it as critical
-	 * to avoid it being gated by the clock framework if no driver owns it.
-	 */
-	if (plt_clk_is_enabled(&pclk->hw))
-		init.flags |= CLK_IS_CRITICAL;
-
 	ret = devm_clk_hw_register(&pdev->dev, &pclk->hw);
 	if (ret) {
 		pclk = ERR_PTR(ret);
-- 
2.19.0.rc0

^ permalink raw reply related

* [PATCH v2 1/3] clk: x86: add "ether_clk" alias for Bay Trail / Cherry Trail
From: Hans de Goede @ 2018-09-12  9:34 UTC (permalink / raw)
  To: David S . Miller, Heiner Kallweit, Michael Turquette,
	Stephen Boyd, Andy Shevchenko, Pierre-Louis Bossart
  Cc: Hans de Goede, linux-wireless, netdev, Johannes Stezenbach,
	Carlo Caione, linux-clk
In-Reply-To: <20180912093456.23400-1-hdegoede@redhat.com>

Commit d31fd43c0f9a ("clk: x86: Do not gate clocks enabled by the
firmware") causes all unclaimed PMC clocks on Cherry Trail devices to be on
all the time, resulting on the device not being able to reach S0i2 or S0i3
when suspended.

The reason for this commit is that on some Bay Trail / Cherry Trail devices
the ethernet controller uses pmc_plt_clk_4. This commit adds an "ether_clk"
alias, so that the relevant ethernet drivers can try to (optionally) use
this, without needing X86 specific code / hacks, thus fixing ethernet on
these devices without breaking S0i3 support.

This commit uses clkdev_hw_create() to create the alias, mirroring the code
for the already existing "mclk" alias for pmc_plt_clk_3.

Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=193891#c102
Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=196861
Cc: Johannes Stezenbach <js@sig21.net>
Cc: Carlo Caione <carlo@endlessm.com>
Reported-by: Johannes Stezenbach <js@sig21.net>
Acked-by: Stephen Boyd <sboyd@kernel.org>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-Tweaked the commit msg a bit
-Added: Stephen's Acked-by, Andy's Reviewed-by
---
 drivers/clk/x86/clk-pmc-atom.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/clk/x86/clk-pmc-atom.c b/drivers/clk/x86/clk-pmc-atom.c
index 08ef69945ffb..75151901ff7d 100644
--- a/drivers/clk/x86/clk-pmc-atom.c
+++ b/drivers/clk/x86/clk-pmc-atom.c
@@ -55,6 +55,7 @@ struct clk_plt_data {
 	u8 nparents;
 	struct clk_plt *clks[PMC_CLK_NUM];
 	struct clk_lookup *mclk_lookup;
+	struct clk_lookup *ether_clk_lookup;
 };
 
 /* Return an index in parent table */
@@ -351,11 +352,20 @@ static int plt_clk_probe(struct platform_device *pdev)
 		goto err_unreg_clk_plt;
 	}
 
+	data->ether_clk_lookup = clkdev_hw_create(&data->clks[4]->hw,
+						  "ether_clk", NULL);
+	if (!data->ether_clk_lookup) {
+		err = -ENOMEM;
+		goto err_drop_mclk;
+	}
+
 	plt_clk_free_parent_names_loop(parent_names, data->nparents);
 
 	platform_set_drvdata(pdev, data);
 	return 0;
 
+err_drop_mclk:
+	clkdev_drop(data->mclk_lookup);
 err_unreg_clk_plt:
 	plt_clk_unregister_loop(data, i);
 	plt_clk_unregister_parents(data);
@@ -369,6 +379,7 @@ static int plt_clk_remove(struct platform_device *pdev)
 
 	data = platform_get_drvdata(pdev);
 
+	clkdev_drop(data->ether_clk_lookup);
 	clkdev_drop(data->mclk_lookup);
 	plt_clk_unregister_loop(data, PMC_CLK_NUM);
 	plt_clk_unregister_parents(data);
-- 
2.19.0.rc0

^ permalink raw reply related

* [PATCH v2 0/3] r8169 (x86) clk fixes to fix S0ix not being reached
From: Hans de Goede @ 2018-09-12  9:34 UTC (permalink / raw)
  To: David S . Miller, Heiner Kallweit, Michael Turquette,
	Stephen Boyd, Andy Shevchenko, Pierre-Louis Bossart
  Cc: Hans de Goede, linux-wireless, netdev, Johannes Stezenbach,
	Carlo Caione, linux-clk

Hi David,

This series adds code to the r8169 ethernet driver to get and enable an
external clock if present, avoiding the need for a hack in the
clk-pmc-atom driver where that clock was left on continuesly causing x86
some devices to not reach deep power saving states (S0ix) when suspended
causing to them to quickly drain their battery while suspended.

The 3 commits in this series need to be merged in order to avoid
regressions while bisecting. The clk-pmc-atom driver does not see much
changes (it was last touched over a year ago). So the clk maintainers
have agreed with merging all 3 patches through the net tree.
All 3 patches have Stephen Boyd's Acked-by for this purpose.

This v2 of the series only had some minor tweaks done to the commit
messages and is ready for merging through the net tree now.

Thanks & Regards,

Hans

^ permalink raw reply

* Re: [PATCH net-next v3 02/10] net: mvpp2: phylink support
From: Antoine Tenart @ 2018-09-12 14:34 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Andrew Lunn, Antoine Tenart, davem, kishon, gregory.clement,
	jason, sebastian.hesselbarth, netdev, linux-kernel,
	thomas.petazzoni, maxime.chevallier, miquel.raynal, nadavh,
	stefanc, ymarkman, mw, linux-arm-kernel
In-Reply-To: <20180831152131.GN30658@n2100.armlinux.org.uk>

Russell,

On Fri, Aug 31, 2018 at 04:21:31PM +0100, Russell King - ARM Linux wrote:
> 
> I think some questions for Antoine are:

I just got back to this. Using the SFP port on the 7040-db board (which
is one of the problematic interfaces):

> - what is the state of the carrier at the start of mvpp2_start() ?

Always on.

> - when does the missing call to mac_link_up() occur - is it the first
>   time the netdev is brought up, or a subsequent time?

Only the first time the netdev is brought up. If the link is set down
and then up again, its phylink link state would be good, and a mismatch
with the carrier state occurs as expected.

> - is the carrier always off at the end of mvpp2_stop()?

Always off.

So the issue really is the phylink internal link state matching the
carrier on when phylink is started the first time (and hence mac_config
is not called).

I've made some patches to rework PPv2 not to mess things up in
mac_config(), I've added a call to netif_carrier_off() at the
beginning of phylink_start(), and then removed the netif_carrier_off()
call in mvneta's open() function. It seems to work fine, I tested a few
boards with various network configurations. I'll send them so that
we can have more people testing this, and have proper reviews, since
this seems to be an acceptable solution given the answers in this
thread.

Thanks,
Antoine

-- 
Antoine Ténart, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* Re: [net-next, PATCH 2/2, v2] net: socionext: add XDP support
From: Ilias Apalodimas @ 2018-09-12  9:29 UTC (permalink / raw)
  To: Jesper Dangaard Brouer
  Cc: netdev, jaswinder.singh, ard.biesheuvel, masami.hiramatsu, arnd,
	mykyta.iziumtsev, bjorn.topel, magnus.karlsson, daniel, ast
In-Reply-To: <20180912112524.34250d1c@redhat.com>

On Wed, Sep 12, 2018 at 11:25:24AM +0200, Jesper Dangaard Brouer wrote:
> On Wed, 12 Sep 2018 12:02:38 +0300
> Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote:
> 
> >  static const struct net_device_ops netsec_netdev_ops = {
> >  	.ndo_init		= netsec_netdev_init,
> >  	.ndo_uninit		= netsec_netdev_uninit,
> > @@ -1430,6 +1627,7 @@ static const struct net_device_ops netsec_netdev_ops = {
> >  	.ndo_set_mac_address    = eth_mac_addr,
> >  	.ndo_validate_addr	= eth_validate_addr,
> >  	.ndo_do_ioctl		= netsec_netdev_ioctl,
> > +	.ndo_bpf		= netsec_xdp,
> >  };
> >  
> 
> You have not implemented ndo_xdp_xmit.
> 
> Thus, you have "only" implemented the RX side of XDP_REDIRECT.  Which
> allows you to do, cpumap and AF_XDP redirects, but not allowing other
> drivers to XDP send out this device.
Correct, that was the planning, is ndo_xdp_xmit() needed for the patch or
is the patch message just misleading and i should change that ?

Thanks
/Ilias

^ permalink raw reply

* Re: [net-next, PATCH 2/2, v2] net: socionext: add XDP support
From: Björn Töpel @ 2018-09-12  9:28 UTC (permalink / raw)
  To: Ilias Apalodimas
  Cc: Jesper Dangaard Brouer, Netdev, Jaswinder Brar, Ard Biesheuvel,
	Masami Hiramatsu, Arnd Bergmann, MykytaI Iziumtsev,
	Björn Töpel, Karlsson, Magnus, Daniel Borkmann, ast
In-Reply-To: <20180912092012.GA31360@apalos>

Den ons 12 sep. 2018 kl 11:21 skrev Ilias Apalodimas
<ilias.apalodimas@linaro.org>:
>
> On Wed, Sep 12, 2018 at 11:14:57AM +0200, Jesper Dangaard Brouer wrote:
> > On Wed, 12 Sep 2018 12:02:38 +0300
> > Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote:
> >
> > > @@ -1003,20 +1076,29 @@ static int netsec_setup_rx_dring(struct netsec_priv *priv)
> > >             u16 len;
> > >
> > >             buf = netsec_alloc_rx_data(priv, &dma_handle, &len);
> > > -           if (!buf) {
> > > -                   netsec_uninit_pkt_dring(priv, NETSEC_RING_RX);
> > > +           if (!buf)
> > >                     goto err_out;
> > > -           }
> > >             desc->dma_addr = dma_handle;
> > >             desc->addr = buf;
> > >             desc->len = len;
> > >     }
> > >
> > >     netsec_rx_fill(priv, 0, DESC_NUM);
> > > +   err = xdp_rxq_info_reg(&dring->xdp_rxq, priv->ndev, 0);
> >
> > Do you only have 1 RX queue? (last arg to xdp_rxq_info_reg is 0),
> >
> >
> Yes the current driver is only supporting a single queue (same for Tx)

XDP and skbuff path sharing the same queue? You'll probably need some
means of synchronization between the .ndo_xmit_xdp and .ndo_start_xmit
implementations. And it looks like .ndo_xmit_xdp is missing!


Björn

> > > +   if (err)
> > > +           goto err_out;
> > > +
> > > +   err = xdp_rxq_info_reg_mem_model(&dring->xdp_rxq, MEM_TYPE_PAGE_SHARED,
> > > +                                    NULL);
> > > +   if (err) {
> > > +           xdp_rxq_info_unreg(&dring->xdp_rxq);
> > > +           goto err_out;
> > > +   }
> > >
> > >     return 0;
> > >
> >
> >
> > --
> > Best regards,
> >   Jesper Dangaard Brouer
> >   MSc.CS, Principal Kernel Engineer at Red Hat
> >   LinkedIn: http://www.linkedin.com/in/brouer
>
>
> Thanks for looking at this
>
> /Ilias

^ permalink raw reply

* Re: [net-next, PATCH 2/2, v2] net: socionext: add XDP support
From: Jesper Dangaard Brouer @ 2018-09-12  9:25 UTC (permalink / raw)
  To: Ilias Apalodimas
  Cc: netdev, jaswinder.singh, ard.biesheuvel, masami.hiramatsu, arnd,
	mykyta.iziumtsev, bjorn.topel, magnus.karlsson, daniel, ast,
	brouer
In-Reply-To: <1536742958-29887-3-git-send-email-ilias.apalodimas@linaro.org>

On Wed, 12 Sep 2018 12:02:38 +0300
Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote:

>  static const struct net_device_ops netsec_netdev_ops = {
>  	.ndo_init		= netsec_netdev_init,
>  	.ndo_uninit		= netsec_netdev_uninit,
> @@ -1430,6 +1627,7 @@ static const struct net_device_ops netsec_netdev_ops = {
>  	.ndo_set_mac_address    = eth_mac_addr,
>  	.ndo_validate_addr	= eth_validate_addr,
>  	.ndo_do_ioctl		= netsec_netdev_ioctl,
> +	.ndo_bpf		= netsec_xdp,
>  };
>  

You have not implemented ndo_xdp_xmit.

Thus, you have "only" implemented the RX side of XDP_REDIRECT.  Which
allows you to do, cpumap and AF_XDP redirects, but not allowing other
drivers to XDP send out this device.

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

^ permalink raw reply

* Re: [net-next, PATCH 2/2, v2] net: socionext: add XDP support
From: Ilias Apalodimas @ 2018-09-12  9:20 UTC (permalink / raw)
  To: Jesper Dangaard Brouer
  Cc: netdev, jaswinder.singh, ard.biesheuvel, masami.hiramatsu, arnd,
	mykyta.iziumtsev, bjorn.topel, magnus.karlsson, daniel, ast
In-Reply-To: <20180912111457.0121d9f3@redhat.com>

On Wed, Sep 12, 2018 at 11:14:57AM +0200, Jesper Dangaard Brouer wrote:
> On Wed, 12 Sep 2018 12:02:38 +0300
> Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote:
> 
> > @@ -1003,20 +1076,29 @@ static int netsec_setup_rx_dring(struct netsec_priv *priv)
> >  		u16 len;
> >  
> >  		buf = netsec_alloc_rx_data(priv, &dma_handle, &len);
> > -		if (!buf) {
> > -			netsec_uninit_pkt_dring(priv, NETSEC_RING_RX);
> > +		if (!buf)
> >  			goto err_out;
> > -		}
> >  		desc->dma_addr = dma_handle;
> >  		desc->addr = buf;
> >  		desc->len = len;
> >  	}
> >  
> >  	netsec_rx_fill(priv, 0, DESC_NUM);
> > +	err = xdp_rxq_info_reg(&dring->xdp_rxq, priv->ndev, 0);
> 
> Do you only have 1 RX queue? (last arg to xdp_rxq_info_reg is 0),
> 
> 
Yes the current driver is only supporting a single queue (same for Tx)
> > +	if (err)
> > +		goto err_out;
> > +
> > +	err = xdp_rxq_info_reg_mem_model(&dring->xdp_rxq, MEM_TYPE_PAGE_SHARED,
> > +					 NULL);
> > +	if (err) {
> > +		xdp_rxq_info_unreg(&dring->xdp_rxq);
> > +		goto err_out;
> > +	}
> >  
> >  	return 0;
> >  
> 
> 
> -- 
> Best regards,
>   Jesper Dangaard Brouer
>   MSc.CS, Principal Kernel Engineer at Red Hat
>   LinkedIn: http://www.linkedin.com/in/brouer


Thanks for looking at this

/Ilias

^ permalink raw reply

* Re: [net-next, PATCH 2/2, v2] net: socionext: add XDP support
From: Jesper Dangaard Brouer @ 2018-09-12  9:14 UTC (permalink / raw)
  To: Ilias Apalodimas
  Cc: netdev, jaswinder.singh, ard.biesheuvel, masami.hiramatsu, arnd,
	mykyta.iziumtsev, bjorn.topel, magnus.karlsson, daniel, ast,
	brouer
In-Reply-To: <1536742958-29887-3-git-send-email-ilias.apalodimas@linaro.org>

On Wed, 12 Sep 2018 12:02:38 +0300
Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote:

> @@ -1003,20 +1076,29 @@ static int netsec_setup_rx_dring(struct netsec_priv *priv)
>  		u16 len;
>  
>  		buf = netsec_alloc_rx_data(priv, &dma_handle, &len);
> -		if (!buf) {
> -			netsec_uninit_pkt_dring(priv, NETSEC_RING_RX);
> +		if (!buf)
>  			goto err_out;
> -		}
>  		desc->dma_addr = dma_handle;
>  		desc->addr = buf;
>  		desc->len = len;
>  	}
>  
>  	netsec_rx_fill(priv, 0, DESC_NUM);
> +	err = xdp_rxq_info_reg(&dring->xdp_rxq, priv->ndev, 0);

Do you only have 1 RX queue? (last arg to xdp_rxq_info_reg is 0),


> +	if (err)
> +		goto err_out;
> +
> +	err = xdp_rxq_info_reg_mem_model(&dring->xdp_rxq, MEM_TYPE_PAGE_SHARED,
> +					 NULL);
> +	if (err) {
> +		xdp_rxq_info_unreg(&dring->xdp_rxq);
> +		goto err_out;
> +	}
>  
>  	return 0;
>  


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

^ permalink raw reply

* [PATCH] brcm80211: remove redundant condition check before debugfs_remove_recursive
From: zhong jiang @ 2018-09-12 14:10 UTC (permalink / raw)
  To: kvalo-sgV2jX0FEOL9JmXXK+q4OQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: hante.meuleman-dY08KVG/lbpWk0Htik3J/w,
	franky.lin-dY08KVG/lbpWk0Htik3J/w,
	arend.vanspriel-dY08KVG/lbpWk0Htik3J/w,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	brcm80211-dev-list.pdl-dY08KVG/lbpWk0Htik3J/w,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

debugfs_remove_recursive has taken IS_ERR_OR_NULL into account. So just
remove the condition check before debugfs_remove_recursive.

Signed-off-by: zhong jiang <zhongjiang-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
 drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c
index 2fe1f68..3bd54f1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/debug.c
@@ -62,8 +62,7 @@ int brcms_debugfs_attach(struct brcms_pub *drvr)
 
 void brcms_debugfs_detach(struct brcms_pub *drvr)
 {
-	if (!IS_ERR_OR_NULL(drvr->dbgfs_dir))
-		debugfs_remove_recursive(drvr->dbgfs_dir);
+	debugfs_remove_recursive(drvr->dbgfs_dir);
 }
 
 struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr)
-- 
1.7.12.4

^ permalink raw reply related

* Re: [PATCH v2] neighbour: confirm neigh entries when ARP packet is received
From: Sergei Shtylyov @ 2018-09-12  9:05 UTC (permalink / raw)
  To: Vasily Khoruzhick, David S. Miller, Roopa Prabhu, Alexey Dobriyan,
	Eric Dumazet, Stephen Hemminger, Jim Westfall, Wolfgang Bumiller,
	Vasily Khoruzhick, Kees Cook, Ihar Hrachyshka, netdev,
	linux-kernel
In-Reply-To: <20180911180406.31283-1-vasilykh@arista.com>

Hello!

On 9/11/2018 9:04 PM, Vasily Khoruzhick wrote:

> Update 'confirmed' timestamp when ARP packet is received. It shouldn't
> affect locktime logic and anyway entry can be confirmed by any higher-layer
> protocol. Thus it makes to sense not to confirm it when ARP packet is

    "Makes sense" or "makes no sense"?

> received.
> 
> Fixes: 77d7123342 ("neighbour: update neigh timestamps iff update is
> effective")
> 
> Signed-off-by: Vasily Khoruzhick <vasilykh@arista.com>
[...]

MBR, Sergei

^ permalink raw reply

* [net-next, PATCH 2/2, v2] net: socionext: add XDP support
From: Ilias Apalodimas @ 2018-09-12  9:02 UTC (permalink / raw)
  To: netdev, jaswinder.singh
  Cc: ard.biesheuvel, masami.hiramatsu, arnd, mykyta.iziumtsev,
	bjorn.topel, magnus.karlsson, brouer, daniel, ast,
	Ilias Apalodimas
In-Reply-To: <1536742958-29887-1-git-send-email-ilias.apalodimas@linaro.org>

Add basic XDP support

Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
---
 drivers/net/ethernet/socionext/netsec.c | 234 +++++++++++++++++++++++++++++---
 1 file changed, 216 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c
index 666fee2..1f4594f 100644
--- a/drivers/net/ethernet/socionext/netsec.c
+++ b/drivers/net/ethernet/socionext/netsec.c
@@ -9,6 +9,9 @@
 #include <linux/etherdevice.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/netlink.h>
+#include <linux/bpf.h>
+#include <linux/bpf_trace.h>
 
 #include <net/tcp.h>
 #include <net/ip6_checksum.h>
@@ -238,6 +241,11 @@
 
 #define NETSEC_F_NETSEC_VER_MAJOR_NUM(x)	((x) & 0xffff0000)
 
+#define NETSEC_XDP_PASS          0
+#define NETSEC_XDP_CONSUMED      BIT(0)
+#define NETSEC_XDP_TX            BIT(1)
+#define NETSEC_XDP_REDIR         BIT(2)
+
 enum ring_id {
 	NETSEC_RING_TX = 0,
 	NETSEC_RING_RX
@@ -256,11 +264,14 @@ struct netsec_desc_ring {
 	void *vaddr;
 	u16 pkt_cnt;
 	u16 head, tail;
+	bool is_xdp;
+	struct xdp_rxq_info xdp_rxq;
 };
 
 struct netsec_priv {
 	struct netsec_desc_ring desc_ring[NETSEC_RING_MAX];
 	struct ethtool_coalesce et_coalesce;
+	struct bpf_prog *xdp_prog;
 	spinlock_t reglock; /* protect reg access */
 	struct napi_struct napi;
 	phy_interface_t phy_interface;
@@ -297,6 +308,8 @@ struct netsec_rx_pkt_info {
 };
 
 static void netsec_rx_fill(struct netsec_priv *priv, u16 from, u16 num);
+static u32 netsec_run_xdp(struct netsec_desc *desc, struct netsec_priv *priv,
+			  struct bpf_prog *prog, struct xdp_buff *xdp);
 
 static void *netsec_alloc_rx_data(struct netsec_priv *priv,
 				  dma_addr_t *dma_addr, u16 *len);
@@ -613,13 +626,23 @@ static int netsec_clean_tx_dring(struct netsec_priv *priv, int budget)
 
 		eop = (entry->attr >> NETSEC_TX_LAST) & 1;
 
-		dma_unmap_single(priv->dev, desc->dma_addr, desc->len,
-				 DMA_TO_DEVICE);
-		if (eop) {
-			pkts++;
+		if (desc->skb)
+			dma_unmap_single(priv->dev,
+					 desc->dma_addr - XDP_PACKET_HEADROOM,
+					 desc->len, DMA_TO_DEVICE);
+
+		if (!eop) {
+			*desc = (struct netsec_desc){};
+			continue;
+		}
+
+		if (!desc->skb) {
+			skb_free_frag(desc->addr);
+		} else {
 			bytes += desc->skb->len;
 			dev_kfree_skb(desc->skb);
 		}
+		pkts++;
 		*desc = (struct netsec_desc){};
 	}
 	dring->pkt_cnt -= budget;
@@ -659,19 +682,22 @@ static void nsetsec_adv_desc(u16 *idx)
 static int netsec_process_rx(struct netsec_priv *priv, int budget)
 {
 	struct netsec_desc_ring *dring = &priv->desc_ring[NETSEC_RING_RX];
+	struct bpf_prog *xdp_prog = READ_ONCE(priv->xdp_prog);
 	struct net_device *ndev = priv->ndev;
-	struct sk_buff *skb;
+	struct sk_buff *skb = NULL;
+	u32 xdp_flush = 0;
+	u32 xdp_result;
 	int done = 0;
 
 	while (done < budget) {
 		u16 idx = dring->tail;
 		struct netsec_de *de = dring->vaddr + (DESC_SZ * idx);
 		struct netsec_desc *desc = &dring->desc[idx];
+		dma_addr_t dma_handle, dma_unmap;
 		struct netsec_rx_pkt_info rpi;
-		dma_addr_t dma_handle;
+		u16 pkt_len, desc_len;
+		struct xdp_buff xdp;
 		void *buf_addr;
-		u16 pkt_len;
-		u16 desc_len;
 
 		if (de->attr & (1U << NETSEC_RX_PKT_OWN_FIELD))
 			break;
@@ -704,10 +730,40 @@ static int netsec_process_rx(struct netsec_priv *priv, int budget)
 
 		prefetch(desc->addr);
 		buf_addr = netsec_alloc_rx_data(priv, &dma_handle, &desc_len);
+
 		if (unlikely(!buf_addr))
 			break;
 
-		skb = build_skb(desc->addr, desc->len);
+		dma_unmap = dring->is_xdp ?
+			desc->dma_addr - XDP_PACKET_HEADROOM : desc->dma_addr;
+
+		xdp.data_hard_start = desc->addr;
+		xdp.data = desc->addr;
+		xdp_set_data_meta_invalid(&xdp);
+		xdp.data_end = xdp.data + pkt_len;
+		xdp.rxq = &dring->xdp_rxq;
+
+		if (xdp_prog) {
+			xdp.data = desc->addr + XDP_PACKET_HEADROOM;
+			xdp.data_end = xdp.data + pkt_len;
+			xdp_result = netsec_run_xdp(desc, priv, xdp_prog, &xdp);
+			if (xdp_result != NETSEC_XDP_PASS) {
+				xdp_flush |= xdp_result & NETSEC_XDP_REDIR;
+
+				dma_unmap_single_attrs(priv->dev, dma_unmap,
+						       desc->len, DMA_TO_DEVICE,
+						       DMA_ATTR_SKIP_CPU_SYNC);
+
+				desc->len = desc_len;
+				desc->dma_addr = dma_handle;
+				desc->addr = buf_addr;
+				netsec_rx_fill(priv, idx, 1);
+				nsetsec_adv_desc(&dring->tail);
+				continue;
+			}
+		}
+
+		skb = build_skb(xdp.data_hard_start, desc->len);
 		if (unlikely(!skb)) {
 			dma_unmap_single(priv->dev, dma_handle, desc_len,
 					 DMA_TO_DEVICE);
@@ -716,7 +772,7 @@ static int netsec_process_rx(struct netsec_priv *priv, int budget)
 				  "rx failed to alloc skb\n");
 			break;
 		}
-		dma_unmap_single_attrs(priv->dev, desc->dma_addr, desc->len,
+		dma_unmap_single_attrs(priv->dev, dma_unmap, desc->len,
 				       DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
 
 		/* Update the descriptor with fresh buffers */
@@ -724,7 +780,8 @@ static int netsec_process_rx(struct netsec_priv *priv, int budget)
 		desc->dma_addr = dma_handle;
 		desc->addr = buf_addr;
 
-		skb_put(skb, pkt_len);
+		skb_reserve(skb, xdp.data - xdp.data_hard_start);
+		skb_put(skb, xdp.data_end - xdp.data);
 		skb->protocol = eth_type_trans(skb, priv->ndev);
 
 		if (priv->rx_cksum_offload_flag &&
@@ -733,13 +790,16 @@ static int netsec_process_rx(struct netsec_priv *priv, int budget)
 
 		if (napi_gro_receive(&priv->napi, skb) != GRO_DROP) {
 			ndev->stats.rx_packets++;
-			ndev->stats.rx_bytes += pkt_len;
+			ndev->stats.rx_bytes += xdp.data_end - xdp.data;
 		}
 
 		netsec_rx_fill(priv, idx, 1);
 		nsetsec_adv_desc(&dring->tail);
 	}
 
+	if (xdp_flush & NETSEC_XDP_REDIR)
+		xdp_do_flush_map();
+
 	return done;
 }
 
@@ -892,6 +952,9 @@ static void netsec_uninit_pkt_dring(struct netsec_priv *priv, int id)
 	if (!dring->vaddr || !dring->desc)
 		return;
 
+	if (xdp_rxq_info_is_reg(&dring->xdp_rxq))
+		xdp_rxq_info_unreg(&dring->xdp_rxq);
+
 	for (idx = 0; idx < DESC_NUM; idx++) {
 		desc = &dring->desc[idx];
 		if (!desc->addr)
@@ -931,11 +994,14 @@ static void netsec_free_dring(struct netsec_priv *priv, int id)
 static void *netsec_alloc_rx_data(struct netsec_priv *priv,
 				  dma_addr_t *dma_handle, u16 *desc_len)
 {
+	struct netsec_desc_ring *dring = &priv->desc_ring[NETSEC_RING_RX];
 	size_t len = priv->ndev->mtu + ETH_HLEN + VLAN_HLEN * 2 + NET_SKB_PAD +
 		NET_IP_ALIGN;
 	dma_addr_t mapping;
 	void *buf;
 
+	if (dring->is_xdp)
+		len += XDP_PACKET_HEADROOM;
 	len = SKB_DATA_ALIGN(len);
 	len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 
@@ -943,11 +1009,12 @@ static void *netsec_alloc_rx_data(struct netsec_priv *priv,
 	if (!buf)
 		return NULL;
 
-	mapping = dma_map_single(priv->dev, buf, len, DMA_FROM_DEVICE);
+	mapping = dma_map_single(priv->dev, buf, len,
+				 DMA_FROM_DEVICE);
 	if (unlikely(dma_mapping_error(priv->dev, mapping)))
 		goto err_out;
 
-	*dma_handle = mapping;
+	*dma_handle = mapping + (dring->is_xdp ? XDP_PACKET_HEADROOM : 0);
 	*desc_len = len;
 
 	return buf;
@@ -994,7 +1061,13 @@ static int netsec_alloc_dring(struct netsec_priv *priv, enum ring_id id)
 static int netsec_setup_rx_dring(struct netsec_priv *priv)
 {
 	struct netsec_desc_ring *dring = &priv->desc_ring[NETSEC_RING_RX];
-	int i;
+	struct bpf_prog *xdp_prog = READ_ONCE(priv->xdp_prog);
+	int i, err;
+
+	if (xdp_prog)
+		dring->is_xdp = true;
+	else
+		dring->is_xdp = false;
 
 	for (i = 0; i < DESC_NUM; i++) {
 		struct netsec_desc *desc = &dring->desc[i];
@@ -1003,20 +1076,29 @@ static int netsec_setup_rx_dring(struct netsec_priv *priv)
 		u16 len;
 
 		buf = netsec_alloc_rx_data(priv, &dma_handle, &len);
-		if (!buf) {
-			netsec_uninit_pkt_dring(priv, NETSEC_RING_RX);
+		if (!buf)
 			goto err_out;
-		}
 		desc->dma_addr = dma_handle;
 		desc->addr = buf;
 		desc->len = len;
 	}
 
 	netsec_rx_fill(priv, 0, DESC_NUM);
+	err = xdp_rxq_info_reg(&dring->xdp_rxq, priv->ndev, 0);
+	if (err)
+		goto err_out;
+
+	err = xdp_rxq_info_reg_mem_model(&dring->xdp_rxq, MEM_TYPE_PAGE_SHARED,
+					 NULL);
+	if (err) {
+		xdp_rxq_info_unreg(&dring->xdp_rxq);
+		goto err_out;
+	}
 
 	return 0;
 
 err_out:
+	netsec_uninit_pkt_dring(priv, NETSEC_RING_RX);
 	return -ENOMEM;
 }
 
@@ -1420,6 +1502,121 @@ static int netsec_netdev_ioctl(struct net_device *ndev, struct ifreq *ifr,
 	return phy_mii_ioctl(ndev->phydev, ifr, cmd);
 }
 
+static u32 netsec_xmit_xdp(struct netsec_priv *priv, struct xdp_buff *xdp,
+			   struct netsec_desc *rx_desc)
+{
+	struct netsec_desc_ring *tx_ring = &priv->desc_ring[NETSEC_RING_TX];
+	struct netsec_tx_pkt_ctrl tx_ctrl = {};
+	struct netsec_desc tx_desc;
+	int filled;
+	u32 len;
+
+	len = xdp->data_end - xdp->data;
+
+	if (tx_ring->head >= tx_ring->tail)
+		filled = tx_ring->head - tx_ring->tail;
+	else
+		filled = tx_ring->head + DESC_NUM - tx_ring->tail;
+
+	if (DESC_NUM - filled <= 1)
+		return NETSEC_XDP_CONSUMED;
+
+	dma_sync_single_for_device(priv->dev, rx_desc->dma_addr, len,
+				   DMA_TO_DEVICE);
+
+	tx_desc.dma_addr = rx_desc->dma_addr;
+	tx_desc.addr = xdp->data;
+	tx_desc.len = len;
+
+	netsec_set_tx_de(priv, tx_ring, &tx_ctrl, &tx_desc, NULL);
+	netsec_write(priv, NETSEC_REG_NRM_TX_PKTCNT, 1);
+
+	return NETSEC_XDP_TX;
+}
+
+static u32 netsec_run_xdp(struct netsec_desc *desc, struct netsec_priv *priv,
+			  struct bpf_prog *prog, struct xdp_buff *xdp)
+{
+	u32 ret = NETSEC_XDP_PASS;
+	int err;
+	u32 act;
+
+	rcu_read_lock();
+	act = bpf_prog_run_xdp(prog, xdp);
+
+	switch (act) {
+	case XDP_PASS:
+		ret = NETSEC_XDP_PASS;
+		break;
+	case XDP_TX:
+		ret = netsec_xmit_xdp(priv, xdp, desc);
+		break;
+	case XDP_REDIRECT:
+		err = xdp_do_redirect(priv->ndev, xdp, prog);
+		if (!err) {
+			ret = NETSEC_XDP_REDIR;
+		} else {
+			ret = NETSEC_XDP_CONSUMED;
+			xdp_return_buff(xdp);
+		}
+		break;
+	default:
+		bpf_warn_invalid_xdp_action(act);
+		/* fall through */
+	case XDP_ABORTED:
+		trace_xdp_exception(priv->ndev, prog, act);
+		/* fall through -- handle aborts by dropping packet */
+	case XDP_DROP:
+		ret = NETSEC_XDP_CONSUMED;
+		break;
+	}
+
+	rcu_read_unlock();
+
+	return ret;
+}
+
+static int netsec_xdp_setup(struct netsec_priv *priv, struct bpf_prog *prog,
+			    struct netlink_ext_ack *extack)
+{
+	struct net_device *dev = priv->ndev;
+	struct bpf_prog *old_prog;
+
+	/* For now just support only the usual MTU sized frames */
+	if (prog && dev->mtu > 1500) {
+		NL_SET_ERR_MSG_MOD(extack, "Jumbo frames not supported on XDP");
+		return -EOPNOTSUPP;
+	}
+
+	if (netif_running(dev))
+		netsec_netdev_stop(dev);
+
+	/* Detach old prog, if any */
+	old_prog = xchg(&priv->xdp_prog, prog);
+	if (old_prog)
+		bpf_prog_put(old_prog);
+
+	if (netif_running(dev))
+		netsec_netdev_open(dev);
+
+	return 0;
+}
+
+static int netsec_xdp(struct net_device *ndev, struct netdev_bpf *xdp)
+{
+	struct netsec_priv *priv = netdev_priv(ndev);
+
+	switch (xdp->command) {
+	case XDP_SETUP_PROG:
+		return netsec_xdp_setup(priv, xdp->prog, xdp->extack);
+	case XDP_QUERY_PROG:
+		xdp->prog_id = priv->xdp_prog ? priv->xdp_prog->aux->id : 0;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
 static const struct net_device_ops netsec_netdev_ops = {
 	.ndo_init		= netsec_netdev_init,
 	.ndo_uninit		= netsec_netdev_uninit,
@@ -1430,6 +1627,7 @@ static const struct net_device_ops netsec_netdev_ops = {
 	.ndo_set_mac_address    = eth_mac_addr,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_do_ioctl		= netsec_netdev_ioctl,
+	.ndo_bpf		= netsec_xdp,
 };
 
 static int netsec_of_probe(struct platform_device *pdev,
-- 
2.7.4

^ permalink raw reply related

* [net-next, PATCH 1/2, v2] net: socionext: different approach on DMA
From: Ilias Apalodimas @ 2018-09-12  9:02 UTC (permalink / raw)
  To: netdev, jaswinder.singh
  Cc: ard.biesheuvel, masami.hiramatsu, arnd, mykyta.iziumtsev,
	bjorn.topel, magnus.karlsson, brouer, daniel, ast,
	Ilias Apalodimas
In-Reply-To: <1536742958-29887-1-git-send-email-ilias.apalodimas@linaro.org>

Current driver dynamically allocates an skb and maps it as DMA rx buffer.
A following patch introduces AF_XDP functionality, so we need a
different allocation scheme. Buffers are allocated dynamically and
mapped into hardware. During the Rx operation the driver uses
build_skb() to produce the necessary buffers for the network stack

Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
---
 drivers/net/ethernet/socionext/netsec.c | 239 +++++++++++++++++---------------
 1 file changed, 130 insertions(+), 109 deletions(-)

diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c
index 7aa5ebb..666fee2 100644
--- a/drivers/net/ethernet/socionext/netsec.c
+++ b/drivers/net/ethernet/socionext/netsec.c
@@ -296,6 +296,11 @@ struct netsec_rx_pkt_info {
 	bool err_flag;
 };
 
+static void netsec_rx_fill(struct netsec_priv *priv, u16 from, u16 num);
+
+static void *netsec_alloc_rx_data(struct netsec_priv *priv,
+				  dma_addr_t *dma_addr, u16 *len);
+
 static void netsec_write(struct netsec_priv *priv, u32 reg_addr, u32 val)
 {
 	writel(val, priv->ioaddr + reg_addr);
@@ -556,34 +561,10 @@ static const struct ethtool_ops netsec_ethtool_ops = {
 
 /************* NETDEV_OPS FOLLOW *************/
 
-static struct sk_buff *netsec_alloc_skb(struct netsec_priv *priv,
-					struct netsec_desc *desc)
-{
-	struct sk_buff *skb;
-
-	if (device_get_dma_attr(priv->dev) == DEV_DMA_COHERENT) {
-		skb = netdev_alloc_skb_ip_align(priv->ndev, desc->len);
-	} else {
-		desc->len = L1_CACHE_ALIGN(desc->len);
-		skb = netdev_alloc_skb(priv->ndev, desc->len);
-	}
-	if (!skb)
-		return NULL;
-
-	desc->addr = skb->data;
-	desc->dma_addr = dma_map_single(priv->dev, desc->addr, desc->len,
-					DMA_FROM_DEVICE);
-	if (dma_mapping_error(priv->dev, desc->dma_addr)) {
-		dev_kfree_skb_any(skb);
-		return NULL;
-	}
-	return skb;
-}
 
 static void netsec_set_rx_de(struct netsec_priv *priv,
 			     struct netsec_desc_ring *dring, u16 idx,
-			     const struct netsec_desc *desc,
-			     struct sk_buff *skb)
+			     const struct netsec_desc *desc)
 {
 	struct netsec_de *de = dring->vaddr + DESC_SZ * idx;
 	u32 attr = (1 << NETSEC_RX_PKT_OWN_FIELD) |
@@ -602,59 +583,6 @@ static void netsec_set_rx_de(struct netsec_priv *priv,
 	dring->desc[idx].dma_addr = desc->dma_addr;
 	dring->desc[idx].addr = desc->addr;
 	dring->desc[idx].len = desc->len;
-	dring->desc[idx].skb = skb;
-}
-
-static struct sk_buff *netsec_get_rx_de(struct netsec_priv *priv,
-					struct netsec_desc_ring *dring,
-					u16 idx,
-					struct netsec_rx_pkt_info *rxpi,
-					struct netsec_desc *desc, u16 *len)
-{
-	struct netsec_de de = {};
-
-	memcpy(&de, dring->vaddr + DESC_SZ * idx, DESC_SZ);
-
-	*len = de.buf_len_info >> 16;
-
-	rxpi->err_flag = (de.attr >> NETSEC_RX_PKT_ER_FIELD) & 1;
-	rxpi->rx_cksum_result = (de.attr >> NETSEC_RX_PKT_CO_FIELD) & 3;
-	rxpi->err_code = (de.attr >> NETSEC_RX_PKT_ERR_FIELD) &
-							NETSEC_RX_PKT_ERR_MASK;
-	*desc = dring->desc[idx];
-	return desc->skb;
-}
-
-static struct sk_buff *netsec_get_rx_pkt_data(struct netsec_priv *priv,
-					      struct netsec_rx_pkt_info *rxpi,
-					      struct netsec_desc *desc,
-					      u16 *len)
-{
-	struct netsec_desc_ring *dring = &priv->desc_ring[NETSEC_RING_RX];
-	struct sk_buff *tmp_skb, *skb = NULL;
-	struct netsec_desc td;
-	int tail;
-
-	*rxpi = (struct netsec_rx_pkt_info){};
-
-	td.len = priv->ndev->mtu + 22;
-
-	tmp_skb = netsec_alloc_skb(priv, &td);
-
-	tail = dring->tail;
-
-	if (!tmp_skb) {
-		netsec_set_rx_de(priv, dring, tail, &dring->desc[tail],
-				 dring->desc[tail].skb);
-	} else {
-		skb = netsec_get_rx_de(priv, dring, tail, rxpi, desc, len);
-		netsec_set_rx_de(priv, dring, tail, &td, tmp_skb);
-	}
-
-	/* move tail ahead */
-	dring->tail = (dring->tail + 1) % DESC_NUM;
-
-	return skb;
 }
 
 static int netsec_clean_tx_dring(struct netsec_priv *priv, int budget)
@@ -721,19 +649,29 @@ static int netsec_process_tx(struct netsec_priv *priv, int budget)
 	return done;
 }
 
+static void nsetsec_adv_desc(u16 *idx)
+{
+	*idx = *idx + 1;
+	if (unlikely(*idx >= DESC_NUM))
+		*idx = 0;
+}
+
 static int netsec_process_rx(struct netsec_priv *priv, int budget)
 {
 	struct netsec_desc_ring *dring = &priv->desc_ring[NETSEC_RING_RX];
 	struct net_device *ndev = priv->ndev;
-	struct netsec_rx_pkt_info rx_info;
-	int done = 0;
-	struct netsec_desc desc;
 	struct sk_buff *skb;
-	u16 len;
+	int done = 0;
 
 	while (done < budget) {
 		u16 idx = dring->tail;
 		struct netsec_de *de = dring->vaddr + (DESC_SZ * idx);
+		struct netsec_desc *desc = &dring->desc[idx];
+		struct netsec_rx_pkt_info rpi;
+		dma_addr_t dma_handle;
+		void *buf_addr;
+		u16 pkt_len;
+		u16 desc_len;
 
 		if (de->attr & (1U << NETSEC_RX_PKT_OWN_FIELD))
 			break;
@@ -744,28 +682,62 @@ static int netsec_process_rx(struct netsec_priv *priv, int budget)
 		 */
 		dma_rmb();
 		done++;
-		skb = netsec_get_rx_pkt_data(priv, &rx_info, &desc, &len);
-		if (unlikely(!skb) || rx_info.err_flag) {
+
+		pkt_len = de->buf_len_info >> 16;
+		rpi.err_code = (de->attr >> NETSEC_RX_PKT_ERR_FIELD) &
+			NETSEC_RX_PKT_ERR_MASK;
+		rpi.err_flag = (de->attr >> NETSEC_RX_PKT_ER_FIELD) & 1;
+		if (rpi.err_flag) {
 			netif_err(priv, drv, priv->ndev,
-				  "%s: rx fail err(%d)\n",
-				  __func__, rx_info.err_code);
+				  "%s: rx fail err(%d)\n", __func__,
+				  rpi.err_code);
 			ndev->stats.rx_dropped++;
+			nsetsec_adv_desc(&dring->tail);
+			/* reuse buffer page frag */
+			netsec_rx_fill(priv, idx, 1);
 			continue;
 		}
+		rpi.rx_cksum_result = (de->attr >> NETSEC_RX_PKT_CO_FIELD) & 3;
 
-		dma_unmap_single(priv->dev, desc.dma_addr, desc.len,
-				 DMA_FROM_DEVICE);
-		skb_put(skb, len);
+		dma_sync_single_for_cpu(priv->dev, desc->dma_addr, pkt_len,
+					DMA_FROM_DEVICE);
+
+		prefetch(desc->addr);
+		buf_addr = netsec_alloc_rx_data(priv, &dma_handle, &desc_len);
+		if (unlikely(!buf_addr))
+			break;
+
+		skb = build_skb(desc->addr, desc->len);
+		if (unlikely(!skb)) {
+			dma_unmap_single(priv->dev, dma_handle, desc_len,
+					 DMA_TO_DEVICE);
+			skb_free_frag(buf_addr);
+			netif_err(priv, drv, priv->ndev,
+				  "rx failed to alloc skb\n");
+			break;
+		}
+		dma_unmap_single_attrs(priv->dev, desc->dma_addr, desc->len,
+				       DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
+
+		/* Update the descriptor with fresh buffers */
+		desc->len = desc_len;
+		desc->dma_addr = dma_handle;
+		desc->addr = buf_addr;
+
+		skb_put(skb, pkt_len);
 		skb->protocol = eth_type_trans(skb, priv->ndev);
 
 		if (priv->rx_cksum_offload_flag &&
-		    rx_info.rx_cksum_result == NETSEC_RX_CKSUM_OK)
+		    rpi.rx_cksum_result == NETSEC_RX_CKSUM_OK)
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 		if (napi_gro_receive(&priv->napi, skb) != GRO_DROP) {
 			ndev->stats.rx_packets++;
-			ndev->stats.rx_bytes += len;
+			ndev->stats.rx_bytes += pkt_len;
 		}
+
+		netsec_rx_fill(priv, idx, 1);
+		nsetsec_adv_desc(&dring->tail);
 	}
 
 	return done;
@@ -928,7 +900,10 @@ static void netsec_uninit_pkt_dring(struct netsec_priv *priv, int id)
 		dma_unmap_single(priv->dev, desc->dma_addr, desc->len,
 				 id == NETSEC_RING_RX ? DMA_FROM_DEVICE :
 							      DMA_TO_DEVICE);
-		dev_kfree_skb(desc->skb);
+		if (id == NETSEC_RING_RX)
+			skb_free_frag(desc->addr);
+		else if (id == NETSEC_RING_TX)
+			dev_kfree_skb(desc->skb);
 	}
 
 	memset(dring->desc, 0, sizeof(struct netsec_desc) * DESC_NUM);
@@ -953,50 +928,96 @@ static void netsec_free_dring(struct netsec_priv *priv, int id)
 	dring->desc = NULL;
 }
 
+static void *netsec_alloc_rx_data(struct netsec_priv *priv,
+				  dma_addr_t *dma_handle, u16 *desc_len)
+{
+	size_t len = priv->ndev->mtu + ETH_HLEN + VLAN_HLEN * 2 + NET_SKB_PAD +
+		NET_IP_ALIGN;
+	dma_addr_t mapping;
+	void *buf;
+
+	len = SKB_DATA_ALIGN(len);
+	len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+
+	buf = napi_alloc_frag(len);
+	if (!buf)
+		return NULL;
+
+	mapping = dma_map_single(priv->dev, buf, len, DMA_FROM_DEVICE);
+	if (unlikely(dma_mapping_error(priv->dev, mapping)))
+		goto err_out;
+
+	*dma_handle = mapping;
+	*desc_len = len;
+
+	return buf;
+
+err_out:
+	skb_free_frag(buf);
+	return NULL;
+}
+
+static void netsec_rx_fill(struct netsec_priv *priv, u16 from, u16 num)
+{
+	struct netsec_desc_ring *dring = &priv->desc_ring[NETSEC_RING_RX];
+	u16 idx = from;
+
+	while (num) {
+		netsec_set_rx_de(priv, dring, idx, &dring->desc[idx]);
+		idx++;
+		if (idx >= DESC_NUM)
+			idx = 0;
+		num--;
+	}
+}
+
 static int netsec_alloc_dring(struct netsec_priv *priv, enum ring_id id)
 {
 	struct netsec_desc_ring *dring = &priv->desc_ring[id];
-	int ret = 0;
 
 	dring->vaddr = dma_zalloc_coherent(priv->dev, DESC_SZ * DESC_NUM,
 					   &dring->desc_dma, GFP_KERNEL);
-	if (!dring->vaddr) {
-		ret = -ENOMEM;
+	if (!dring->vaddr)
 		goto err;
-	}
 
 	dring->desc = kcalloc(DESC_NUM, sizeof(*dring->desc), GFP_KERNEL);
-	if (!dring->desc) {
-		ret = -ENOMEM;
+	if (!dring->desc)
 		goto err;
-	}
 
 	return 0;
 err:
 	netsec_free_dring(priv, id);
 
-	return ret;
+	return -ENOMEM;
 }
 
 static int netsec_setup_rx_dring(struct netsec_priv *priv)
 {
 	struct netsec_desc_ring *dring = &priv->desc_ring[NETSEC_RING_RX];
-	struct netsec_desc desc;
-	struct sk_buff *skb;
-	int n;
+	int i;
 
-	desc.len = priv->ndev->mtu + 22;
+	for (i = 0; i < DESC_NUM; i++) {
+		struct netsec_desc *desc = &dring->desc[i];
+		dma_addr_t dma_handle;
+		void *buf;
+		u16 len;
 
-	for (n = 0; n < DESC_NUM; n++) {
-		skb = netsec_alloc_skb(priv, &desc);
-		if (!skb) {
+		buf = netsec_alloc_rx_data(priv, &dma_handle, &len);
+		if (!buf) {
 			netsec_uninit_pkt_dring(priv, NETSEC_RING_RX);
-			return -ENOMEM;
+			goto err_out;
 		}
-		netsec_set_rx_de(priv, dring, n, &desc, skb);
+		desc->dma_addr = dma_handle;
+		desc->addr = buf;
+		desc->len = len;
 	}
 
+	netsec_rx_fill(priv, 0, DESC_NUM);
+
 	return 0;
+
+err_out:
+	return -ENOMEM;
 }
 
 static int netsec_netdev_load_ucode_region(struct netsec_priv *priv, u32 reg,
-- 
2.7.4

^ permalink raw reply related

* [net-next, PATCH 0/2, v2]  net: socionext: add XDP support
From: Ilias Apalodimas @ 2018-09-12  9:02 UTC (permalink / raw)
  To: netdev, jaswinder.singh
  Cc: ard.biesheuvel, masami.hiramatsu, arnd, mykyta.iziumtsev,
	bjorn.topel, magnus.karlsson, brouer, daniel, ast,
	Ilias Apalodimas

This patch series adds AF_XDP support socionext netsec driver
In addition the new dma allocation scheme offers a 10% boost on Rx
pps rate using 64b packets

- patch [1/2]: Use a different allocation scheme for Rx DMA buffers to prepare
the driver for AF_XDP support
- patch [2/2]: Add XDP support without zero-copy

Changes since v1:
- patch [2/2]: 
	- Rephrased commit message
	- As pointed out by Toshiaki Makita: 
	 - Added XDP_PACKET_HEADROOM
	 - Fixed a bug on XDP_PASS case as pointed out by Toshiaki Makita
	 - Using extact for error messaging instead of netdev_warn, when 
	tryint to setup XDP as suggested by Toshiaki Makita

Ilias Apalodimas (2):
  net: socionext: different approach on DMA
  net: socionext: add XDP support

 drivers/net/ethernet/socionext/netsec.c | 449 ++++++++++++++++++++++++--------
 1 file changed, 334 insertions(+), 115 deletions(-)

-- 
2.7.4

^ permalink raw reply

* Re: [PATCH net-next v2] net: sched: change tcf_del_walker() to take idrinfo->lock
From: Vlad Buslov @ 2018-09-12  8:50 UTC (permalink / raw)
  To: Cong Wang
  Cc: Linux Kernel Network Developers, Jamal Hadi Salim, Jiri Pirko,
	David Miller
In-Reply-To: <CAM_iQpW1z+dNLiazr87HupqzYPeBnFR5fyVfsXkhwZcRW0LrSA@mail.gmail.com>


On Fri 07 Sep 2018 at 19:12, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> On Fri, Sep 7, 2018 at 6:52 AM Vlad Buslov <vladbu@mellanox.com> wrote:
>>
>> Action API was changed to work with actions and action_idr in concurrency
>> safe manner, however tcf_del_walker() still uses actions without taking a
>> reference or idrinfo->lock first, and deletes them directly, disregarding
>> possible concurrent delete.
>>
>> Add tc_action_wq workqueue to action API. Implement
>> tcf_idr_release_unsafe() that assumes external synchronization by caller
>> and delays blocking action cleanup part to tc_action_wq workqueue. Extend
>> tcf_action_cleanup() with 'async' argument to indicate that function should
>> free action asynchronously.
>
> Where exactly is blocking in tcf_action_cleanup()?
>
> From your code, it looks like free_tcf(), but from my observation,
> the only blocking function inside is tcf_action_goto_chain_fini()
> which calls __tcf_chain_put(). But, __tcf_chain_put() is blocking
> _ONLY_ when tc_chain_notify() is called, for tc action it is never
> called.
>
> So, what else is blocking?

__tcf_chain_put() calls tc_chain_tmplt_del(), which calls
ops->tmplt_destroy(). This last function uses hw offload API, which is
blocking.

^ permalink raw reply

* Re: kernels > v4.12 oops/crash with ipsec-traffic: bisected to b838d5e1c5b6e57b10ec8af2268824041e3ea911: ipv4: mark DST_NOGC and remove the operation of dst_free()
From: Steffen Klassert @ 2018-09-12  8:50 UTC (permalink / raw)
  To: Tobias Hommel
  Cc: Wolfgang Walter, Kristian Evensen, Network Development, weiwan,
	edumazet
In-Reply-To: <20180911190248.hj55ultypwnnkcnx@delI>

On Tue, Sep 11, 2018 at 09:02:48PM +0200, Tobias Hommel wrote:
> > > Subject: [PATCH RFC] xfrm: Fix NULL pointer dereference when skb_dst_force
> > > clears the dst_entry.
> > > 
> > > Since commit 222d7dbd258d ("net: prevent dst uses after free")
> > > skb_dst_force() might clear the dst_entry attached to the skb.
> > > The xfrm code don't expect this to happen, so we crash with
> > > a NULL pointer dereference in this case. Fix it by checking
> > > skb_dst(skb) for NULL after skb_dst_force() and drop the packet
> > > in cast the dst_entry was cleared.
> > > 
> > > Fixes: 222d7dbd258d ("net: prevent dst uses after free")
> > > Reported-by: Tobias Hommel <netdev-list@genoetigt.de>
> > > Reported-by: Kristian Evensen <kristian.evensen@gmail.com>
> > > Reported-by: Wolfgang Walter <linux@stwm.de>
> > > Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
> > > ---
> > 
> > This patch fixes the problem here.
> > 
> > XfrmFwdHdrError gets around 80 at the very beginning and remains so. Probably 
> > this happens when some route are changed/set then. 
> > 
> > Regards and thanks,
> 
> Same here, we're now running stable for ~6 hours, XfrmFwdHdrError is at 220.
> This is less than 1 lost packet per minute, which seems to be okay for now.

Thanks a lot for testing! This is now applied to the ipsec tree.

^ permalink raw reply

* Re: [RFC v2 2/2] netlink: add ethernet address policy types
From: Johannes Berg @ 2018-09-12  8:50 UTC (permalink / raw)
  To: Arend van Spriel, linux-wireless, netdev; +Cc: Michal Kubecek
In-Reply-To: <5B98D336.4090107@broadcom.com>

On Wed, 2018-09-12 at 10:49 +0200, Arend van Spriel wrote:
> On 9/12/2018 10:36 AM, Johannes Berg wrote:
> > From: Johannes Berg <johannes.berg@intel.com>
> > 
> > Commonly, ethernet addresses are just using a policy of
> > 	{ .len = ETH_ALEN }
> > which leaves userspace free to send more data than it should,
> > which may hide bugs.
> > 
> > Introduce NLA_ETH_ADDR which checks for exact size, and rejects
> > the attribute if the length isn't ETH_ALEN.
> > 
> > Also add NLA_ETH_ADDR_COMPAT which can be used in place of the
> > policy above, but will, in addition, warn on an address that's
> > too long.
> 
> Not sure if this is correctly described here. It seems longer addresses 
> are not rejected, but only result in a warning message. I guess the 
> problem is in the reference to the "policy above" ;-)

Yeah, good point. I meant ".len = ETH_ALEN" but should clarify that.

johannes

^ permalink raw reply

* Re: [RFC v2 2/2] netlink: add ethernet address policy types
From: Arend van Spriel @ 2018-09-12  8:49 UTC (permalink / raw)
  To: Johannes Berg, linux-wireless, netdev; +Cc: Michal Kubecek, Johannes Berg
In-Reply-To: <20180912083610.20857-2-johannes@sipsolutions.net>

On 9/12/2018 10:36 AM, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
>
> Commonly, ethernet addresses are just using a policy of
> 	{ .len = ETH_ALEN }
> which leaves userspace free to send more data than it should,
> which may hide bugs.
>
> Introduce NLA_ETH_ADDR which checks for exact size, and rejects
> the attribute if the length isn't ETH_ALEN.
>
> Also add NLA_ETH_ADDR_COMPAT which can be used in place of the
> policy above, but will, in addition, warn on an address that's
> too long.

Not sure if this is correctly described here. It seems longer addresses 
are not rejected, but only result in a warning message. I guess the 
problem is in the reference to the "policy above" ;-)

Regards,
Arend

^ permalink raw reply

* Re: [PATCH] net: dsa: mv88e6xxx: Add MV88E6352 DT compatible
From: Marek Vasut @ 2018-09-12  8:38 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev
In-Reply-To: <20180912004602.GA14588@lunn.ch>

On 09/12/2018 02:46 AM, Andrew Lunn wrote:
> On Wed, Sep 12, 2018 at 02:04:54AM +0200, Marek Vasut wrote:
>> On 09/12/2018 01:32 AM, Andrew Lunn wrote:
>>>> compatible = "marvell,mv88e6352", "marvell,mv88e6085";
>>>
>>> Just "marvell,mv88e6085";
>>>
>>> Please take a look at all the other DT files using the Marvell
>>> chips. You will only ever find "marvell,mv88e6085" or
>>> "marvell,mv88e6190", because everything is compatible to one of these
>>> two.
>>
>> Well, until you find a difference between those chips which you cannot
>> discern based solely on the ID register content. Then it's better to
>> have a compatible to match on which matches the actual chip.
> 
> Hi Marek
> 
> We have been around this loop before. The problem with putting in a
> more specific compatible is that nothing is validating it. So it is
> going to be wrong, simple because people cut/paste, and don't
> necessary change it. So when we do need to look at it, we cannot look
> at it, because it is wrong.
> 
> I would only add a more specific compatible if and when we need it, it
> is actually used, and we can verify it is correct.

You may need it in the future and it may not be possible to adjust the
DT then. So having a specific compatible and fallback compatible is I
think the way to go. You can always match on the fallback and if the
time comes, you can match on the specific one because it's there. In
addition to that, such a DT would fully correctly describe the hardware,
unlike one with only a fallback compatible.

Regarding validation, I don't see other systems using this approach
(specific + fallback compatible) having a problem with validation.
What is the trick there ?

-- 
Best regards,
Marek Vasut

^ permalink raw reply

* Re: [RFC v2 1/2] netlink: add NLA_REJECT policy type
From: Johannes Berg @ 2018-09-12  8:38 UTC (permalink / raw)
  To: linux-wireless, netdev; +Cc: Michal Kubecek
In-Reply-To: <20180912083610.20857-1-johannes@sipsolutions.net>

On Wed, 2018-09-12 at 10:36 +0200, Johannes Berg wrote:
> @@ -251,7 +257,7 @@ int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
>  
>  		if (type > 0 && type <= maxtype) {
>  			if (policy) {
> -				err = validate_nla(nla, maxtype, policy);
> +				err = validate_nla(nla, maxtype, policy, extack);
>  				if (err < 0) {
>  					NL_SET_ERR_MSG_ATTR(extack, nla,
>  							    "Attribute failed policy validation");

Err... I should read my patches before sending them :-)

Clearly, this NL_SET_ERR_MSG_ATTR() overwrites the error message, so
would have to be made conditional.

I can fix that (and I should use/test it) if we decide it's worthwhile.

johannes

^ permalink raw reply

* Re: [PATCH net-next 13/13] net: sched: add flags to Qdisc class ops struct
From: Vlad Buslov @ 2018-09-12  8:25 UTC (permalink / raw)
  To: Cong Wang
  Cc: Linux Kernel Network Developers, Jamal Hadi Salim, Jiri Pirko,
	David Miller, Stephen Hemminger, Kirill Tkhai, Paul E. McKenney,
	Nicolas Dichtel, Leon Romanovsky, Greg KH, mark.rutland,
	Florian Westphal, David Ahern, lucien xin, Jakub Kicinski,
	Christian Brauner, Jiri Benc
In-Reply-To: <CAM_iQpU2FxihLKBpQkUP2RPfXe=eygd8QmLkE+VYhFEnuyrf3g@mail.gmail.com>


On Fri 07 Sep 2018 at 19:50, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> On Thu, Sep 6, 2018 at 12:59 AM Vlad Buslov <vladbu@mellanox.com> wrote:
>>
>> Extend Qdisc_class_ops with flags. Create enum to hold possible class ops
>> flag values. Add first class ops flags value QDISC_CLASS_OPS_DOIT_UNLOCKED
>> to indicate that class ops functions can be called without taking rtnl
>> lock.
>
> We don't add anything that is not used.
>
> This is the last patch in this series, so I am pretty sure you split
> it in a wrong way, it certainly belongs to next series, not this series.

Will do.

Thank you for reviewing my code!

^ permalink raw reply

* Re: [PATCH net-next 09/13] net: sched: extend tcf_block with rcu
From: Vlad Buslov @ 2018-09-12  8:25 UTC (permalink / raw)
  To: Cong Wang
  Cc: Linux Kernel Network Developers, Jamal Hadi Salim, Jiri Pirko,
	David Miller, Stephen Hemminger, Kirill Tkhai, Paul E. McKenney,
	Nicolas Dichtel, Leon Romanovsky, Greg KH, mark.rutland,
	Florian Westphal, David Ahern, lucien xin, Jakub Kicinski,
	Christian Brauner, Jiri Benc
In-Reply-To: <CAM_iQpXf=WgBGb2+2bNp-w=hssmbjPX6RMvjCKv2EW53yeBsVw@mail.gmail.com>


On Fri 07 Sep 2018 at 19:52, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> On Thu, Sep 6, 2018 at 12:59 AM Vlad Buslov <vladbu@mellanox.com> wrote:
>>
>> Extend tcf_block with rcu to allow safe deallocation when it is accessed
>> concurrently.
>
> This sucks, please fold this patch into where you call rcu_read_lock()
> on tcf block.
>
> This patch _alone_ is apparently not complete. This is not how
> we split patches.

Got it.

^ permalink raw reply

* Re: [PATCH net-next 08/13] net: sched: rename tcf_block_get{_ext}() and tcf_block_put{_ext}()
From: Vlad Buslov @ 2018-09-12  8:24 UTC (permalink / raw)
  To: Cong Wang
  Cc: Linux Kernel Network Developers, Jamal Hadi Salim, Jiri Pirko,
	David Miller, Stephen Hemminger, Kirill Tkhai, Paul E. McKenney,
	Nicolas Dichtel, Leon Romanovsky, Greg KH, mark.rutland,
	Florian Westphal, David Ahern, lucien xin, Jakub Kicinski,
	Christian Brauner, Jiri Benc
In-Reply-To: <CAM_iQpVMU7nPgkw+N_V6ukrH5rx-37+nd+++wj47JRA33RqMUQ@mail.gmail.com>


On Fri 07 Sep 2018 at 20:09, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> On Thu, Sep 6, 2018 at 12:59 AM Vlad Buslov <vladbu@mellanox.com> wrote:
>>
>> Functions tcf_block_get{_ext}() and tcf_block_put{_ext}() actually
>> attach/detach block to specific Qdisc besides just taking/putting
>> reference. Rename them according to their purpose.
>
> Where exactly does it attach to?
>
> Each qdisc provides a pointer to a pointer of a block, like
> &cl->block. It is where the result is saved to. It takes a parameter
> of Qdisc* merely for read-only purpose.

tcf_block_attach_ext() passes qdisc parameter to tcf_block_owner_add()
which saves qdisc to new tcf_block_owner_item and adds the item to
block's owner list. I proposed several naming options for these
functions to Jiri on internal review and he suggested "attach" as better
option.

>
> So, renaming it to *attach() is even confusing, at least not
> any better. Please find other names or leave them as they are.

What would you recommend?

^ 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