* Re: [SPAM]Re: [PATCH] net: mediatek: use dma_zalloc_coherent instead of allocator/memset
From: YueHaibing @ 2018-07-20 14:16 UTC (permalink / raw)
To: Sean Wang
Cc: nbd, nelson.chang, netdev, Russell King - ARM Linux, linux-kernel,
linux-mediatek, john, matthias.bgg, davem, linux-arm-kernel
In-Reply-To: <1532095058.8953.264.camel@mtkswgap22>
On 2018/7/20 21:57, Sean Wang wrote:
> On Fri, 2018-07-20 at 21:33 +0800, YueHaibing wrote:
>> On 2018/7/20 16:13, Russell King - ARM Linux wrote:
>>> On Fri, Jul 20, 2018 at 02:30:53PM +0800, YueHaibing wrote:
>>>> On 2018/7/20 1:02, Sean Wang wrote:
>>>>> On Thu, 2018-07-19 at 15:17 +0100, Russell King - ARM Linux wrote:
>>>>>> On Thu, Jul 19, 2018 at 10:09:55PM +0800, YueHaibing wrote:
>>>>>>> Use dma_zalloc_coherent instead of dma_alloc_coherent
>>>>>>> followed by memset 0.
>>>>>>>
>>>>>>> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
>>>>>>> ---
>>>>>>> drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 ++-----
>>>>>>> 1 file changed, 2 insertions(+), 5 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
>>>>>>> index d8ebf0a..fbdb3e3 100644
>>>>>>> --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
>>>>>>> +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
>>>>>>> @@ -1221,14 +1221,11 @@ static int mtk_tx_alloc(struct mtk_eth *eth)
>>>>>>> if (!ring->buf)
>>>>>>> goto no_tx_mem;
>>>>>>>
>>>>>>> - ring->dma = dma_alloc_coherent(eth->dev,
>>>>>>> - MTK_DMA_SIZE * sz,
>>>>>>> - &ring->phys,
>>>>>>> - GFP_ATOMIC | __GFP_ZERO);
>>>>>>> + ring->dma = dma_zalloc_coherent(eth->dev, MTK_DMA_SIZE * sz,
>>>>>>> + &ring->phys, GFP_ATOMIC | __GFP_ZERO);
>>>>>>> if (!ring->dma)
>>>>>>> goto no_tx_mem;
>>>>>>>
>>>>>>> - memset(ring->dma, 0, MTK_DMA_SIZE * sz);
>>>>>>
>>>>>> I have to wonder whether this code needs two forms of zeroing... in
>>>>>> the original code, __GFP_ZERO _and_ a call to memset() just in case
>>>>>> __GFP_ZERO failed to do its job, and in the replacement code, just
>>>>>> in case dma_zalloc_coherent() hasn't got the idea...
>>>>>>
>>>>>> I think you can drop the __GFP_ZERO. ;)
>>>>>>
>>>>>
>>>>> Just now I did an experiment on 4.14.56 on armv7. I found that
>>>>> dma_zalloc_coherent does not guarantee that the buffer we get
>>>>> is all filled with 0.
>>>>>
>>>>>
>>>>> I really think it's a little bit weird OR what was I missing something
>>>>> for enabling dma_zalloc_coherent ? The result seems to tell that we
>>>>> can't remove freely the memset with 0 at this moment until we get a
>>>>> cause.
>>>>>
>>>>
>>>> That means dma_zalloc_coherent doesn't work as expect on armv7?
>>>
>>> Can someone work out which underlying allocator is being used - the
>>> possibilities are:
>>>
>>> - dma_alloc_from_dev_coherent
>>> - cma
>>> - simple
>>> - remap
>>> - pool
>>>
>>> Looking at the code, I'd guess it's the pool allocator, as I don't see
>>> anything which zeros memory there, and it doesn't honor the __GFP_ZERO
>>> flag. This is definitely an allocator bug.
>>>
>>
>> Sean,
>>
>> can you test bellow patch:
>>
>>
>> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
>> index be0fa7e..52029bb 100644
>> --- a/arch/arm/mm/dma-mapping.c
>> +++ b/arch/arm/mm/dma-mapping.c
>> @@ -564,6 +564,7 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page)
>>
>> *ret_page = phys_to_page(phys);
>> ptr = (void *)val;
>> + memset(ptr, 0, size);
>> }
>>
>
> it should work. but don't we need to compare gfp against __GFP_ZERO
> before zeros buffer ?
>
arm64 zero it unconditionally in __alloc_from_pool.
>
>
> .
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 02/38] netfilter: flowtables: use fixed renew timeout on teardown
From: Florian Westphal @ 2018-07-20 13:32 UTC (permalink / raw)
To: Felix Fietkau; +Cc: Pablo Neira Ayuso, netfilter-devel, davem, netdev
In-Reply-To: <2b757614-c824-cc1b-7ebb-925c2e963830@nbd.name>
Felix Fietkau <nbd@nbd.name> wrote:
> On 2018-07-20 15:08, Pablo Neira Ayuso wrote:
> > From: Florian Westphal <fw@strlen.de>
> >
> > This is one of the very few external callers of ->get_timeouts(),
> >
> > We can use a fixed timeout instead, conntrack core will refresh this in
> > case a new packet comes within this period.
> >
> > Use of ESTABLISHED timeout seems way too huge anyway.
> It seems to me that this could easily break long-lived connections that
> are idle most of the time.
Problem is that we don't know state of connection, since it was
offloaded.
We don't know if connection 'died' with unacked data (short default
timeout) or not (long default timeout).
So I would prefer to err on the 'evict idle connection that had no
keepalives early' side rather than the 'add dead connection hanging
around forever'.
^ permalink raw reply
* Re: [PATCH v3 3/3] net: add MTD support to eth_platform_get_mac_address()
From: Andrew Lunn @ 2018-07-20 14:28 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Sekhar Nori, Kevin Hilman, Russell King, Grygorii Strashko,
David S . Miller, Srinivas Kandagatla, Lukas Wunner, Rob Herring,
Florian Fainelli, Dan Carpenter, Ivan Khoronzhuk, David Lechner,
Greg Kroah-Hartman, linux-arm-kernel, linux-kernel, linux-omap,
netdev, Bartosz Golaszewski
In-Reply-To: <20180719153243.20944-4-brgl@bgdev.pl>
On Thu, Jul 19, 2018 at 05:32:43PM +0200, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>
> MTD doesn't support nvmem yet. Some platforms use MTD to read the MAC
> address from SPI flash. If we want this function to generalize reading
> the MAC address, we need to separately try to use MTD.
How many board files are doing this? It is only worth generlizing if
there are a number of board files, all just pulling 6 bytes out from
the beginning of an MTD partition.
It is also normal to actually add a user of a new feature at the same
time as the new feature. It can be messy when it is across subsystem
boundaries, but please at least try.
Andrew
^ permalink raw reply
* Re: [PATCH v2 1/5] can: enable multi-queue for SocketCAN devices
From: Marc Kleine-Budde @ 2018-07-20 14:34 UTC (permalink / raw)
To: Mark Jonas, Wolfgang Grandegger
Cc: linux-can, netdev, linux-kernel, hs, yi.zhu5, petar.petrovic2,
stephan.baetge, andy.shevchenko, socketcan, o.rempel
In-Reply-To: <1528900641-18677-2-git-send-email-mark.jonas@de.bosch.com>
[-- Attachment #1.1: Type: text/plain, Size: 1552 bytes --]
On 06/13/2018 04:37 PM, Mark Jonas wrote:
> From: Zhu Yi <yi.zhu5@cn.bosch.com>
>
> The existing SocketCAN implementation provides alloc_candev() to
> allocate a CAN device using a single Tx and Rx queue. This can lead to
> priority inversion in case the single Tx queue is already full with low
> priority messages and a high priority message needs to be sent while the
> bus is fully loaded with medium priority messages.
>
> This problem can be solved by using the existing multi-queue support of
> the network subsytem. The commit makes it possible to use multi-queue in
> the CAN subsystem in the same way it is used in the Ethernet subsystem
> by adding an alloc_candev_mqs() call and accompanying macros. With this
> support a CAN device can use multi-queue qdisc (e.g. mqprio) to avoid
> the aforementioned priority inversion.
>
> The exisiting functionality of alloc_candev() is the same as before.
>
> CAN devices need to have prioritized multiple hardware queues or are
> able to abort waiting for arbitration to make sensible use of
> multi-queues.
>
> Signed-off-by: Zhu Yi <yi.zhu5@cn.bosch.com>
> Signed-off-by: Mark Jonas <mark.jonas@de.bosch.com>
> Reviewed-by: Heiko Schocher <hs@denx.de>
Applied to linux-can-next.
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH v2 0/5] can: enable multi-queue for SocketCAN devices
From: Marc Kleine-Budde @ 2018-07-20 14:36 UTC (permalink / raw)
To: Jonas Mark (BT-FIR/ENG1), Wolfgang Grandegger
Cc: linux-can@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, hs@denx.de,
ZHU Yi (BT-FIR/ENG1-Zhu), Petrovic Petar (CM-CI1/ENP1),
Baetge Stephan (CM-CI1/ENP1), andy.shevchenko@gmail.com,
socketcan@hartkopp.net, o.rempel@pengutronix.de
In-Reply-To: <f858e62c59754a0c9f785b3dfc7aa50f@de.bosch.com>
[-- Attachment #1.1: Type: text/plain, Size: 711 bytes --]
On 07/11/2018 07:00 PM, Jonas Mark (BT-FIR/ENG1) wrote:
> Hi Marc,
>
>> Betreff: [PATCH v2 0/5] can: enable multi-queue for SocketCAN devices
>
> You have been interested in seeing the reason why we are proposing the
> "can: enable multi-queue for SocketCAN devices" patch for the Linux
> mainline. So far I have not heard from you. Do you now see a chance of
> getting the patch accepted?
I've applied patch 1.
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH net-next,v2] net: rename ndo_setup_tc to ndo_setup_offload
From: Florian Fainelli @ 2018-07-20 14:01 UTC (permalink / raw)
To: Pablo Neira Ayuso, netdev
Cc: jiri, thomas.lendacky, ariel.elior, michael.chan, santosh,
madalin.bucur, yisen.zhuang, salil.mehta, jeffrey.t.kirsher,
tariqt, saeedm, jiri, idosch, ganeshgr, jakub.kicinski,
linux-net-drivers, peppe.cavallaro, alexandre.torgue, joabreu,
grygorii.strashko, andrew, vivien.didelot
In-Reply-To: <20180719001114.4883-1-pablo@netfilter.org>
On 07/18/2018 05:11 PM, Pablo Neira Ayuso wrote:
> One of the recurring complaints is that we do not have, as a driver
> writer, a central location from which we would be fed offloading rules
> into a NIC. This was brought up again during Netconf'18 in Boston.
>
> This patch just renames ndo_setup_tc to ndo_setup_offload as a very
> early initial work to prepare for follow up patch that discuss unified
> flow representation for the existing offload programming APIs.
>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> Acked-by: Jiri Pirko <jiri@mellanox.com>
> Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Thanks Pablo!
--
Florian
^ permalink raw reply
* Re: [PATCH net-next,v2] net: rename ndo_setup_tc to ndo_setup_offload
From: Roopa Prabhu @ 2018-07-20 14:37 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: netdev, Jiří Pírko, thomas.lendacky,
Florian Fainelli, Elior, Ariel, Michael Chan, Santosh Rastapur,
madalin.bucur, yisen.zhuang, salil.mehta, Jeff Kirsher, tariqt,
Saeed Mahameed, Jiri Pirko, Ido Schimmel, Ganesh GR,
Jakub Kicinski, linux-net-drivers, peppe.cavallaro,
alexandre.torgue, joabreu, grygorii.strashko, Andrew Lunn
On Wed, Jul 18, 2018 at 5:11 PM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> One of the recurring complaints is that we do not have, as a driver
> writer, a central location from which we would be fed offloading rules
> into a NIC. This was brought up again during Netconf'18 in Boston.
>
> This patch just renames ndo_setup_tc to ndo_setup_offload as a very
> early initial work to prepare for follow up patch that discuss unified
> flow representation for the existing offload programming APIs.
>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> Acked-by: Jiri Pirko <jiri@mellanox.com>
> Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
ok with a rename,...but this seems to be going from a very specific to
a completely generic name.
maybe ndo_setup_flow_offload or ndo_setup_rule_offload might be better ?.
(or maybe i am missing some context and this is really for setting up
every possible hardware offload ?)
> ---
> v2: Missing function definition update in drivers/net/ethernet/sfc/falcon/tx.c
> apparently I forgot to turn on that driver when doing compile-testing,
> problem spotted by Martin Habets. Keeping Jakub and Jiri Acked-by tags,
> as this is the only change in the v1 patch.
>
> drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 6 +++---
> drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 6 +++---
> drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 4 ++--
> drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +-
> drivers/net/ethernet/broadcom/bnxt/bnxt.c | 6 +++---
> drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 6 +++---
> drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 6 +++---
> drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 6 +++---
> drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 6 +++---
> drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 6 +++---
> drivers/net/ethernet/intel/i40e/i40e_main.c | 6 +++---
> drivers/net/ethernet/intel/i40evf/i40evf_main.c | 8 ++++----
> drivers/net/ethernet/intel/igb/igb_main.c | 6 +++---
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 6 +++---
> drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 9 +++++----
> drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 6 +++---
> drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 6 +++---
> drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 6 +++---
> drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 2 +-
> drivers/net/ethernet/netronome/nfp/nfp_net_repr.c | 2 +-
> drivers/net/ethernet/netronome/nfp/nfp_port.c | 4 ++--
> drivers/net/ethernet/netronome/nfp/nfp_port.h | 4 ++--
> drivers/net/ethernet/sfc/efx.c | 2 +-
> drivers/net/ethernet/sfc/efx.h | 4 ++--
> drivers/net/ethernet/sfc/falcon/efx.c | 2 +-
> drivers/net/ethernet/sfc/falcon/efx.h | 4 ++--
> drivers/net/ethernet/sfc/falcon/tx.c | 4 ++--
> drivers/net/ethernet/sfc/tx.c | 4 ++--
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++---
> drivers/net/ethernet/ti/netcp_core.c | 6 +++---
> drivers/net/netdevsim/netdev.c | 5 +++--
> include/linux/netdevice.h | 18 +++++++++---------
> net/dsa/slave.c | 7 ++++---
> net/sched/cls_api.c | 6 +++---
> net/sched/sch_cbs.c | 8 ++++----
> net/sched/sch_etf.c | 8 ++++----
> net/sched/sch_mq.c | 8 ++++----
> net/sched/sch_mqprio.c | 16 ++++++++--------
> net/sched/sch_prio.c | 15 ++++++++-------
> net/sched/sch_red.c | 15 ++++++++-------
> 40 files changed, 131 insertions(+), 126 deletions(-)
>
> diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
> index 24f1053b8785..766864a35648 100644
> --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
> +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
> @@ -2246,8 +2246,8 @@ static void xgbe_poll_controller(struct net_device *netdev)
> }
> #endif /* End CONFIG_NET_POLL_CONTROLLER */
>
> -static int xgbe_setup_tc(struct net_device *netdev, enum tc_setup_type type,
> - void *type_data)
> +static int xgbe_setup_offload(struct net_device *netdev,
> + enum tc_setup_type type, void *type_data)
> {
> struct xgbe_prv_data *pdata = netdev_priv(netdev);
> struct tc_mqprio_qopt *mqprio = type_data;
> @@ -2501,7 +2501,7 @@ static const struct net_device_ops xgbe_netdev_ops = {
> #ifdef CONFIG_NET_POLL_CONTROLLER
> .ndo_poll_controller = xgbe_poll_controller,
> #endif
> - .ndo_setup_tc = xgbe_setup_tc,
> + .ndo_setup_offload = xgbe_setup_offload,
> .ndo_fix_features = xgbe_fix_features,
> .ndo_set_features = xgbe_set_features,
> .ndo_udp_tunnel_add = xgbe_udp_tunnel_add,
> diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
> index 5a727d4729da..200a5938dfe5 100644
> --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
> +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
> @@ -4228,7 +4228,7 @@ void bnx2x_get_c2s_mapping(struct bnx2x *bp, u8 *c2s_map, u8 *c2s_default)
> * @netdev: net device to configure
> * @tc: number of traffic classes to enable
> *
> - * callback connected to the ndo_setup_tc function pointer
> + * callback connected to the ndo_setup_offload function pointer
> */
> int bnx2x_setup_tc(struct net_device *dev, u8 num_tc)
> {
> @@ -4293,8 +4293,8 @@ int bnx2x_setup_tc(struct net_device *dev, u8 num_tc)
> return 0;
> }
>
> -int __bnx2x_setup_tc(struct net_device *dev, enum tc_setup_type type,
> - void *type_data)
> +int __bnx2x_setup_offload(struct net_device *dev, enum tc_setup_type type,
> + void *type_data)
> {
> struct tc_mqprio_qopt *mqprio = type_data;
>
> diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
> index 0e508e5defce..e3df86f8d140 100644
> --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
> +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
> @@ -486,8 +486,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev);
>
> /* setup_tc callback */
> int bnx2x_setup_tc(struct net_device *dev, u8 num_tc);
> -int __bnx2x_setup_tc(struct net_device *dev, enum tc_setup_type type,
> - void *type_data);
> +int __bnx2x_setup_offload(struct net_device *dev, enum tc_setup_type type,
> + void *type_data);
>
> int bnx2x_get_vf_config(struct net_device *dev, int vf,
> struct ifla_vf_info *ivi);
> diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
> index 71362b7f6040..b238f3478a2f 100644
> --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
> +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
> @@ -13116,7 +13116,7 @@ static const struct net_device_ops bnx2x_netdev_ops = {
> #ifdef CONFIG_NET_POLL_CONTROLLER
> .ndo_poll_controller = poll_bnx2x,
> #endif
> - .ndo_setup_tc = __bnx2x_setup_tc,
> + .ndo_setup_offload = __bnx2x_setup_offload,
> #ifdef CONFIG_BNX2X_SRIOV
> .ndo_set_vf_mac = bnx2x_set_vf_mac,
> .ndo_set_vf_vlan = bnx2x_set_vf_vlan,
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> index d2dadade1d0e..e38e1cdd4e02 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> @@ -7993,8 +7993,8 @@ static int bnxt_setup_tc_block(struct net_device *dev,
> }
> }
>
> -static int bnxt_setup_tc(struct net_device *dev, enum tc_setup_type type,
> - void *type_data)
> +static int bnxt_setup_offload(struct net_device *dev, enum tc_setup_type type,
> + void *type_data)
> {
> switch (type) {
> case TC_SETUP_BLOCK:
> @@ -8377,7 +8377,7 @@ static const struct net_device_ops bnxt_netdev_ops = {
> #ifdef CONFIG_NET_POLL_CONTROLLER
> .ndo_poll_controller = bnxt_poll_controller,
> #endif
> - .ndo_setup_tc = bnxt_setup_tc,
> + .ndo_setup_offload = bnxt_setup_offload,
> #ifdef CONFIG_RFS_ACCEL
> .ndo_rx_flow_steer = bnxt_rx_flow_steer,
> #endif
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
> index e31f5d803c13..76abfd943d7c 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
> @@ -183,8 +183,8 @@ static int bnxt_vf_rep_setup_tc_block(struct net_device *dev,
> }
> }
>
> -static int bnxt_vf_rep_setup_tc(struct net_device *dev, enum tc_setup_type type,
> - void *type_data)
> +static int bnxt_vf_rep_setup_offload(struct net_device *dev,
> + enum tc_setup_type type, void *type_data)
> {
> switch (type) {
> case TC_SETUP_BLOCK:
> @@ -263,7 +263,7 @@ static const struct net_device_ops bnxt_vf_rep_netdev_ops = {
> .ndo_stop = bnxt_vf_rep_close,
> .ndo_start_xmit = bnxt_vf_rep_xmit,
> .ndo_get_stats64 = bnxt_vf_rep_get_stats64,
> - .ndo_setup_tc = bnxt_vf_rep_setup_tc,
> + .ndo_setup_offload = bnxt_vf_rep_setup_offload,
> .ndo_get_phys_port_name = bnxt_vf_rep_get_phys_port_name
> };
>
> diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
> index 40cf8dc9f163..899fe9921bdf 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
> +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
> @@ -3027,8 +3027,8 @@ static int cxgb_setup_tc_block(struct net_device *dev,
> }
> }
>
> -static int cxgb_setup_tc(struct net_device *dev, enum tc_setup_type type,
> - void *type_data)
> +static int cxgb_setup_offload(struct net_device *dev, enum tc_setup_type type,
> + void *type_data)
> {
> switch (type) {
> case TC_SETUP_BLOCK:
> @@ -3236,7 +3236,7 @@ static const struct net_device_ops cxgb4_netdev_ops = {
> .ndo_fcoe_disable = cxgb_fcoe_disable,
> #endif /* CONFIG_CHELSIO_T4_FCOE */
> .ndo_set_tx_maxrate = cxgb_set_tx_maxrate,
> - .ndo_setup_tc = cxgb_setup_tc,
> + .ndo_setup_offload = cxgb_setup_offload,
> .ndo_udp_tunnel_add = cxgb_add_udp_tunnel,
> .ndo_udp_tunnel_del = cxgb_del_udp_tunnel,
> .ndo_features_check = cxgb_features_check,
> diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> index 65a22cd9aef2..1537e92d147c 100644
> --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> @@ -346,8 +346,8 @@ static void dpaa_get_stats64(struct net_device *net_dev,
> }
> }
>
> -static int dpaa_setup_tc(struct net_device *net_dev, enum tc_setup_type type,
> - void *type_data)
> +static int dpaa_setup_offload(struct net_device *net_dev,
> + enum tc_setup_type type, void *type_data)
> {
> struct dpaa_priv *priv = netdev_priv(net_dev);
> struct tc_mqprio_qopt *mqprio = type_data;
> @@ -2619,7 +2619,7 @@ static const struct net_device_ops dpaa_ops = {
> .ndo_validate_addr = eth_validate_addr,
> .ndo_set_rx_mode = dpaa_set_rx_mode,
> .ndo_do_ioctl = dpaa_ioctl,
> - .ndo_setup_tc = dpaa_setup_tc,
> + .ndo_setup_offload = dpaa_setup_offload,
> };
>
> static int dpaa_napi_add(struct net_device *net_dev)
> diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
> index c211450bfd78..b5fdafff1ff7 100644
> --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
> +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
> @@ -1368,8 +1368,8 @@ static int hns3_setup_tc(struct net_device *netdev, void *type_data)
> return ret;
> }
>
> -static int hns3_nic_setup_tc(struct net_device *dev, enum tc_setup_type type,
> - void *type_data)
> +static int hns3_nic_setup_offload(struct net_device *dev,
> + enum tc_setup_type type, void *type_data)
> {
> if (type != TC_SETUP_QDISC_MQPRIO)
> return -EOPNOTSUPP;
> @@ -1543,7 +1543,7 @@ static const struct net_device_ops hns3_nic_netdev_ops = {
> .ndo_change_mtu = hns3_nic_change_mtu,
> .ndo_set_features = hns3_nic_set_features,
> .ndo_get_stats64 = hns3_nic_get_stats64,
> - .ndo_setup_tc = hns3_nic_setup_tc,
> + .ndo_setup_offload = hns3_nic_setup_offload,
> .ndo_set_rx_mode = hns3_nic_set_rx_mode,
> .ndo_vlan_rx_add_vid = hns3_vlan_rx_add_vid,
> .ndo_vlan_rx_kill_vid = hns3_vlan_rx_kill_vid,
> diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
> index 929f538d28bc..40bfc52f1928 100644
> --- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
> +++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
> @@ -1428,8 +1428,8 @@ int fm10k_setup_tc(struct net_device *dev, u8 tc)
> return err;
> }
>
> -static int __fm10k_setup_tc(struct net_device *dev, enum tc_setup_type type,
> - void *type_data)
> +static int __fm10k_setup_offload(struct net_device *dev,
> + enum tc_setup_type type, void *type_data)
> {
> struct tc_mqprio_qopt *mqprio = type_data;
>
> @@ -1639,7 +1639,7 @@ static const struct net_device_ops fm10k_netdev_ops = {
> .ndo_vlan_rx_kill_vid = fm10k_vlan_rx_kill_vid,
> .ndo_set_rx_mode = fm10k_set_rx_mode,
> .ndo_get_stats64 = fm10k_get_stats64,
> - .ndo_setup_tc = __fm10k_setup_tc,
> + .ndo_setup_offload = __fm10k_setup_offload,
> .ndo_set_vf_mac = fm10k_ndo_set_vf_mac,
> .ndo_set_vf_vlan = fm10k_ndo_set_vf_vlan,
> .ndo_set_vf_rate = fm10k_ndo_set_vf_bw,
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
> index 51762428b40e..f409ca5a9c9a 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -7563,8 +7563,8 @@ static int i40e_setup_tc_block(struct net_device *dev,
> }
> }
>
> -static int __i40e_setup_tc(struct net_device *netdev, enum tc_setup_type type,
> - void *type_data)
> +static int __i40e_setup_offload(struct net_device *netdev,
> + enum tc_setup_type type, void *type_data)
> {
> switch (type) {
> case TC_SETUP_QDISC_MQPRIO:
> @@ -11864,7 +11864,7 @@ static const struct net_device_ops i40e_netdev_ops = {
> #ifdef CONFIG_NET_POLL_CONTROLLER
> .ndo_poll_controller = i40e_netpoll,
> #endif
> - .ndo_setup_tc = __i40e_setup_tc,
> + .ndo_setup_offload = __i40e_setup_offload,
> .ndo_set_features = i40e_set_features,
> .ndo_set_vf_mac = i40e_ndo_set_vf_mac,
> .ndo_set_vf_vlan = i40e_ndo_set_vf_port_vlan,
> diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
> index 5906c1c1d19d..9c1111410f2b 100644
> --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
> +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
> @@ -2942,13 +2942,13 @@ static int i40evf_setup_tc_block(struct net_device *dev,
> * @type: type of offload
> * @type_date: tc offload data
> *
> - * This function is the callback to ndo_setup_tc in the
> + * This function is the callback to ndo_setup_offload in the
> * netdev_ops.
> *
> * Returns 0 on success
> **/
> -static int i40evf_setup_tc(struct net_device *netdev, enum tc_setup_type type,
> - void *type_data)
> +static int i40evf_setup_offload(struct net_device *netdev,
> + enum tc_setup_type type, void *type_data)
> {
> switch (type) {
> case TC_SETUP_QDISC_MQPRIO:
> @@ -3232,7 +3232,7 @@ static const struct net_device_ops i40evf_netdev_ops = {
> #ifdef CONFIG_NET_POLL_CONTROLLER
> .ndo_poll_controller = i40evf_netpoll,
> #endif
> - .ndo_setup_tc = i40evf_setup_tc,
> + .ndo_setup_offload = i40evf_setup_offload,
> };
>
> /**
> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
> index e3a0c02721c9..69b1633b6351 100644
> --- a/drivers/net/ethernet/intel/igb/igb_main.c
> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> @@ -2845,8 +2845,8 @@ static int igb_offload_txtime(struct igb_adapter *adapter,
> return 0;
> }
>
> -static int igb_setup_tc(struct net_device *dev, enum tc_setup_type type,
> - void *type_data)
> +static int igb_setup_offload(struct net_device *dev, enum tc_setup_type type,
> + void *type_data)
> {
> struct igb_adapter *adapter = netdev_priv(dev);
>
> @@ -2889,7 +2889,7 @@ static const struct net_device_ops igb_netdev_ops = {
> .ndo_set_features = igb_set_features,
> .ndo_fdb_add = igb_ndo_fdb_add,
> .ndo_features_check = igb_features_check,
> - .ndo_setup_tc = igb_setup_tc,
> + .ndo_setup_offload = igb_setup_offload,
> };
>
> /**
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> index 5a6600f7b382..872b2a4f3d9a 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> @@ -9360,8 +9360,8 @@ static int ixgbe_setup_tc_mqprio(struct net_device *dev,
> return ixgbe_setup_tc(dev, mqprio->num_tc);
> }
>
> -static int __ixgbe_setup_tc(struct net_device *dev, enum tc_setup_type type,
> - void *type_data)
> +static int __ixgbe_setup_offload(struct net_device *dev,
> + enum tc_setup_type type, void *type_data)
> {
> switch (type) {
> case TC_SETUP_BLOCK:
> @@ -10068,7 +10068,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
> .ndo_set_vf_trust = ixgbe_ndo_set_vf_trust,
> .ndo_get_vf_config = ixgbe_ndo_get_vf_config,
> .ndo_get_stats64 = ixgbe_get_stats64,
> - .ndo_setup_tc = __ixgbe_setup_tc,
> + .ndo_setup_offload = __ixgbe_setup_offload,
> #ifdef CONFIG_NET_POLL_CONTROLLER
> .ndo_poll_controller = ixgbe_netpoll,
> #endif
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> index 6785661d1a72..4a01b58a07f4 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> @@ -130,8 +130,9 @@ int mlx4_en_alloc_tx_queue_per_tc(struct net_device *dev, u8 tc)
> return err;
> }
>
> -static int __mlx4_en_setup_tc(struct net_device *dev, enum tc_setup_type type,
> - void *type_data)
> +static int __mlx4_en_setup_offload(struct net_device *dev,
> + enum tc_setup_type type,
> + void *type_data)
> {
> struct tc_mqprio_qopt *mqprio = type_data;
>
> @@ -2951,7 +2952,7 @@ static const struct net_device_ops mlx4_netdev_ops = {
> #endif
> .ndo_set_features = mlx4_en_set_features,
> .ndo_fix_features = mlx4_en_fix_features,
> - .ndo_setup_tc = __mlx4_en_setup_tc,
> + .ndo_setup_offload = __mlx4_en_setup_offload,
> #ifdef CONFIG_RFS_ACCEL
> .ndo_rx_flow_steer = mlx4_en_filter_rfs,
> #endif
> @@ -2988,7 +2989,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
> #endif
> .ndo_set_features = mlx4_en_set_features,
> .ndo_fix_features = mlx4_en_fix_features,
> - .ndo_setup_tc = __mlx4_en_setup_tc,
> + .ndo_setup_offload = __mlx4_en_setup_offload,
> #ifdef CONFIG_RFS_ACCEL
> .ndo_rx_flow_steer = mlx4_en_filter_rfs,
> #endif
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> index 712b9766485f..469359cbef27 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> @@ -3383,8 +3383,8 @@ static int mlx5e_setup_tc_block(struct net_device *dev,
> }
> #endif
>
> -static int mlx5e_setup_tc(struct net_device *dev, enum tc_setup_type type,
> - void *type_data)
> +static int mlx5e_setup_offload(struct net_device *dev, enum tc_setup_type type,
> + void *type_data)
> {
> switch (type) {
> #ifdef CONFIG_MLX5_ESWITCH
> @@ -4222,7 +4222,7 @@ static const struct net_device_ops mlx5e_netdev_ops = {
> .ndo_open = mlx5e_open,
> .ndo_stop = mlx5e_close,
> .ndo_start_xmit = mlx5e_xmit,
> - .ndo_setup_tc = mlx5e_setup_tc,
> + .ndo_setup_offload = mlx5e_setup_offload,
> .ndo_select_queue = mlx5e_select_queue,
> .ndo_get_stats64 = mlx5e_get_stats,
> .ndo_set_rx_mode = mlx5e_set_rx_mode,
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
> index 8e3c5b4b90ab..eddb20fd4dcc 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
> @@ -806,8 +806,8 @@ static int mlx5e_rep_setup_tc_block(struct net_device *dev,
> }
> }
>
> -static int mlx5e_rep_setup_tc(struct net_device *dev, enum tc_setup_type type,
> - void *type_data)
> +static int mlx5e_rep_setup_offload(struct net_device *dev,
> + enum tc_setup_type type, void *type_data)
> {
> switch (type) {
> case TC_SETUP_BLOCK:
> @@ -917,7 +917,7 @@ static const struct net_device_ops mlx5e_netdev_ops_rep = {
> .ndo_stop = mlx5e_rep_close,
> .ndo_start_xmit = mlx5e_xmit,
> .ndo_get_phys_port_name = mlx5e_rep_get_phys_port_name,
> - .ndo_setup_tc = mlx5e_rep_setup_tc,
> + .ndo_setup_offload = mlx5e_rep_setup_offload,
> .ndo_get_stats64 = mlx5e_rep_get_stats,
> .ndo_has_offload_stats = mlx5e_has_offload_stats,
> .ndo_get_offload_stats = mlx5e_get_offload_stats,
> diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
> index 6ec0f91a93cc..910fefbec88d 100644
> --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
> +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
> @@ -1631,8 +1631,8 @@ static int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port,
> }
> }
>
> -static int mlxsw_sp_setup_tc(struct net_device *dev, enum tc_setup_type type,
> - void *type_data)
> +static int mlxsw_sp_setup_offload(struct net_device *dev,
> + enum tc_setup_type type, void *type_data)
> {
> struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
>
> @@ -1708,7 +1708,7 @@ static const struct net_device_ops mlxsw_sp_port_netdev_ops = {
> .ndo_open = mlxsw_sp_port_open,
> .ndo_stop = mlxsw_sp_port_stop,
> .ndo_start_xmit = mlxsw_sp_port_xmit,
> - .ndo_setup_tc = mlxsw_sp_setup_tc,
> + .ndo_setup_offload = mlxsw_sp_setup_offload,
> .ndo_set_rx_mode = mlxsw_sp_set_rx_mode,
> .ndo_set_mac_address = mlxsw_sp_port_set_mac_address,
> .ndo_change_mtu = mlxsw_sp_port_change_mtu,
> diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> index a712e83c3f0f..56f7b468bc8c 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> @@ -3494,7 +3494,7 @@ const struct net_device_ops nfp_net_netdev_ops = {
> .ndo_set_vf_spoofchk = nfp_app_set_vf_spoofchk,
> .ndo_get_vf_config = nfp_app_get_vf_config,
> .ndo_set_vf_link_state = nfp_app_set_vf_link_state,
> - .ndo_setup_tc = nfp_port_setup_tc,
> + .ndo_setup_offload = nfp_port_setup_offload,
> .ndo_tx_timeout = nfp_net_tx_timeout,
> .ndo_set_rx_mode = nfp_net_set_rx_mode,
> .ndo_change_mtu = nfp_net_change_mtu,
> diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
> index d7b712f6362f..a98d3762caa2 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
> +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
> @@ -270,7 +270,7 @@ const struct net_device_ops nfp_repr_netdev_ops = {
> .ndo_has_offload_stats = nfp_repr_has_offload_stats,
> .ndo_get_offload_stats = nfp_repr_get_offload_stats,
> .ndo_get_phys_port_name = nfp_port_get_phys_port_name,
> - .ndo_setup_tc = nfp_port_setup_tc,
> + .ndo_setup_offload = nfp_port_setup_offload,
> .ndo_set_vf_mac = nfp_app_set_vf_mac,
> .ndo_set_vf_vlan = nfp_app_set_vf_vlan,
> .ndo_set_vf_spoofchk = nfp_app_set_vf_spoofchk,
> diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.c b/drivers/net/ethernet/netronome/nfp/nfp_port.c
> index 9c1298114c70..fb945adada08 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfp_port.c
> +++ b/drivers/net/ethernet/netronome/nfp/nfp_port.c
> @@ -89,8 +89,8 @@ const struct switchdev_ops nfp_port_switchdev_ops = {
> .switchdev_port_attr_get = nfp_port_attr_get,
> };
>
> -int nfp_port_setup_tc(struct net_device *netdev, enum tc_setup_type type,
> - void *type_data)
> +int nfp_port_setup_offload(struct net_device *netdev, enum tc_setup_type type,
> + void *type_data)
> {
> struct nfp_port *port;
>
> diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.h b/drivers/net/ethernet/netronome/nfp/nfp_port.h
> index 51f10ae2d53e..044fbb6f9219 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfp_port.h
> +++ b/drivers/net/ethernet/netronome/nfp/nfp_port.h
> @@ -124,8 +124,8 @@ extern const struct switchdev_ops nfp_port_switchdev_ops;
>
> __printf(2, 3) u8 *nfp_pr_et(u8 *data, const char *fmt, ...);
>
> -int nfp_port_setup_tc(struct net_device *netdev, enum tc_setup_type type,
> - void *type_data);
> +int nfp_port_setup_offload(struct net_device *netdev, enum tc_setup_type type,
> + void *type_data);
>
> static inline bool nfp_port_is_vnic(const struct nfp_port *port)
> {
> diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
> index b24c2e21db8e..d0cbded8360b 100644
> --- a/drivers/net/ethernet/sfc/efx.c
> +++ b/drivers/net/ethernet/sfc/efx.c
> @@ -2518,7 +2518,7 @@ static const struct net_device_ops efx_netdev_ops = {
> #ifdef CONFIG_NET_POLL_CONTROLLER
> .ndo_poll_controller = efx_netpoll,
> #endif
> - .ndo_setup_tc = efx_setup_tc,
> + .ndo_setup_offload = efx_setup_offload,
> #ifdef CONFIG_RFS_ACCEL
> .ndo_rx_flow_steer = efx_filter_rfs,
> #endif
> diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
> index 3f759ebdcf10..383fb4c15dea 100644
> --- a/drivers/net/ethernet/sfc/efx.h
> +++ b/drivers/net/ethernet/sfc/efx.h
> @@ -27,8 +27,8 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
> struct net_device *net_dev);
> netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
> void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
> -int efx_setup_tc(struct net_device *net_dev, enum tc_setup_type type,
> - void *type_data);
> +int efx_setup_offload(struct net_device *net_dev, enum tc_setup_type type,
> + void *type_data);
> unsigned int efx_tx_max_skb_descs(struct efx_nic *efx);
> extern unsigned int efx_piobuf_size;
> extern bool efx_separate_tx_channels;
> diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c
> index dd5530a4f8c8..8c8b012945a8 100644
> --- a/drivers/net/ethernet/sfc/falcon/efx.c
> +++ b/drivers/net/ethernet/sfc/falcon/efx.c
> @@ -2253,7 +2253,7 @@ static const struct net_device_ops ef4_netdev_ops = {
> #ifdef CONFIG_NET_POLL_CONTROLLER
> .ndo_poll_controller = ef4_netpoll,
> #endif
> - .ndo_setup_tc = ef4_setup_tc,
> + .ndo_setup_offload = ef4_setup_offload,
> #ifdef CONFIG_RFS_ACCEL
> .ndo_rx_flow_steer = ef4_filter_rfs,
> #endif
> diff --git a/drivers/net/ethernet/sfc/falcon/efx.h b/drivers/net/ethernet/sfc/falcon/efx.h
> index a4e4d8ea4078..67ff3891bc42 100644
> --- a/drivers/net/ethernet/sfc/falcon/efx.h
> +++ b/drivers/net/ethernet/sfc/falcon/efx.h
> @@ -32,8 +32,8 @@ netdev_tx_t ef4_hard_start_xmit(struct sk_buff *skb,
> struct net_device *net_dev);
> netdev_tx_t ef4_enqueue_skb(struct ef4_tx_queue *tx_queue, struct sk_buff *skb);
> void ef4_xmit_done(struct ef4_tx_queue *tx_queue, unsigned int index);
> -int ef4_setup_tc(struct net_device *net_dev, enum tc_setup_type type,
> - void *type_data);
> +int ef4_setup_offload(struct net_device *net_dev, enum tc_setup_type type,
> + void *type_data);
> unsigned int ef4_tx_max_skb_descs(struct ef4_nic *efx);
> extern bool ef4_separate_tx_channels;
>
> diff --git a/drivers/net/ethernet/sfc/falcon/tx.c b/drivers/net/ethernet/sfc/falcon/tx.c
> index 3409bbf5b19f..15a1b82160bb 100644
> --- a/drivers/net/ethernet/sfc/falcon/tx.c
> +++ b/drivers/net/ethernet/sfc/falcon/tx.c
> @@ -425,8 +425,8 @@ void ef4_init_tx_queue_core_txq(struct ef4_tx_queue *tx_queue)
> efx->n_tx_channels : 0));
> }
>
> -int ef4_setup_tc(struct net_device *net_dev, enum tc_setup_type type,
> - void *type_data)
> +int ef4_setup_offload(struct net_device *net_dev, enum tc_setup_type type,
> + void *type_data)
> {
> struct ef4_nic *efx = netdev_priv(net_dev);
> struct tc_mqprio_qopt *mqprio = type_data;
> diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c
> index c3ad564ac4c0..53c7801decbc 100644
> --- a/drivers/net/ethernet/sfc/tx.c
> +++ b/drivers/net/ethernet/sfc/tx.c
> @@ -687,8 +687,8 @@ void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue)
> efx->n_tx_channels : 0));
> }
>
> -int efx_setup_tc(struct net_device *net_dev, enum tc_setup_type type,
> - void *type_data)
> +int efx_setup_offload(struct net_device *net_dev, enum tc_setup_type type,
> + void *type_data)
> {
> struct efx_nic *efx = netdev_priv(net_dev);
> struct tc_mqprio_qopt *mqprio = type_data;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index d9e60cfd8a85..a274d0c6b375 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -3787,8 +3787,8 @@ static int stmmac_setup_tc_block(struct stmmac_priv *priv,
> }
> }
>
> -static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type,
> - void *type_data)
> +static int stmmac_setup_offload(struct net_device *ndev,
> + enum tc_setup_type type, void *type_data)
> {
> struct stmmac_priv *priv = netdev_priv(ndev);
>
> @@ -4040,7 +4040,7 @@ static const struct net_device_ops stmmac_netdev_ops = {
> .ndo_set_rx_mode = stmmac_set_rx_mode,
> .ndo_tx_timeout = stmmac_tx_timeout,
> .ndo_do_ioctl = stmmac_ioctl,
> - .ndo_setup_tc = stmmac_setup_tc,
> + .ndo_setup_offload = stmmac_setup_offload,
> #ifdef CONFIG_NET_POLL_CONTROLLER
> .ndo_poll_controller = stmmac_poll_controller,
> #endif
> diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c
> index a1d335a3c5e4..70d469eabc10 100644
> --- a/drivers/net/ethernet/ti/netcp_core.c
> +++ b/drivers/net/ethernet/ti/netcp_core.c
> @@ -1889,8 +1889,8 @@ static int netcp_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vid)
> return err;
> }
>
> -static int netcp_setup_tc(struct net_device *dev, enum tc_setup_type type,
> - void *type_data)
> +static int netcp_setup_offload(struct net_device *dev, enum tc_setup_type type,
> + void *type_data)
> {
> struct tc_mqprio_qopt *mqprio = type_data;
> u8 num_tc;
> @@ -1966,7 +1966,7 @@ static const struct net_device_ops netcp_netdev_ops = {
> .ndo_vlan_rx_kill_vid = netcp_rx_kill_vid,
> .ndo_tx_timeout = netcp_ndo_tx_timeout,
> .ndo_select_queue = dev_pick_tx_zero,
> - .ndo_setup_tc = netcp_setup_tc,
> + .ndo_setup_offload = netcp_setup_offload,
> };
>
> static int netcp_create_interface(struct netcp_device *netcp_device,
> diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
> index a7b179f0d954..9b6a5d2f335f 100644
> --- a/drivers/net/netdevsim/netdev.c
> +++ b/drivers/net/netdevsim/netdev.c
> @@ -393,7 +393,8 @@ static int nsim_set_vf_link_state(struct net_device *dev, int vf, int state)
> }
>
> static int
> -nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
> +nsim_setup_offload(struct net_device *dev, enum tc_setup_type type,
> + void *type_data)
> {
> switch (type) {
> case TC_SETUP_BLOCK:
> @@ -431,7 +432,7 @@ static const struct net_device_ops nsim_netdev_ops = {
> .ndo_get_vf_config = nsim_get_vf_config,
> .ndo_set_vf_link_state = nsim_set_vf_link_state,
> .ndo_set_vf_rss_query_en = nsim_set_vf_rss_query_en,
> - .ndo_setup_tc = nsim_setup_tc,
> + .ndo_setup_offload = nsim_setup_offload,
> .ndo_set_features = nsim_set_features,
> .ndo_bpf = nsim_bpf,
> };
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 3514d67112b3..0f50bf95b7cd 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -1047,12 +1047,12 @@ struct dev_ifalias {
> * with PF and querying it may introduce a theoretical security risk.
> * int (*ndo_set_vf_rss_query_en)(struct net_device *dev, int vf, bool setting);
> * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb);
> - * int (*ndo_setup_tc)(struct net_device *dev, enum tc_setup_type type,
> - * void *type_data);
> - * Called to setup any 'tc' scheduler, classifier or action on @dev.
> - * This is always called from the stack with the rtnl lock held and netif
> - * tx queues stopped. This allows the netdevice to perform queue
> - * management safely.
> + * int (*ndo_setup_offload)(struct net_device *dev, enum tc_setup_type type,
> + void *type_data);
> + * Called to setup any offload, such as 'tc' scheduler, classifier or
> + * action on @dev. This is always called from the stack with the rtnl lock
> + * held and netif tx queues stopped. This allows the netdevice to perform
> + * queue management safely.
> *
> * Fiber Channel over Ethernet (FCoE) offload functions.
> * int (*ndo_fcoe_enable)(struct net_device *dev);
> @@ -1297,9 +1297,9 @@ struct net_device_ops {
> int (*ndo_set_vf_rss_query_en)(
> struct net_device *dev,
> int vf, bool setting);
> - int (*ndo_setup_tc)(struct net_device *dev,
> - enum tc_setup_type type,
> - void *type_data);
> + int (*ndo_setup_offload)(struct net_device *dev,
> + enum tc_setup_type type,
> + void *type_data);
> #if IS_ENABLED(CONFIG_FCOE)
> int (*ndo_fcoe_enable)(struct net_device *dev);
> int (*ndo_fcoe_disable)(struct net_device *dev);
> diff --git a/net/dsa/slave.c b/net/dsa/slave.c
> index 71536c435132..a8f4013edc2a 100644
> --- a/net/dsa/slave.c
> +++ b/net/dsa/slave.c
> @@ -909,8 +909,9 @@ static int dsa_slave_setup_tc_block(struct net_device *dev,
> }
> }
>
> -static int dsa_slave_setup_tc(struct net_device *dev, enum tc_setup_type type,
> - void *type_data)
> +static int dsa_slave_setup_offload(struct net_device *dev,
> + enum tc_setup_type type,
> + void *type_data)
> {
> switch (type) {
> case TC_SETUP_BLOCK:
> @@ -1045,7 +1046,7 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
> .ndo_poll_controller = dsa_slave_poll_controller,
> #endif
> .ndo_get_phys_port_name = dsa_slave_get_phys_port_name,
> - .ndo_setup_tc = dsa_slave_setup_tc,
> + .ndo_setup_offload = dsa_slave_setup_offload,
> .ndo_get_stats64 = dsa_slave_get_stats64,
> };
>
> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
> index c51b1b12450d..d5add1358b66 100644
> --- a/net/sched/cls_api.c
> +++ b/net/sched/cls_api.c
> @@ -286,7 +286,7 @@ static int tcf_block_offload_cmd(struct tcf_block *block,
> bo.binder_type = ei->binder_type;
> bo.block = block;
> bo.extack = extack;
> - return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_BLOCK, &bo);
> + return dev->netdev_ops->ndo_setup_offload(dev, TC_SETUP_BLOCK, &bo);
> }
>
> static int tcf_block_offload_bind(struct tcf_block *block, struct Qdisc *q,
> @@ -296,7 +296,7 @@ static int tcf_block_offload_bind(struct tcf_block *block, struct Qdisc *q,
> struct net_device *dev = q->dev_queue->dev;
> int err;
>
> - if (!dev->netdev_ops->ndo_setup_tc)
> + if (!dev->netdev_ops->ndo_setup_offload)
> goto no_offload_dev_inc;
>
> /* If tc offload feature is disabled and the block we try to bind
> @@ -325,7 +325,7 @@ static void tcf_block_offload_unbind(struct tcf_block *block, struct Qdisc *q,
> struct net_device *dev = q->dev_queue->dev;
> int err;
>
> - if (!dev->netdev_ops->ndo_setup_tc)
> + if (!dev->netdev_ops->ndo_setup_offload)
> goto no_offload_dev_dec;
> err = tcf_block_offload_cmd(block, dev, ei, TC_BLOCK_UNBIND, NULL);
> if (err == -EOPNOTSUPP)
> diff --git a/net/sched/sch_cbs.c b/net/sched/sch_cbs.c
> index cdd96b9a27bc..d7e4169f9a1c 100644
> --- a/net/sched/sch_cbs.c
> +++ b/net/sched/sch_cbs.c
> @@ -206,13 +206,13 @@ static void cbs_disable_offload(struct net_device *dev,
> q->dequeue = cbs_dequeue_soft;
>
> ops = dev->netdev_ops;
> - if (!ops->ndo_setup_tc)
> + if (!ops->ndo_setup_offload)
> return;
>
> cbs.queue = q->queue;
> cbs.enable = 0;
>
> - err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_CBS, &cbs);
> + err = ops->ndo_setup_offload(dev, TC_SETUP_QDISC_CBS, &cbs);
> if (err < 0)
> pr_warn("Couldn't disable CBS offload for queue %d\n",
> cbs.queue);
> @@ -226,7 +226,7 @@ static int cbs_enable_offload(struct net_device *dev, struct cbs_sched_data *q,
> struct tc_cbs_qopt_offload cbs = { };
> int err;
>
> - if (!ops->ndo_setup_tc) {
> + if (!ops->ndo_setup_offload) {
> NL_SET_ERR_MSG(extack, "Specified device does not support cbs offload");
> return -EOPNOTSUPP;
> }
> @@ -239,7 +239,7 @@ static int cbs_enable_offload(struct net_device *dev, struct cbs_sched_data *q,
> cbs.idleslope = opt->idleslope;
> cbs.sendslope = opt->sendslope;
>
> - err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_CBS, &cbs);
> + err = ops->ndo_setup_offload(dev, TC_SETUP_QDISC_CBS, &cbs);
> if (err < 0) {
> NL_SET_ERR_MSG(extack, "Specified device failed to setup cbs hardware offload");
> return err;
> diff --git a/net/sched/sch_etf.c b/net/sched/sch_etf.c
> index 1538d6fa8165..97061e26d2b5 100644
> --- a/net/sched/sch_etf.c
> +++ b/net/sched/sch_etf.c
> @@ -272,13 +272,13 @@ static void etf_disable_offload(struct net_device *dev,
> return;
>
> ops = dev->netdev_ops;
> - if (!ops->ndo_setup_tc)
> + if (!ops->ndo_setup_offload)
> return;
>
> etf.queue = q->queue;
> etf.enable = 0;
>
> - err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_ETF, &etf);
> + err = ops->ndo_setup_offload(dev, TC_SETUP_QDISC_ETF, &etf);
> if (err < 0)
> pr_warn("Couldn't disable ETF offload for queue %d\n",
> etf.queue);
> @@ -294,7 +294,7 @@ static int etf_enable_offload(struct net_device *dev, struct etf_sched_data *q,
> if (q->offload)
> return 0;
>
> - if (!ops->ndo_setup_tc) {
> + if (!ops->ndo_setup_offload) {
> NL_SET_ERR_MSG(extack, "Specified device does not support ETF offload");
> return -EOPNOTSUPP;
> }
> @@ -302,7 +302,7 @@ static int etf_enable_offload(struct net_device *dev, struct etf_sched_data *q,
> etf.queue = q->queue;
> etf.enable = 1;
>
> - err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_ETF, &etf);
> + err = ops->ndo_setup_offload(dev, TC_SETUP_QDISC_ETF, &etf);
> if (err < 0) {
> NL_SET_ERR_MSG(extack, "Specified device failed to setup ETF hardware offload");
> return err;
> diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
> index d6b8ae4ed7a3..575a6b168dbc 100644
> --- a/net/sched/sch_mq.c
> +++ b/net/sched/sch_mq.c
> @@ -32,10 +32,10 @@ static int mq_offload(struct Qdisc *sch, enum tc_mq_command cmd)
> .handle = sch->handle,
> };
>
> - if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
> + if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_offload)
> return -EOPNOTSUPP;
>
> - return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_MQ, &opt);
> + return dev->netdev_ops->ndo_setup_offload(dev, TC_SETUP_QDISC_MQ, &opt);
> }
>
> static void mq_offload_stats(struct Qdisc *sch)
> @@ -50,8 +50,8 @@ static void mq_offload_stats(struct Qdisc *sch)
> },
> };
>
> - if (tc_can_offload(dev) && dev->netdev_ops->ndo_setup_tc)
> - dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_MQ, &opt);
> + if (tc_can_offload(dev) && dev->netdev_ops->ndo_setup_offload)
> + dev->netdev_ops->ndo_setup_offload(dev, TC_SETUP_QDISC_MQ, &opt);
> }
>
> static void mq_destroy(struct Qdisc *sch)
> diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
> index 0e9d761cdd80..153d137aa2cc 100644
> --- a/net/sched/sch_mqprio.c
> +++ b/net/sched/sch_mqprio.c
> @@ -44,15 +44,15 @@ static void mqprio_destroy(struct Qdisc *sch)
> kfree(priv->qdiscs);
> }
>
> - if (priv->hw_offload && dev->netdev_ops->ndo_setup_tc) {
> + if (priv->hw_offload && dev->netdev_ops->ndo_setup_offload) {
> struct tc_mqprio_qopt_offload mqprio = { { 0 } };
>
> switch (priv->mode) {
> case TC_MQPRIO_MODE_DCB:
> case TC_MQPRIO_MODE_CHANNEL:
> - dev->netdev_ops->ndo_setup_tc(dev,
> - TC_SETUP_QDISC_MQPRIO,
> - &mqprio);
> + dev->netdev_ops->ndo_setup_offload(dev,
> + TC_SETUP_QDISC_MQPRIO,
> + &mqprio);
> break;
> default:
> return;
> @@ -85,11 +85,11 @@ static int mqprio_parse_opt(struct net_device *dev, struct tc_mqprio_qopt *qopt)
>
> /* If hardware offload is requested we will leave it to the device
> * to either populate the queue counts itself or to validate the
> - * provided queue counts. If ndo_setup_tc is not present then
> + * provided queue counts. If ndo_setup_offload is not present then
> * hardware doesn't support offload and we should return an error.
> */
> if (qopt->hw)
> - return dev->netdev_ops->ndo_setup_tc ? 0 : -EINVAL;
> + return dev->netdev_ops->ndo_setup_offload ? 0 : -EINVAL;
>
> for (i = 0; i < qopt->num_tc; i++) {
> unsigned int last = qopt->offset[i] + qopt->count[i];
> @@ -239,7 +239,7 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
> }
>
> /* If the mqprio options indicate that hardware should own
> - * the queue mapping then run ndo_setup_tc otherwise use the
> + * the queue mapping then run ndo_setup_offload otherwise use the
> * supplied and verified mapping
> */
> if (qopt->hw) {
> @@ -266,7 +266,7 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
> default:
> return -EINVAL;
> }
> - err = dev->netdev_ops->ndo_setup_tc(dev,
> + err = dev->netdev_ops->ndo_setup_offload(dev,
> TC_SETUP_QDISC_MQPRIO,
> &mqprio);
> if (err)
> diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
> index 222e53d3d27a..ae9bf5fe320a 100644
> --- a/net/sched/sch_prio.c
> +++ b/net/sched/sch_prio.c
> @@ -150,7 +150,7 @@ static int prio_offload(struct Qdisc *sch, struct tc_prio_qopt *qopt)
> .parent = sch->parent,
> };
>
> - if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
> + if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_offload)
> return -EOPNOTSUPP;
>
> if (qopt) {
> @@ -163,7 +163,8 @@ static int prio_offload(struct Qdisc *sch, struct tc_prio_qopt *qopt)
> opt.command = TC_PRIO_DESTROY;
> }
>
> - return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_PRIO, &opt);
> + return dev->netdev_ops->ndo_setup_offload(dev, TC_SETUP_QDISC_PRIO,
> + &opt);
> }
>
> static void
> @@ -266,11 +267,11 @@ static int prio_dump_offload(struct Qdisc *sch)
> int err;
>
> sch->flags &= ~TCQ_F_OFFLOADED;
> - if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
> + if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_offload)
> return 0;
>
> - err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_PRIO,
> - &hw_stats);
> + err = dev->netdev_ops->ndo_setup_offload(dev, TC_SETUP_QDISC_PRIO,
> + &hw_stats);
> if (err == -EOPNOTSUPP)
> return 0;
>
> @@ -328,8 +329,8 @@ static int prio_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
> graft_offload.graft_params.child_handle = new->handle;
> graft_offload.command = TC_PRIO_GRAFT;
>
> - err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_PRIO,
> - &graft_offload);
> + err = dev->netdev_ops->ndo_setup_offload(dev, TC_SETUP_QDISC_PRIO,
> + &graft_offload);
>
> /* Don't report error if the graft is part of destroy operation. */
> if (err && new != &noop_qdisc) {
> diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
> index 56c181c3feeb..63a4ee50cf05 100644
> --- a/net/sched/sch_red.c
> +++ b/net/sched/sch_red.c
> @@ -158,7 +158,7 @@ static int red_offload(struct Qdisc *sch, bool enable)
> .parent = sch->parent,
> };
>
> - if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
> + if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_offload)
> return -EOPNOTSUPP;
>
> if (enable) {
> @@ -172,7 +172,8 @@ static int red_offload(struct Qdisc *sch, bool enable)
> opt.command = TC_RED_DESTROY;
> }
>
> - return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, &opt);
> + return dev->netdev_ops->ndo_setup_offload(dev, TC_SETUP_QDISC_RED,
> + &opt);
> }
>
> static void red_destroy(struct Qdisc *sch)
> @@ -295,11 +296,11 @@ static int red_dump_offload_stats(struct Qdisc *sch, struct tc_red_qopt *opt)
>
> sch->flags &= ~TCQ_F_OFFLOADED;
>
> - if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
> + if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_offload)
> return 0;
>
> - err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED,
> - &hw_stats);
> + err = dev->netdev_ops->ndo_setup_offload(dev, TC_SETUP_QDISC_RED,
> + &hw_stats);
> if (err == -EOPNOTSUPP)
> return 0;
>
> @@ -356,8 +357,8 @@ static int red_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
> .xstats = &q->stats,
> },
> };
> - dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED,
> - &hw_stats_request);
> + dev->netdev_ops->ndo_setup_offload(dev, TC_SETUP_QDISC_RED,
> + &hw_stats_request);
> }
> st.early = q->stats.prob_drop + q->stats.forced_drop;
> st.pdrop = q->stats.pdrop;
> --
> 2.11.0
>
^ permalink raw reply
* Re: [PATCH 2/5] rhashtable: don't hold lock on first table throughout insertion.
From: Paul E. McKenney @ 2018-07-20 14:41 UTC (permalink / raw)
To: Herbert Xu; +Cc: NeilBrown, Thomas Graf, netdev, linux-kernel
In-Reply-To: <20180720075409.kfckhodsnvktift7@gondor.apana.org.au>
On Fri, Jul 20, 2018 at 03:54:09PM +0800, Herbert Xu wrote:
> On Fri, Jul 06, 2018 at 05:22:30PM +1000, NeilBrown wrote:
> > rhashtable_try_insert() currently hold a lock on the bucket in
> > the first table, while also locking buckets in subsequent tables.
> > This is unnecessary and looks like a hold-over from some earlier
> > version of the implementation.
> >
> > As insert and remove always lock a bucket in each table in turn, and
> > as insert only inserts in the final table, there cannot be any races
> > that are not covered by simply locking a bucket in each table in turn.
> >
> > When an insert call reaches that last table it can be sure that there
> > is no match entry in any other table as it has searched them all, and
> > insertion never happens anywhere but in the last table. The fact that
> > code tests for the existence of future_tbl while holding a lock on
> > the relevant bucket ensures that two threads inserting the same key
> > will make compatible decisions about which is the "last" table.
> >
> > This simplifies the code and allows the ->rehash field to be
> > discarded.
> >
> > We still need a way to ensure that a dead bucket_table is never
> > re-linked by rhashtable_walk_stop(). This can be achieved by
> > calling call_rcu() inside the locked region, and checking
> > ->rcu.func in rhashtable_walk_stop(). If it is not NULL, then
> > the bucket table is empty and dead.
> >
> > Signed-off-by: NeilBrown <neilb@suse.com>
>
> ...
>
> > @@ -339,13 +338,16 @@ static int rhashtable_rehash_table(struct rhashtable *ht)
> > spin_lock(&ht->lock);
> > list_for_each_entry(walker, &old_tbl->walkers, list)
> > walker->tbl = NULL;
> > - spin_unlock(&ht->lock);
> >
> > /* Wait for readers. All new readers will see the new
> > * table, and thus no references to the old table will
> > * remain.
> > + * We do this inside the locked region so that
> > + * rhashtable_walk_stop() can check ->rcu.func and know
> > + * not to re-link the table.
> > */
> > call_rcu(&old_tbl->rcu, bucket_table_free_rcu);
> > + spin_unlock(&ht->lock);
> >
> > return rht_dereference(new_tbl->future_tbl, ht) ? -EAGAIN : 0;
> > }
>
> ...
>
> > @@ -964,7 +942,7 @@ void rhashtable_walk_stop(struct rhashtable_iter *iter)
> > ht = iter->ht;
> >
> > spin_lock(&ht->lock);
> > - if (tbl->rehash < tbl->size)
> > + if (tbl->rcu.func == NULL)
> > list_add(&iter->walker.list, &tbl->walkers);
> > else
> > iter->walker.tbl = NULL;
>
> This appears to be relying on implementation details within RCU.
> Paul, are you OK with rhashtable doing this trick?
The notion of accessing objects that are already on RCU's callback lists
makes me -very- nervous because this sort of thing is not easy to
get right. After all, if you are accessing something that is already
on one of RCU's callback lists, RCU might invoke the callback it at any
time (thus freeing it in this case), and because it is already on RCU's
callback lists, rcu_read_lock() is going to be of no help whatsoever.
In addition, RCU does no ordering on its store to ->func, but the ht->lock
compensates in this case. But suppose rhashtable_walk_stop() sees the
pointer as non-NULL. What prevents RCU from freeing the bucket table out
from under rhashtable_walk_stop()? In v4.17, bucket_table_free_rcu()
just does some calls to various deallocators, which does not provide
the necessary synchronization.
Does the rhashtable_iter structure use some trick to make this safe?
Or has synchronization been added to bucket_table_free_rcu()? Or is
some other trick in use?
Thanx, Paul
^ permalink raw reply
* Re: [PATCH net-next,v2] net: rename ndo_setup_tc to ndo_setup_offload
From: Alexander Duyck @ 2018-07-20 14:45 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: Netdev, Jiri Pirko, Tom Lendacky, Florian Fainelli, Ariel Elior,
Michael Chan, Santosh Raspatur, madalin.bucur, yisen.zhuang,
salil.mehta, Jeff Kirsher, Tariq Toukan, Saeed Mahameed,
Jiri Pirko, Ido Schimmel, Ganesh Goudar, Jakub Kicinski,
linux-net-drivers, peppe.cavallaro, alexandre.torgue, joabreu,
grygorii.strashko, Andrew Lunn
In-Reply-To: <20180720100945.fkbhkniygr7psnky@salvia>
On Fri, Jul 20, 2018 at 3:09 AM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> On Thu, Jul 19, 2018 at 02:04:16PM -0700, Alexander Duyck wrote:
>> On Thu, Jul 19, 2018 at 1:52 PM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
>> > On Thu, Jul 19, 2018 at 08:18:20AM -0700, Alexander Duyck wrote:
>> >> On Wed, Jul 18, 2018 at 5:11 PM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
>> >> > One of the recurring complaints is that we do not have, as a driver
>> >> > writer, a central location from which we would be fed offloading rules
>> >> > into a NIC. This was brought up again during Netconf'18 in Boston.
>> >> >
>> >> > This patch just renames ndo_setup_tc to ndo_setup_offload as a very
>> >> > early initial work to prepare for follow up patch that discuss unified
>> >> > flow representation for the existing offload programming APIs.
>> >> >
>> >> > Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
>> >> > Acked-by: Jiri Pirko <jiri@mellanox.com>
>> >> > Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
>> >>
>> >> One request I would have here is to not bother updating the individual
>> >> driver function names. For now I would say we could leave the
>> >> "_setup_tc" in the naming of the driver functions itself and just
>> >> update the name of the net device operation. Renaming the driver
>> >> functions just adds unnecessary overhead and complexity to the patch
>> >> and will make it more difficult to maintain. When we get around to
>> >> adding additional functionality that relates to the rename we could
>> >> address renaming the function on a per driver basis in the future.
>> >
>> > Plan was to follow up patch will rename enum tc_setup_type too:
>> >
>> > https://marc.info/?l=linux-netdev&m=153193158512556&w=2
>> >
>> > that will result in more renames in the driver side.
>> >
>> > I would expect this will happen sooner or later, and out of tree
>> > patches will end up needing a rebase sooner or later, if that is the
>> > concern.
>>
>> I was just thinking that renaming the functions themselves adds noise
>> and makes it harder to debug functions later when they get renamed. As
>> far as the out-of-tree driver I agree we will still have to deal with
>> it due to the enum and NDO function rename. I just figured that using
>> things like LXR is a bit easier when the function name stays the same
>> and you have to move between versions.
>
> Semantic changes in this interface are expected in follow up patches.
> Specifically, this interface will not be exclusively dedicated to 'tc'
> anymore. The function rename will provide a hint on this semantic change
> going on. I understand your concern, and I also tend to dislike renaming
> for the sake of renaming, but in this case this rename coveys useful
> information to developers.
>
> Thanks.
I kind of figured semantic changes were coming. I just thought we
could wait until then for the function renames. There isn't any point
in renaming the function until it changes what it is actually doing. I
suspect you may only have a few drivers that do the update as there
probably isn't much value in updating the function name on drivers
such as fm10k or igb as they are unlikely to ever support anything
other than the tc offloads. That way it is clear that currently none
of the drivers are supporting anything other than the tc offloads
until the new functionality to support netfilter offloads is added on
a per driver basis.
- Alex
^ permalink raw reply
* Re: [RFC PATCH] ip: re-introduce fragments cache worker
From: Paolo Abeni @ 2018-07-20 14:48 UTC (permalink / raw)
To: Eric Dumazet, netdev
Cc: David S. Miller, Eric Dumazet, Florian Westphal, NeilBrown
In-Reply-To: <449a637d-5af5-1d0a-818a-e30c0007ae30@gmail.com>
Hi,
On Mon, 2018-07-09 at 05:50 -0700, Eric Dumazet wrote:
> On 07/09/2018 04:39 AM, Eric Dumazet wrote:
>
> > Alternatively, you could try to patch fq_codel to drop all frags of one UDP datagram
> > instead of few of them.
>
> A first step would be to make sure fq_codel_hash() (using skb_get_hash(skb)) selects
> the same bucket for all frags of a datagram :/
I gave the above a shot and I have some non upstream ready but somewhat
working code. Anyway it has some issues I'm unable to solve:
* it's very invasive for fq_codel, because I need to parse each packet
looking for the fragment id
* the parsing overhead can't be easily avoided for non fragments
I tried also something hopefully along the same lines of your other
suggestion (drop eariler the fragment queues when above low threshold):
when allocating a new frag queue and the ipfrag mem is above the low
th, another frag queue is selected in a pseudorandom way and dropped.
This latter patch is much smaller, cope quite well with fragment drops,
and the goodput degradates gracefully when the ipfrag cache is
overloaded.
I'm wodering if you could consider this second option, too.
Thank you,
Paolo
^ permalink raw reply
* [PATCH net-next 0/2] net: bridge: add support for backup port
From: Nikolay Aleksandrov @ 2018-07-20 14:48 UTC (permalink / raw)
To: netdev; +Cc: roopa, anuradhak, stephen, bridge, wkok, davem,
Nikolay Aleksandrov
Hi,
This set introduces a new bridge port option that allows any port to have
any other port (in the same bridge of course) as its backup and traffic
will be forwarded to the backup port when the primary goes down. This is
mainly used in MLAG and EVPN setups where we have peerlink path which is
a backup of many (or even all) ports and is a participating bridge port
itself. There's more detailed information in patch 02. Patch 01 just
prepares the port sysfs code for options that take raw value. The main
issues that this set solves are scalability and fallback latency.
We have used similar code for over 6 months now to bring the fallback
latency of the backup peerlink down and avoid fdb notification storms.
Also due to the nature of master devices such setup is currently not
possible, and last but not least having tens of thousands of fdbs require
thousands of calls to switch.
I've also CCed our MLAG experts that have been using similar option.
Thanks,
Nik
Nikolay Aleksandrov (2):
net: bridge: add support for raw sysfs port options
net: bridge: add support for backup port
include/uapi/linux/if_link.h | 1 +
net/bridge/br_forward.c | 16 ++++++++-
net/bridge/br_if.c | 53 ++++++++++++++++++++++++++++
net/bridge/br_netlink.c | 30 +++++++++++++++-
net/bridge/br_private.h | 3 ++
net/bridge/br_sysfs_if.c | 82 ++++++++++++++++++++++++++++++++++++--------
6 files changed, 168 insertions(+), 17 deletions(-)
--
2.11.0
^ permalink raw reply
* [PATCH net-next 1/2] net: bridge: add support for raw sysfs port options
From: Nikolay Aleksandrov @ 2018-07-20 14:48 UTC (permalink / raw)
To: netdev; +Cc: roopa, anuradhak, stephen, bridge, wkok, davem,
Nikolay Aleksandrov
In-Reply-To: <20180720144826.29892-1-nikolay@cumulusnetworks.com>
This patch adds a new alternative store callback for port sysfs options
which takes a raw value (buf) and can use it directly. It is needed for the
backup port sysfs support since we have to pass the device by its name.
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
There are a few checkpatch warnings here because of the old code, I've
noted them in my todo and will send separate patch for simple_strtoul
and the function prototypes.
net/bridge/br_sysfs_if.c | 49 +++++++++++++++++++++++++++++++++---------------
1 file changed, 34 insertions(+), 15 deletions(-)
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
index f99c5bf5c906..38c58879423d 100644
--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -25,6 +25,15 @@ struct brport_attribute {
struct attribute attr;
ssize_t (*show)(struct net_bridge_port *, char *);
int (*store)(struct net_bridge_port *, unsigned long);
+ int (*store_raw)(struct net_bridge_port *, char *);
+};
+
+#define BRPORT_ATTR_RAW(_name, _mode, _show, _store) \
+const struct brport_attribute brport_attr_##_name = { \
+ .attr = {.name = __stringify(_name), \
+ .mode = _mode }, \
+ .show = _show, \
+ .store_raw = _store, \
};
#define BRPORT_ATTR(_name, _mode, _show, _store) \
@@ -270,27 +279,37 @@ static ssize_t brport_store(struct kobject *kobj,
struct brport_attribute *brport_attr = to_brport_attr(attr);
struct net_bridge_port *p = to_brport(kobj);
ssize_t ret = -EINVAL;
- char *endp;
unsigned long val;
+ char *endp;
if (!ns_capable(dev_net(p->dev)->user_ns, CAP_NET_ADMIN))
return -EPERM;
- val = simple_strtoul(buf, &endp, 0);
- if (endp != buf) {
- if (!rtnl_trylock())
- return restart_syscall();
- if (p->dev && p->br && brport_attr->store) {
- spin_lock_bh(&p->br->lock);
- ret = brport_attr->store(p, val);
- spin_unlock_bh(&p->br->lock);
- if (!ret) {
- br_ifinfo_notify(RTM_NEWLINK, NULL, p);
- ret = count;
- }
- }
- rtnl_unlock();
+ if (!rtnl_trylock())
+ return restart_syscall();
+
+ if (!p->dev || !p->br)
+ goto out_unlock;
+
+ if (brport_attr->store_raw) {
+ spin_lock_bh(&p->br->lock);
+ ret = brport_attr->store_raw(p, (char *)buf);
+ spin_unlock_bh(&p->br->lock);
+ } else if (brport_attr->store) {
+ val = simple_strtoul(buf, &endp, 0);
+ if (endp == buf)
+ goto out_unlock;
+ spin_lock_bh(&p->br->lock);
+ ret = brport_attr->store(p, val);
+ spin_unlock_bh(&p->br->lock);
+ }
+ if (!ret) {
+ br_ifinfo_notify(RTM_NEWLINK, NULL, p);
+ ret = count;
}
+out_unlock:
+ rtnl_unlock();
+
return ret;
}
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 2/2] net: bridge: add support for backup port
From: Nikolay Aleksandrov @ 2018-07-20 14:48 UTC (permalink / raw)
To: netdev; +Cc: roopa, anuradhak, stephen, bridge, wkok, davem,
Nikolay Aleksandrov
In-Reply-To: <20180720144826.29892-1-nikolay@cumulusnetworks.com>
This patch adds a new port attribute - IFLA_BRPORT_BACKUP_PORT, which
allows to set a backup port to be used for known unicast traffic if the
port has gone carrier down. The backup pointer is rcu protected and set
only under RTNL, a counter is maintained so when deleting a port we know
how many other ports reference it as a backup and we remove it from all.
Also the pointer is in the first cache line which is hot at the time of
the check and thus in the common case we only add one more test.
The backup port will be used only for the non-flooding case since
it's a part of the bridge and the flooded packets will be forwarded to it
anyway. To remove the forwarding just send a 0/non-existing backup port.
This is used to avoid numerous scalability problems when using MLAG most
notably if we have thousands of fdbs one would need to change all of them
on port carrier going down which takes too long and causes a storm of fdb
notifications (and again when the port comes back up). In a Multi-chassis
Link Aggregation setup usually hosts are connected to two different
switches which act as a single logical switch. Those switches usually have
a control and backup link between them called peerlink which might be used
for communication in case a host loses connectivity to one of them.
We need a fast way to failover in case a host port goes down and currently
none of the solutions (like bond) cannot fulfill the requirements because
the participating ports are actually the "master" devices and must have the
same peerlink as their backup interface and at the same time all of them
must participate in the bridge device. As Roopa noted it's normal practice
in routing called fast re-route where a precalculated backup path is used
when the main one is down.
Another use case of this is with EVPN, having a single vxlan device which
is backup of every port. Due to the nature of master devices it's not
currently possible to use one device as a backup for many and still have
all of them participate in the bridge (which is master itself).
More detailed information about MLAG is available at the link below.
https://docs.cumulusnetworks.com/display/DOCS/Multi-Chassis+Link+Aggregation+-+MLAG
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
I've also tried a version where the backup_port is checked via a port flag
but this saves us one internal flag and we use the already cache hot ptr
with a simple null check. I don't mind reverting to the flag behaviour if
anyone has strong preference.
This can be optimized further with a offline backup port switching
mechanism. We can remove the additional fast-path test later. Currently
I'd prefer to leave it simpler for easier review and commenting since
that would be an internal change and maybe isn't even worth the small gain.
include/uapi/linux/if_link.h | 1 +
net/bridge/br_forward.c | 16 ++++++++++++-
net/bridge/br_if.c | 53 ++++++++++++++++++++++++++++++++++++++++++++
net/bridge/br_netlink.c | 30 ++++++++++++++++++++++++-
net/bridge/br_private.h | 3 +++
net/bridge/br_sysfs_if.c | 33 +++++++++++++++++++++++++++
6 files changed, 134 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 8759cfb8aa2e..01b5069a73a5 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -334,6 +334,7 @@ enum {
IFLA_BRPORT_GROUP_FWD_MASK,
IFLA_BRPORT_NEIGH_SUPPRESS,
IFLA_BRPORT_ISOLATED,
+ IFLA_BRPORT_BACKUP_PORT,
__IFLA_BRPORT_MAX
};
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index 9019f326fe81..5372e2042adf 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -142,7 +142,20 @@ static int deliver_clone(const struct net_bridge_port *prev,
void br_forward(const struct net_bridge_port *to,
struct sk_buff *skb, bool local_rcv, bool local_orig)
{
- if (to && should_deliver(to, skb)) {
+ if (unlikely(!to))
+ goto out;
+
+ /* redirect to backup link if the destination port is down */
+ if (rcu_access_pointer(to->backup_port) && !netif_carrier_ok(to->dev)) {
+ struct net_bridge_port *backup_port;
+
+ backup_port = rcu_dereference(to->backup_port);
+ if (unlikely(!backup_port))
+ goto out;
+ to = backup_port;
+ }
+
+ if (should_deliver(to, skb)) {
if (local_rcv)
deliver_clone(to, skb, local_orig);
else
@@ -150,6 +163,7 @@ void br_forward(const struct net_bridge_port *to,
return;
}
+out:
if (!local_rcv)
kfree_skb(skb);
}
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 05e42d86882d..365759ac7c73 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -169,6 +169,58 @@ void br_manage_promisc(struct net_bridge *br)
}
}
+int nbp_backup_change(struct net_bridge_port *p,
+ struct net_device *backup_dev)
+{
+ struct net_bridge_port *old_backup = rtnl_dereference(p->backup_port);
+ struct net_bridge_port *backup_p = NULL;
+
+ ASSERT_RTNL();
+
+ if (backup_dev) {
+ if (!br_port_exists(backup_dev))
+ return -ENOENT;
+
+ backup_p = br_port_get_rtnl(backup_dev);
+ if (backup_p->br != p->br)
+ return -EINVAL;
+ }
+
+ if (p == backup_p)
+ return -EINVAL;
+
+ if (old_backup == backup_p)
+ return 0;
+
+ /* if the backup link is already set, clear it */
+ if (old_backup)
+ old_backup->backup_redirected_cnt--;
+
+ if (backup_p)
+ backup_p->backup_redirected_cnt++;
+ rcu_assign_pointer(p->backup_port, backup_p);
+
+ return 0;
+}
+
+static void nbp_backup_clear(struct net_bridge_port *p)
+{
+ nbp_backup_change(p, NULL);
+ if (p->backup_redirected_cnt) {
+ struct net_bridge_port *cur_p;
+
+ list_for_each_entry(cur_p, &p->br->port_list, list) {
+ struct net_bridge_port *backup_p;
+
+ backup_p = rtnl_dereference(cur_p->backup_port);
+ if (backup_p == p)
+ nbp_backup_change(cur_p, NULL);
+ }
+ }
+
+ WARN_ON(rcu_access_pointer(p->backup_port) || p->backup_redirected_cnt);
+}
+
static void nbp_update_port_count(struct net_bridge *br)
{
struct net_bridge_port *p;
@@ -286,6 +338,7 @@ static void del_nbp(struct net_bridge_port *p)
nbp_vlan_flush(p);
br_fdb_delete_by_port(br, p, 0, 1);
switchdev_deferred_process();
+ nbp_backup_clear(p);
nbp_update_port_count(br);
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 9f5eb05b0373..ec2b58a09f76 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -169,13 +169,15 @@ static inline size_t br_nlmsg_size(struct net_device *dev, u32 filter_mask)
+ nla_total_size(1) /* IFLA_OPERSTATE */
+ nla_total_size(br_port_info_size()) /* IFLA_PROTINFO */
+ nla_total_size(br_get_link_af_size_filtered(dev,
- filter_mask)); /* IFLA_AF_SPEC */
+ filter_mask)) /* IFLA_AF_SPEC */
+ + nla_total_size(4); /* IFLA_BRPORT_BACKUP_PORT */
}
static int br_port_fill_attrs(struct sk_buff *skb,
const struct net_bridge_port *p)
{
u8 mode = !!(p->flags & BR_HAIRPIN_MODE);
+ struct net_bridge_port *backup_p;
u64 timerval;
if (nla_put_u8(skb, IFLA_BRPORT_STATE, p->state) ||
@@ -237,6 +239,14 @@ static int br_port_fill_attrs(struct sk_buff *skb,
return -EMSGSIZE;
#endif
+ /* we might be called only with br->lock */
+ rcu_read_lock();
+ backup_p = rcu_dereference(p->backup_port);
+ if (backup_p)
+ nla_put_u32(skb, IFLA_BRPORT_BACKUP_PORT,
+ backup_p->dev->ifindex);
+ rcu_read_unlock();
+
return 0;
}
@@ -663,6 +673,7 @@ static const struct nla_policy br_port_policy[IFLA_BRPORT_MAX + 1] = {
[IFLA_BRPORT_GROUP_FWD_MASK] = { .type = NLA_U16 },
[IFLA_BRPORT_NEIGH_SUPPRESS] = { .type = NLA_U8 },
[IFLA_BRPORT_ISOLATED] = { .type = NLA_U8 },
+ [IFLA_BRPORT_BACKUP_PORT] = { .type = NLA_U32 },
};
/* Change the state of the port and notify spanning tree */
@@ -817,6 +828,23 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
if (err)
return err;
+ if (tb[IFLA_BRPORT_BACKUP_PORT]) {
+ struct net_device *backup_dev = NULL;
+ u32 backup_ifindex;
+
+ backup_ifindex = nla_get_u32(tb[IFLA_BRPORT_BACKUP_PORT]);
+ if (backup_ifindex) {
+ backup_dev = __dev_get_by_index(dev_net(p->dev),
+ backup_ifindex);
+ if (!backup_dev)
+ return -ENOENT;
+ }
+
+ err = nbp_backup_change(p, backup_dev);
+ if (err)
+ return err;
+ }
+
br_port_flags_change(p, old_flags ^ p->flags);
return 0;
}
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 5216a524b537..ab7db2466c43 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -237,6 +237,7 @@ struct net_bridge_port {
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
struct net_bridge_vlan_group __rcu *vlgrp;
#endif
+ struct net_bridge_port __rcu *backup_port;
/* STP */
u8 priority;
@@ -281,6 +282,7 @@ struct net_bridge_port {
int offload_fwd_mark;
#endif
u16 group_fwd_mask;
+ u16 backup_redirected_cnt;
};
#define br_auto_port(p) ((p)->flags & BR_AUTO_MASK)
@@ -595,6 +597,7 @@ netdev_features_t br_features_recompute(struct net_bridge *br,
netdev_features_t features);
void br_port_flags_change(struct net_bridge_port *port, unsigned long mask);
void br_manage_promisc(struct net_bridge *br);
+int nbp_backup_change(struct net_bridge_port *p, struct net_device *backup_dev);
/* br_input.c */
int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
index 38c58879423d..79d48e587278 100644
--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -191,6 +191,38 @@ static int store_group_fwd_mask(struct net_bridge_port *p,
static BRPORT_ATTR(group_fwd_mask, 0644, show_group_fwd_mask,
store_group_fwd_mask);
+static ssize_t show_backup_port(struct net_bridge_port *p, char *buf)
+{
+ struct net_bridge_port *backup_p;
+ int ret = 0;
+
+ rcu_read_lock();
+ backup_p = rcu_dereference(p->backup_port);
+ if (backup_p)
+ ret = sprintf(buf, "%s\n", backup_p->dev->name);
+ rcu_read_unlock();
+
+ return ret;
+}
+
+static int store_backup_port(struct net_bridge_port *p, char *buf)
+{
+ struct net_device *backup_dev = NULL;
+ char *nl = strchr(buf, '\n');
+
+ if (nl)
+ *nl = '\0';
+
+ if (strlen(buf) > 0) {
+ backup_dev = __dev_get_by_name(dev_net(p->dev), buf);
+ if (!backup_dev)
+ return -ENOENT;
+ }
+
+ return nbp_backup_change(p, backup_dev);
+}
+static BRPORT_ATTR_RAW(backup_port, 0644, show_backup_port, store_backup_port);
+
BRPORT_ATTR_FLAG(hairpin_mode, BR_HAIRPIN_MODE);
BRPORT_ATTR_FLAG(bpdu_guard, BR_BPDU_GUARD);
BRPORT_ATTR_FLAG(root_block, BR_ROOT_BLOCK);
@@ -254,6 +286,7 @@ static const struct brport_attribute *brport_attrs[] = {
&brport_attr_group_fwd_mask,
&brport_attr_neigh_suppress,
&brport_attr_isolated,
+ &brport_attr_backup_port,
NULL
};
--
2.11.0
^ permalink raw reply related
* Re: [PATCH net-next 2/2] net: bridge: add support for backup port
From: Stephen Hemminger @ 2018-07-20 16:02 UTC (permalink / raw)
To: Nikolay Aleksandrov; +Cc: netdev, roopa, bridge, wkok, anuradhak, davem
In-Reply-To: <20180720144826.29892-3-nikolay@cumulusnetworks.com>
On Fri, 20 Jul 2018 17:48:26 +0300
Nikolay Aleksandrov <nikolay@cumulusnetworks.com> wrote:
> This patch adds a new port attribute - IFLA_BRPORT_BACKUP_PORT, which
> allows to set a backup port to be used for known unicast traffic if the
> port has gone carrier down. The backup pointer is rcu protected and set
> only under RTNL, a counter is maintained so when deleting a port we know
> how many other ports reference it as a backup and we remove it from all.
> Also the pointer is in the first cache line which is hot at the time of
> the check and thus in the common case we only add one more test.
> The backup port will be used only for the non-flooding case since
> it's a part of the bridge and the flooded packets will be forwarded to it
> anyway. To remove the forwarding just send a 0/non-existing backup port.
> This is used to avoid numerous scalability problems when using MLAG most
> notably if we have thousands of fdbs one would need to change all of them
> on port carrier going down which takes too long and causes a storm of fdb
> notifications (and again when the port comes back up). In a Multi-chassis
> Link Aggregation setup usually hosts are connected to two different
> switches which act as a single logical switch. Those switches usually have
> a control and backup link between them called peerlink which might be used
> for communication in case a host loses connectivity to one of them.
> We need a fast way to failover in case a host port goes down and currently
> none of the solutions (like bond) cannot fulfill the requirements because
> the participating ports are actually the "master" devices and must have the
> same peerlink as their backup interface and at the same time all of them
> must participate in the bridge device. As Roopa noted it's normal practice
> in routing called fast re-route where a precalculated backup path is used
> when the main one is down.
> Another use case of this is with EVPN, having a single vxlan device which
> is backup of every port. Due to the nature of master devices it's not
> currently possible to use one device as a backup for many and still have
> all of them participate in the bridge (which is master itself).
> More detailed information about MLAG is available at the link below.
> https://docs.cumulusnetworks.com/display/DOCS/Multi-Chassis+Link+Aggregation+-+MLAG
>
> Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Trying to understand this.
Is it the case that what you are trying to solve is the way MLAG
and bridging interact on the Linux side or more a limitation of how
switches operate? Wouldn't this work?
br0 -- team0 -- eth1
+- eth2
The bridge would only have fdb entries for the team device.
Why do eth1 and eth2 have to be master devices? Why would eth1
and eth2 need to be bridge ports.
This kind of thing in the bridge is most likely inevitable, and
I am guilty of introducing same logic into Hyper-V driver.
But still getting pushback that the multi device model is better.
^ permalink raw reply
* [PATCH] ipvs: don't show negative times in ip_vs_conn
From: Matteo Croce @ 2018-07-20 15:19 UTC (permalink / raw)
To: Wensong Zhang, Simon Horman, Julian Anastasov, lvs-devel, netdev,
Jozsef Kadlecsik
Cc: Pablo Neira Ayuso, Florian Westphal, netfilter-devel
Since commit 500462a9de65 ("timers: Switch to a non-cascading wheel"),
timers duration can last even 12.5% more than the scheduled interval.
IPVS has two handlers, /proc/net/ip_vs_conn and /proc/net/ip_vs_conn_sync,
which shows the remaining time before that a connection expires.
The default expire time for a connection is 60 seconds, and the
expiration timer can fire even 4 seconds later than the scheduled time.
The expiration time is calculated subtracting jiffies to the scheduled
expiration time, and it's shown as a huge number when the timer fires late,
since both values are unsigned.
This can confuse script and tools which relies on it, like ipvsadm:
root@mcroce-redhat:~# while ipvsadm -lc |grep SYN_RECV; do sleep 1 ; done
TCP 00:05 SYN_RECV [fc00:1::1]:55732 [fc00:1::2]:8000 [fc00:2000::1]:8000
TCP 00:04 SYN_RECV [fc00:1::1]:55732 [fc00:1::2]:8000 [fc00:2000::1]:8000
TCP 00:03 SYN_RECV [fc00:1::1]:55732 [fc00:1::2]:8000 [fc00:2000::1]:8000
TCP 00:02 SYN_RECV [fc00:1::1]:55732 [fc00:1::2]:8000 [fc00:2000::1]:8000
TCP 00:01 SYN_RECV [fc00:1::1]:55732 [fc00:1::2]:8000 [fc00:2000::1]:8000
TCP 00:00 SYN_RECV [fc00:1::1]:55732 [fc00:1::2]:8000 [fc00:2000::1]:8000
TCP 68719476:44 SYN_RECV [fc00:1::1]:55732 [fc00:1::2]:8000 [fc00:2000::1]:8000
TCP 68719476:43 SYN_RECV [fc00:1::1]:55732 [fc00:1::2]:8000 [fc00:2000::1]:8000
TCP 68719476:42 SYN_RECV [fc00:1::1]:55732 [fc00:1::2]:8000 [fc00:2000::1]:8000
TCP 68719476:41 SYN_RECV [fc00:1::1]:55732 [fc00:1::2]:8000 [fc00:2000::1]:8000
TCP 68719476:40 SYN_RECV [fc00:1::1]:55732 [fc00:1::2]:8000 [fc00:2000::1]:8000
TCP 68719476:39 SYN_RECV [fc00:1::1]:55732 [fc00:1::2]:8000 [fc00:2000::1]:8000
Signed-off-by: Matteo Croce <mcroce@redhat.com>
---
net/netfilter/ipvs/ip_vs_conn.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 99e0aa350dc5..c78c48a6d53f 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -1066,6 +1066,12 @@ static void ip_vs_conn_seq_stop(struct seq_file *seq, void *v)
rcu_read_unlock();
}
+static unsigned int time_left(unsigned long time)
+{
+ return time_is_after_jiffies(time) ?
+ jiffies_to_msecs(time - jiffies) / 1000 : 0;
+}
+
static int ip_vs_conn_seq_show(struct seq_file *seq, void *v)
{
@@ -1102,24 +1108,24 @@ static int ip_vs_conn_seq_show(struct seq_file *seq, void *v)
#ifdef CONFIG_IP_VS_IPV6
if (cp->af == AF_INET6)
seq_printf(seq, "%-3s %pI6 %04X %pI6 %04X "
- "%s %04X %-11s %7lu%s\n",
+ "%s %04X %-11s %7u%s\n",
ip_vs_proto_name(cp->protocol),
&cp->caddr.in6, ntohs(cp->cport),
&cp->vaddr.in6, ntohs(cp->vport),
dbuf, ntohs(cp->dport),
ip_vs_state_name(cp->protocol, cp->state),
- (cp->timer.expires-jiffies)/HZ, pe_data);
+ time_left(cp->timer.expires), pe_data);
else
#endif
seq_printf(seq,
"%-3s %08X %04X %08X %04X"
- " %s %04X %-11s %7lu%s\n",
+ " %s %04X %-11s %7u%s\n",
ip_vs_proto_name(cp->protocol),
ntohl(cp->caddr.ip), ntohs(cp->cport),
ntohl(cp->vaddr.ip), ntohs(cp->vport),
dbuf, ntohs(cp->dport),
ip_vs_state_name(cp->protocol, cp->state),
- (cp->timer.expires-jiffies)/HZ, pe_data);
+ time_left(cp->timer.expires), pe_data);
}
return 0;
}
@@ -1164,26 +1170,26 @@ static int ip_vs_conn_sync_seq_show(struct seq_file *seq, void *v)
#ifdef CONFIG_IP_VS_IPV6
if (cp->af == AF_INET6)
seq_printf(seq, "%-3s %pI6 %04X %pI6 %04X "
- "%s %04X %-11s %-6s %7lu\n",
+ "%s %04X %-11s %-6s %7u\n",
ip_vs_proto_name(cp->protocol),
&cp->caddr.in6, ntohs(cp->cport),
&cp->vaddr.in6, ntohs(cp->vport),
dbuf, ntohs(cp->dport),
ip_vs_state_name(cp->protocol, cp->state),
ip_vs_origin_name(cp->flags),
- (cp->timer.expires-jiffies)/HZ);
+ time_left(cp->timer.expires));
else
#endif
seq_printf(seq,
"%-3s %08X %04X %08X %04X "
- "%s %04X %-11s %-6s %7lu\n",
+ "%s %04X %-11s %-6s %7u\n",
ip_vs_proto_name(cp->protocol),
ntohl(cp->caddr.ip), ntohs(cp->cport),
ntohl(cp->vaddr.ip), ntohs(cp->vport),
dbuf, ntohs(cp->dport),
ip_vs_state_name(cp->protocol, cp->state),
ip_vs_origin_name(cp->flags),
- (cp->timer.expires-jiffies)/HZ);
+ time_left(cp->timer.expires));
}
return 0;
}
--
2.17.1
^ permalink raw reply related
* Re: [PATCH net-next 0/2] net: bridge: add support for backup port
From: Stephen Hemminger @ 2018-07-20 15:22 UTC (permalink / raw)
To: Nikolay Aleksandrov; +Cc: netdev, roopa, anuradhak, bridge, wkok, davem
In-Reply-To: <20180720144826.29892-1-nikolay@cumulusnetworks.com>
On Fri, 20 Jul 2018 17:48:24 +0300
Nikolay Aleksandrov <nikolay@cumulusnetworks.com> wrote:
> Hi,
> This set introduces a new bridge port option that allows any port to have
> any other port (in the same bridge of course) as its backup and traffic
> will be forwarded to the backup port when the primary goes down. This is
> mainly used in MLAG and EVPN setups where we have peerlink path which is
> a backup of many (or even all) ports and is a participating bridge port
> itself. There's more detailed information in patch 02. Patch 01 just
> prepares the port sysfs code for options that take raw value. The main
> issues that this set solves are scalability and fallback latency.
>
> We have used similar code for over 6 months now to bring the fallback
> latency of the backup peerlink down and avoid fdb notification storms.
> Also due to the nature of master devices such setup is currently not
> possible, and last but not least having tens of thousands of fdbs require
> thousands of calls to switch.
>
> I've also CCed our MLAG experts that have been using similar option.
>
> Thanks,
> Nik
>
>
> Nikolay Aleksandrov (2):
> net: bridge: add support for raw sysfs port options
> net: bridge: add support for backup port
>
> include/uapi/linux/if_link.h | 1 +
> net/bridge/br_forward.c | 16 ++++++++-
> net/bridge/br_if.c | 53 ++++++++++++++++++++++++++++
> net/bridge/br_netlink.c | 30 +++++++++++++++-
> net/bridge/br_private.h | 3 ++
> net/bridge/br_sysfs_if.c | 82 ++++++++++++++++++++++++++++++++++++--------
> 6 files changed, 168 insertions(+), 17 deletions(-)
>
Not sure why this has to be built into the bridge.
There already is bonding and teaming, why invent yet another?
^ permalink raw reply
* Re: [PATCH net-next 0/2] net: bridge: add support for backup port
From: Nikolay Aleksandrov @ 2018-07-20 15:26 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, roopa, anuradhak, bridge, wkok, davem
In-Reply-To: <20180720082222.2f8cb8d2@xeon-e3>
On 20/07/18 18:22, Stephen Hemminger wrote:
> On Fri, 20 Jul 2018 17:48:24 +0300
> Nikolay Aleksandrov <nikolay@cumulusnetworks.com> wrote:
>
>> Hi,
>> This set introduces a new bridge port option that allows any port to have
>> any other port (in the same bridge of course) as its backup and traffic
>> will be forwarded to the backup port when the primary goes down. This is
>> mainly used in MLAG and EVPN setups where we have peerlink path which is
>> a backup of many (or even all) ports and is a participating bridge port
>> itself. There's more detailed information in patch 02. Patch 01 just
>> prepares the port sysfs code for options that take raw value. The main
>> issues that this set solves are scalability and fallback latency.
>>
>> We have used similar code for over 6 months now to bring the fallback
>> latency of the backup peerlink down and avoid fdb notification storms.
>> Also due to the nature of master devices such setup is currently not
>> possible, and last but not least having tens of thousands of fdbs require
>> thousands of calls to switch.
>>
>> I've also CCed our MLAG experts that have been using similar option.
>>
>> Thanks,
>> Nik
>>
>>
>> Nikolay Aleksandrov (2):
>> net: bridge: add support for raw sysfs port options
>> net: bridge: add support for backup port
>>
>> include/uapi/linux/if_link.h | 1 +
>> net/bridge/br_forward.c | 16 ++++++++-
>> net/bridge/br_if.c | 53 ++++++++++++++++++++++++++++
>> net/bridge/br_netlink.c | 30 +++++++++++++++-
>> net/bridge/br_private.h | 3 ++
>> net/bridge/br_sysfs_if.c | 82 ++++++++++++++++++++++++++++++++++++--------
>> 6 files changed, 168 insertions(+), 17 deletions(-)
>>
>
> Not sure why this has to be built into the bridge.
> There already is bonding and teaming, why invent yet another?
>
If you read the longer description in patch 02, I've explained why they
cannot solve such problem. The nature of master devices doesn't allow
such setup. We need the ports to be all primary paths with a single
backup path and also to be bridge ports.
I've stressed this point here in the short and also in the longer
description in patch 02.
We have discussed various possible alternatives but they all fall short
and can't deliver neither the switch to backup latency nor the
scalability, and their complexity is huge (multiple virtual devices with
complex forwarding rules).
We haven't taken this decision lightly.
Thanks,
Nik
^ permalink raw reply
* [PATCH -next] net/dsa/realtek: add MODULE_LICENSE()
From: Randy Dunlap @ 2018-07-20 16:16 UTC (permalink / raw)
To: netdev@vger.kernel.org, David Miller; +Cc: LKML, Linus Walleij
From: Randy Dunlap <rdunlap@infradead.org>
Add MODULE_LICENSE() to net/dsa/realtek.o to fix build warning message.
WARNING: modpost: missing MODULE_LICENSE() in drivers/net/dsa/realtek.o
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
---
drivers/net/dsa/realtek-smi.c | 2 ++
1 file changed, 2 insertions(+)
--- linux-next-20180720.orig/drivers/net/dsa/realtek-smi.c
+++ linux-next-20180720/drivers/net/dsa/realtek-smi.c
@@ -485,3 +485,5 @@ static struct platform_driver realtek_sm
.remove = realtek_smi_remove,
};
module_platform_driver(realtek_smi_driver);
+
+MODULE_LICENSE("GPL");
^ permalink raw reply
* [PATCH] rfkill: fix spelling mistake contidion to condition
From: Richard Guy Briggs @ 2018-07-20 15:35 UTC (permalink / raw)
To: netdev; +Cc: Linux-Audit Mailing List, Richard Guy Briggs
This came about while trying to determine if there would be any pattern
match on contid, a new audit container identifier internal variable.
Thsi was the only one.
Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
---
net/rfkill/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 59d0eb9..e89a009 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -494,7 +494,7 @@ void rfkill_remove_epo_lock(void)
/**
* rfkill_is_epo_lock_active - returns true EPO is active
*
- * Returns 0 (false) if there is NOT an active EPO contidion,
+ * Returns 0 (false) if there is NOT an active EPO condition,
* and 1 (true) if there is an active EPO contition, which
* locks all radios in one of the BLOCKED states.
*
--
1.8.3.1
^ permalink raw reply related
* photos
From: Scott @ 2018-07-20 11:54 UTC (permalink / raw)
To: netdev
Hi,
We provide image editing services like - photo cut out; photo clipping
path; photo masking; photo
shadow creation; photo color correction; photo retouching; beauty model
retouching on skin, face,
body; glamour retouching; products retouching and other image editing.
We are also offering to deliver testing for you, so that you get to know
our quality first hand.
If you want to explore further, please reply back.
Thanks and Regards,
Scott
^ permalink raw reply
* [PATCH net-next] xen-netfront: fix queue name setting
From: Vitaly Kuznetsov @ 2018-07-20 16:33 UTC (permalink / raw)
To: netdev
Cc: xen-devel, linux-kernel, Boris Ostrovsky, Juergen Gross,
Ross Lagerwall
Commit f599c64fdf7d ("xen-netfront: Fix race between device setup and
open") changed the initialization order: xennet_create_queues() now
happens before we do register_netdev() so using netdev->name in
xennet_init_queue() is incorrect, we end up with the following in
/proc/interrupts:
60: 139 0 xen-dyn -event eth%d-q0-tx
61: 265 0 xen-dyn -event eth%d-q0-rx
62: 234 0 xen-dyn -event eth%d-q1-tx
63: 1 0 xen-dyn -event eth%d-q1-rx
and this looks ugly. Actually, using early netdev name (even when it's
already set) is also not ideal: nowadays we tend to rename eth devices
and queue name may end up not corresponding to the netdev name.
Use nodename from xenbus device for queue naming: this can't change in VM's
lifetime. Now /proc/interrupts looks like
62: 202 0 xen-dyn -event device/vif/0-q0-tx
63: 317 0 xen-dyn -event device/vif/0-q0-rx
64: 262 0 xen-dyn -event device/vif/0-q1-tx
65: 17 0 xen-dyn -event device/vif/0-q1-rx
Fixes: f599c64fdf7d ("xen-netfront: Fix race between device setup and open")
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
drivers/net/xen-netfront.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index a57daecf1d57..1b40b648ed5c 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1604,7 +1604,7 @@ static int xennet_init_queue(struct netfront_queue *queue)
timer_setup(&queue->rx_refill_timer, rx_refill_timeout, 0);
snprintf(queue->name, sizeof(queue->name), "%s-q%u",
- queue->info->netdev->name, queue->id);
+ queue->info->xbdev->nodename, queue->id);
/* Initialise tx_skbs as a free chain containing every entry. */
queue->tx_skb_freelist = 0;
--
2.14.4
^ permalink raw reply related
* Re: [PATCH iproute2-next] q_cake: Rename autorate_ingress parameter to use dash as word separator
From: David Ahern @ 2018-07-20 15:49 UTC (permalink / raw)
To: Toke Høiland-Jørgensen; +Cc: netdev, cake
In-Reply-To: <20180719165529.6976-1-toke@toke.dk>
On 7/19/18 10:55 AM, Toke Høiland-Jørgensen wrote:
> This is consistent with the other multi-word parameters. Also change the
> JSON output to be consistent with way it is formatted for the other
> options.
>
> Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
> ---
> man/man8/tc-cake.8 | 4 ++--
> tc/q_cake.c | 8 ++++----
> 2 files changed, 6 insertions(+), 6 deletions(-)
applied to iproute2-next. Thanks
^ permalink raw reply
* we edit photos
From: Scott @ 2018-07-20 11:21 UTC (permalink / raw)
To: netdev
Hi,
We provide image editing services like - photo cut out; photo clipping
path; photo masking; photo
shadow creation; photo color correction; photo retouching; beauty model
retouching on skin, face,
body; glamour retouching; products retouching and other image editing.
We are also offering to deliver testing for you, so that you get to know
our quality first hand.
If you want to explore further, please reply back.
Thanks and Regards,
Scott
^ permalink raw reply
* Re: [PATCH net-next 1/2] net: bridge: add support for raw sysfs port options
From: Stephen Hemminger @ 2018-07-20 15:57 UTC (permalink / raw)
To: Nikolay Aleksandrov; +Cc: netdev, roopa, anuradhak, bridge, wkok, davem
In-Reply-To: <20180720144826.29892-2-nikolay@cumulusnetworks.com>
On Fri, 20 Jul 2018 17:48:25 +0300
Nikolay Aleksandrov <nikolay@cumulusnetworks.com> wrote:
> This patch adds a new alternative store callback for port sysfs options
> which takes a raw value (buf) and can use it directly. It is needed for the
> backup port sysfs support since we have to pass the device by its name.
>
> Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
> ---
> There are a few checkpatch warnings here because of the old code, I've
> noted them in my todo and will send separate patch for simple_strtoul
> and the function prototypes.
>
> net/bridge/br_sysfs_if.c | 49 +++++++++++++++++++++++++++++++++---------------
> 1 file changed, 34 insertions(+), 15 deletions(-)
>
> diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
> index f99c5bf5c906..38c58879423d 100644
> --- a/net/bridge/br_sysfs_if.c
> +++ b/net/bridge/br_sysfs_if.c
> @@ -25,6 +25,15 @@ struct brport_attribute {
> struct attribute attr;
> ssize_t (*show)(struct net_bridge_port *, char *);
> int (*store)(struct net_bridge_port *, unsigned long);
> + int (*store_raw)(struct net_bridge_port *, char *);
> +};
> +
> +#define BRPORT_ATTR_RAW(_name, _mode, _show, _store) \
> +const struct brport_attribute brport_attr_##_name = { \
> + .attr = {.name = __stringify(_name), \
> + .mode = _mode }, \
> + .show = _show, \
> + .store_raw = _store, \
> };
>
> #define BRPORT_ATTR(_name, _mode, _show, _store) \
> @@ -270,27 +279,37 @@ static ssize_t brport_store(struct kobject *kobj,
> struct brport_attribute *brport_attr = to_brport_attr(attr);
> struct net_bridge_port *p = to_brport(kobj);
> ssize_t ret = -EINVAL;
> - char *endp;
> unsigned long val;
> + char *endp;
>
> if (!ns_capable(dev_net(p->dev)->user_ns, CAP_NET_ADMIN))
> return -EPERM;
>
> - val = simple_strtoul(buf, &endp, 0);
> - if (endp != buf) {
> - if (!rtnl_trylock())
> - return restart_syscall();
> - if (p->dev && p->br && brport_attr->store) {
> - spin_lock_bh(&p->br->lock);
> - ret = brport_attr->store(p, val);
> - spin_unlock_bh(&p->br->lock);
> - if (!ret) {
> - br_ifinfo_notify(RTM_NEWLINK, NULL, p);
> - ret = count;
> - }
> - }
> - rtnl_unlock();
> + if (!rtnl_trylock())
> + return restart_syscall();
> +
> + if (!p->dev || !p->br)
> + goto out_unlock;
> +
> + if (brport_attr->store_raw) {
> + spin_lock_bh(&p->br->lock);
> + ret = brport_attr->store_raw(p, (char *)buf);
> + spin_unlock_bh(&p->br->lock);
> + } else if (brport_attr->store) {
> + val = simple_strtoul(buf, &endp, 0);
> + if (endp == buf)
> + goto out_unlock;
> + spin_lock_bh(&p->br->lock);
> + ret = brport_attr->store(p, val);
> + spin_unlock_bh(&p->br->lock);
> + }
> + if (!ret) {
> + br_ifinfo_notify(RTM_NEWLINK, NULL, p);
> + ret = count;
> }
> +out_unlock:
> + rtnl_unlock();
> +
> return ret;
> }
>
I see where you are going with this. You want a sysfs attribute where is a string
not a number. This makes sense.
The code might be simpler if you always acquired the lock. Or maybe
move the locking into the store functions.
Casting away the const on the buf variable is going to cause warnings
and should not be necessary.
You might also want an error case if neither store or store_raw are defined.
^ permalink raw reply
* Re: [RFC PATCH] ip: re-introduce fragments cache worker
From: Eric Dumazet @ 2018-07-20 15:58 UTC (permalink / raw)
To: Paolo Abeni; +Cc: Eric Dumazet, netdev, David Miller, Florian Westphal, neilb
In-Reply-To: <921db245c442e4c850670b0584665228bab33c60.camel@redhat.com>
On Fri, Jul 20, 2018 at 7:48 AM Paolo Abeni <pabeni@redhat.com> wrote:
>
> Hi,
>
> On Mon, 2018-07-09 at 05:50 -0700, Eric Dumazet wrote:
> > On 07/09/2018 04:39 AM, Eric Dumazet wrote:
> >
> > > Alternatively, you could try to patch fq_codel to drop all frags of one UDP datagram
> > > instead of few of them.
> >
> > A first step would be to make sure fq_codel_hash() (using skb_get_hash(skb)) selects
> > the same bucket for all frags of a datagram :/
>
> I gave the above a shot and I have some non upstream ready but somewhat
> working code. Anyway it has some issues I'm unable to solve:
> * it's very invasive for fq_codel, because I need to parse each packet
> looking for the fragment id
> * the parsing overhead can't be easily avoided for non fragments
Have you tried using ip_defrag(net, skb, IP_DEFRAG_QDISC) from fq_codel ?
(adding a new value in ip_defrag_users enum)
if (skb->protocol == htons(ETH_P_IP) {
if (ip_is_fragment(ip_hdr(skb))) {
if ((ip_defrag(net, skb, IP_DEFRAG_QDISC))
return 0;
...
>
> I tried also something hopefully along the same lines of your other
> suggestion (drop eariler the fragment queues when above low threshold):
> when allocating a new frag queue and the ipfrag mem is above the low
> th, another frag queue is selected in a pseudorandom way and dropped.
The problem with any strategy like that, is that forthcoming fragments
for this frag queue
will create another frag queue, that will never have a chance to complete.
Some workloads might benefit, others might not.
>
> This latter patch is much smaller, cope quite well with fragment drops,
> and the goodput degradates gracefully when the ipfrag cache is
> overloaded.
>
> I'm wodering if you could consider this second option, too.
>
> Thank you,
>
> Paolo
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox