* Re: [PATCH net-next v6 06/11] net: sched: add 'delete' function to action ops
From: Cong Wang @ 2018-08-09 19:38 UTC (permalink / raw)
To: Vlad Buslov
Cc: Linux Kernel Network Developers, David Miller, Jamal Hadi Salim,
Jiri Pirko, Alexei Starovoitov, Daniel Borkmann,
Yevgeny Kliteynik, Jiri Pirko
In-Reply-To: <1530800673-12280-7-git-send-email-vladbu@mellanox.com>
On Thu, Jul 5, 2018 at 7:24 AM Vlad Buslov <vladbu@mellanox.com> wrote:
>
> Extend action ops with 'delete' function. Each action type to implements
> its own delete function that doesn't depend on rtnl lock.
>
> Implement delete function that is required to delete actions without
> holding rtnl lock. Use action API function that atomically deletes action
> only if it is still in action idr. This implementation prevents concurrent
> threads from deleting same action twice.
I fail to understand why you introduce ops->delete(), it seems all
you want is getting the tn->idrinfo, but you already have tc_action
before calling ops->delete(), and tc_action has ->idrinfo...
Each type of action does the same too, that is, just calling
tcf_idr_delete_index()...
This changelog sucks again, it claims for skipping rtnl lock,
but you can skip rtnl lock by just calling tcf_idr_delete_index()
directly too, it is not the reason for adding ops->delete().
^ permalink raw reply
* Re: [PATCH lora-next v2 2/8] net: lora: sx1301: convert to devm registration of netdev
From: Andreas Färber @ 2018-08-09 19:27 UTC (permalink / raw)
To: Ben Whitten
Cc: starnight, hasnain.virk, netdev, liuxuenetmail, shess,
Ben Whitten
In-Reply-To: <1533818018-29005-2-git-send-email-ben.whitten@lairdtech.com>
Am 09.08.2018 um 14:33 schrieb Ben Whitten:
> We allow the devres framework handle the clean removal of resources on
> teardown of the device, in this case the SPI device, saving lengthy
> unwind code and improving clarity.
>
> Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
> ---
> drivers/net/lora/sx1301.c | 87 +++++++++++++++--------------------------------
> 1 file changed, 27 insertions(+), 60 deletions(-)
>
> diff --git a/drivers/net/lora/sx1301.c b/drivers/net/lora/sx1301.c
> index 5342b61..3c09f5a 100644
> --- a/drivers/net/lora/sx1301.c
> +++ b/drivers/net/lora/sx1301.c
[...]
> static int sx1301_remove(struct spi_device *spi)
> {
> - struct net_device *netdev = spi_get_drvdata(spi);
> -
> - //unregister_loradev(netdev);
Thanks, this part we'll still need later though.
Applying.
Regards,
Andreas
> - free_loradev(netdev);
> -
> dev_info(&spi->dev, "SX1301 module removed\n");
>
> return 0;
[snip]
--
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
^ permalink raw reply
* Re: [PATCH net-next 5/5] net: aquantia: bump driver version
From: Jakub Kicinski @ 2018-08-09 19:20 UTC (permalink / raw)
To: Igor Russkikh; +Cc: Andrew Lunn, David S . Miller, netdev
In-Reply-To: <a409e532-035e-3544-a050-e7238f3a45f4@aquantia.com>
On Thu, 9 Aug 2018 13:10:09 +0300, Igor Russkikh wrote:
> Hi Andrew,
>
> Thanks for the review, agreed on all your findings,
> we'll address these comments in next version.
>
> > Driver versions are pretty much useless. Say somebody backports this
> > driver into a vendor kernel. Vendor kernels are typically based on an
> > old kernel, plus thousands of patches. Is 2.0.4 on such a kernel the
> > same as 2.0.4 in 4.19?
> >
> > You probably want to remove this, just the avoid people thinking is
> > means something.
>
> We do distribute our driver as a separate source package, customers for older
> kernels use it and install without updating their kernels.
>
> We also in fact always have a gap in featureset between upstream driver and our
> preview driver releases on github - alot of people tend to tryout 'hot and latest' driver
> instead of waiting for their distro kernel to receive updates.
>
> All this means we have to understand which version (and featureset)
> users have installed in fields.
>
> `ethtool -i` and this internal driver version is a huge helper for us.
>
> You are right that in event of backporting there could be some
> uncertainty whether that bugfix is there or not. But having kernel
> version plus driver version really helps us to understand the exact
> configuration in fields.
>
> Moreover, inkernel driver version bumps are linked with new features
> added (like in this patchset). Thus the overall concept of internal
> version is still very useful for Aquantia technical and support
> engineers.
>
> Hope the above are good enough arguments to keep up version bumps.
A reasonably successful strategy is to version your out-of-tree driver
with corresponding kernel release versions. Flip the equation.
E.g. current net-next will become 4.19, so all the features you're
pushing now would in your GH repo be:
4.19.0.${extra_numbers_if_you_want}-gh
And you still have single versioning scheme, but the "bump to version
XYZ" commits now go into your local tree not the kernel.
As Andrew said backports make driver versions less than useful. Not
only feature backports to enterprise kernel, but bug fixes which have to
go to stable.
^ permalink raw reply
* Re: [PATCH lora-next v2 1/8] net: lora: add methods for devm registration
From: Andreas Färber @ 2018-08-09 19:18 UTC (permalink / raw)
To: Ben Whitten
Cc: starnight, hasnain.virk, netdev, liuxuenetmail, shess,
Ben Whitten
In-Reply-To: <1533818018-29005-1-git-send-email-ben.whitten@lairdtech.com>
Am 09.08.2018 um 14:33 schrieb Ben Whitten:
> Follow the devm model so that we can avoid lengthy unwind code.
>
> Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
> ---
> drivers/net/lora/dev.c | 28 ++++++++++++++++++++++++++++
> include/linux/lora/dev.h | 1 +
> 2 files changed, 29 insertions(+)
>
> diff --git a/drivers/net/lora/dev.c b/drivers/net/lora/dev.c
> index 8c01106..e32a870 100644
> --- a/drivers/net/lora/dev.c
> +++ b/drivers/net/lora/dev.c
> @@ -84,6 +84,34 @@ void free_loradev(struct net_device *dev)
> }
> EXPORT_SYMBOL_GPL(free_loradev);
>
> +static void devm_free_loradev(struct device *dev, void *res)
> +{
> + struct net_device *net = (*(struct net_device **)res);
> + free_loradev(net);
This is what I meant with adding a variable:
diff --git a/drivers/net/lora/dev.c b/drivers/net/lora/dev.c
index c1b196cdf835..0d4823de8c06 100644
--- a/drivers/net/lora/dev.c
+++ b/drivers/net/lora/dev.c
@@ -87,8 +87,9 @@ EXPORT_SYMBOL_GPL(free_loradev);
static void devm_free_loradev(struct device *dev, void *res)
{
- struct net_device *net = (*(struct net_device **)res);
- free_loradev(net);
+ struct net_device **net = res;
+
+ free_loradev(*net);
}
struct net_device *devm_alloc_loradev(struct device *dev, size_t priv)
Applying.
Thanks,
Andreas
--
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
^ permalink raw reply related
* Re: [net-next, PATCH 1/2] net: socionext: Use descriptor info instead of MMIO reads on Rx
From: Ilias Apalodimas @ 2018-08-09 19:05 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: Networking, Jassi Brar
In-Reply-To: <CAK8P3a0xq2i03Ktr2_10pqkn=Oeebh1p+Yjp26K9CpEA2SxNaQ@mail.gmail.com>
On Thu, Aug 09, 2018 at 05:37:15PM +0200, Arnd Bergmann wrote:
> On Thu, Aug 9, 2018 at 10:02 AM Ilias Apalodimas
> <ilias.apalodimas@linaro.org> wrote:
> >
> > MMIO reads for remaining packets in queue occur (at least)twice per
> > invocation of netsec_process_rx(). We can use the packet descriptor to
> > identify if it's owned by the hardware and break out, avoiding the more
> > expensive MMIO read operations. This has a ~2% increase on the pps of the
> > Rx path when tested with 64byte packets
> >
> > Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
> > ---
> > drivers/net/ethernet/socionext/netsec.c | 19 +++++--------------
> > 1 file changed, 5 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c
> > index 01589b6..ae32909 100644
> > --- a/drivers/net/ethernet/socionext/netsec.c
> > +++ b/drivers/net/ethernet/socionext/netsec.c
> > @@ -657,8 +657,6 @@ static struct sk_buff *netsec_get_rx_pkt_data(struct netsec_priv *priv,
>
> > + if (de->attr & (1U << NETSEC_RX_PKT_OWN_FIELD))
> > + break;
> > done++;
>
> Should this use READ_ONCE() to prevent the compiler from moving the
> access around? I see that netsec_get_rx_pkt_data() has a dma_rmb()
> before reading the data, which prevents the CPU from doing something
> wrong here, but not the compiler.
>
> Arnd
As we discussed i'll send a V2 with the dma_rmb() right after the desc status
read
Thnaks
Ilias
^ permalink raw reply
* [PATCH net] l2tp: use sk_dst_check() to avoid race on sk->sk_dst_cache
From: Wei Wang @ 2018-08-09 18:54 UTC (permalink / raw)
To: David Miller, netdev; +Cc: Martin KaFai Lau, Wei Wang, David Ahern, Cong Wang
From: Wei Wang <weiwan@google.com>
In l2tp code, if it is a L2TP_UDP_ENCAP tunnel, tunnel->sk points to a
UDP socket. User could call sendmsg() on both this tunnel and the UDP
socket itself concurrently. As l2tp_xmit_skb() holds socket lock and call
__sk_dst_check() to refresh sk->sk_dst_cache, while udpv6_sendmsg() is
lockless and call sk_dst_check() to refresh sk->sk_dst_cache, there
could be a race and cause the dst cache to be freed multiple times.
So we fix l2tp side code to always call sk_dst_check() to garantee
xchg() is called when refreshing sk->sk_dst_cache to avoid race
conditions.
Syzkaller reported stack trace:
BUG: KASAN: use-after-free in atomic_read include/asm-generic/atomic-instrumented.h:21 [inline]
BUG: KASAN: use-after-free in atomic_fetch_add_unless include/linux/atomic.h:575 [inline]
BUG: KASAN: use-after-free in atomic_add_unless include/linux/atomic.h:597 [inline]
BUG: KASAN: use-after-free in dst_hold_safe include/net/dst.h:308 [inline]
BUG: KASAN: use-after-free in ip6_hold_safe+0xe6/0x670 net/ipv6/route.c:1029
Read of size 4 at addr ffff8801aea9a880 by task syz-executor129/4829
CPU: 0 PID: 4829 Comm: syz-executor129 Not tainted 4.18.0-rc7-next-20180802+ #30
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x1c9/0x2b4 lib/dump_stack.c:113
print_address_description+0x6c/0x20b mm/kasan/report.c:256
kasan_report_error mm/kasan/report.c:354 [inline]
kasan_report.cold.7+0x242/0x30d mm/kasan/report.c:412
check_memory_region_inline mm/kasan/kasan.c:260 [inline]
check_memory_region+0x13e/0x1b0 mm/kasan/kasan.c:267
kasan_check_read+0x11/0x20 mm/kasan/kasan.c:272
atomic_read include/asm-generic/atomic-instrumented.h:21 [inline]
atomic_fetch_add_unless include/linux/atomic.h:575 [inline]
atomic_add_unless include/linux/atomic.h:597 [inline]
dst_hold_safe include/net/dst.h:308 [inline]
ip6_hold_safe+0xe6/0x670 net/ipv6/route.c:1029
rt6_get_pcpu_route net/ipv6/route.c:1249 [inline]
ip6_pol_route+0x354/0xd20 net/ipv6/route.c:1922
ip6_pol_route_output+0x54/0x70 net/ipv6/route.c:2098
fib6_rule_lookup+0x283/0x890 net/ipv6/fib6_rules.c:122
ip6_route_output_flags+0x2c5/0x350 net/ipv6/route.c:2126
ip6_dst_lookup_tail+0x1278/0x1da0 net/ipv6/ip6_output.c:978
ip6_dst_lookup_flow+0xc8/0x270 net/ipv6/ip6_output.c:1079
ip6_sk_dst_lookup_flow+0x5ed/0xc50 net/ipv6/ip6_output.c:1117
udpv6_sendmsg+0x2163/0x36b0 net/ipv6/udp.c:1354
inet_sendmsg+0x1a1/0x690 net/ipv4/af_inet.c:798
sock_sendmsg_nosec net/socket.c:622 [inline]
sock_sendmsg+0xd5/0x120 net/socket.c:632
___sys_sendmsg+0x51d/0x930 net/socket.c:2115
__sys_sendmmsg+0x240/0x6f0 net/socket.c:2210
__do_sys_sendmmsg net/socket.c:2239 [inline]
__se_sys_sendmmsg net/socket.c:2236 [inline]
__x64_sys_sendmmsg+0x9d/0x100 net/socket.c:2236
do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x446a29
Code: e8 ac b8 02 00 48 83 c4 18 c3 0f 1f 80 00 00 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 eb 08 fc ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007f4de5532db8 EFLAGS: 00000246 ORIG_RAX: 0000000000000133
RAX: ffffffffffffffda RBX: 00000000006dcc38 RCX: 0000000000446a29
RDX: 00000000000000b8 RSI: 0000000020001b00 RDI: 0000000000000003
RBP: 00000000006dcc30 R08: 00007f4de5533700 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00000000006dcc3c
R13: 00007ffe2b830fdf R14: 00007f4de55339c0 R15: 0000000000000001
Fixes: 71b1391a4128 ("l2tp: ensure sk->dst is still valid")
Reported-by: syzbot+05f840f3b04f211bad55@syzkaller.appspotmail.com
Signed-off-by: Wei Wang <weiwan@google.com>
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Cong Wang <xiyou.wangcong@gmail.com>
---
net/l2tp/l2tp_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 40261cb68e83..7166b61338d4 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1110,7 +1110,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
/* Get routing info from the tunnel socket */
skb_dst_drop(skb);
- skb_dst_set(skb, dst_clone(__sk_dst_check(sk, 0)));
+ skb_dst_set(skb, dst_clone(sk_dst_check(sk, 0)));
inet = inet_sk(sk);
fl = &inet->cork.fl;
--
2.18.0.597.ga71716f1ad-goog
^ permalink raw reply related
* Re: [PATCH] ethernet/qlogic: remove unused array msi_tgt_status
From: David Miller @ 2018-08-09 21:17 UTC (permalink / raw)
To: colin.king
Cc: harish.patil, manish.chopra, Dept-GELinuxNICDev, netdev,
kernel-janitors, linux-kernel
In-Reply-To: <20180808180427.14864-1-colin.king@canonical.com>
From: Colin King <colin.king@canonical.com>
Date: Wed, 8 Aug 2018 19:04:27 +0100
> From: Colin Ian King <colin.king@canonical.com>
>
> Array msi_tgt_status is defined but never used, hence it is
> redundant and can be removed.
>
> Cleans up clang warning:
> warning: 'msi_tgt_status' defined but not used [-Wunused-const-variable=]
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
Applied, thank you.
^ permalink raw reply
* Re: [PATCH net-next] mlxsw: spectrum_flower: use PTR_ERR_OR_ZERO()
From: David Miller @ 2018-08-09 21:14 UTC (permalink / raw)
To: yuehaibing; +Cc: jiri, linux-kernel, netdev, idosch
In-Reply-To: <20180808122908.13664-1-yuehaibing@huawei.com>
From: YueHaibing <yuehaibing@huawei.com>
Date: Wed, 8 Aug 2018 20:29:08 +0800
> Fix ptr_ret.cocci warnings:
> drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c:543:1-3: WARNING: PTR_ERR_OR_ZERO can be used
>
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] decnet: fix using plain integer as NULL warning
From: David Miller @ 2018-08-09 21:12 UTC (permalink / raw)
To: yuehaibing; +Cc: linux-kernel, netdev, keescook, edumazet, linux-decnet-user
In-Reply-To: <20180808115932.12944-1-yuehaibing@huawei.com>
From: YueHaibing <yuehaibing@huawei.com>
Date: Wed, 8 Aug 2018 19:59:32 +0800
> Fixes the following sparse warning:
> net/decnet/dn_route.c:407:30: warning: Using plain integer as NULL pointer
> net/decnet/dn_route.c:1923:22: warning: Using plain integer as NULL pointer
>
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] net: skbuff.h: fix using plain integer as NULL warning
From: David Miller @ 2018-08-09 21:10 UTC (permalink / raw)
To: yuehaibing
Cc: edumazet, willemb, dja, linux-kernel, netdev, ast, pabeni, posk,
daniel
In-Reply-To: <20180808114031.12292-1-yuehaibing@huawei.com>
From: YueHaibing <yuehaibing@huawei.com>
Date: Wed, 8 Aug 2018 19:40:31 +0800
> Fixes the following sparse warning:
> ./include/linux/skbuff.h:2365:58: warning: Using plain integer as NULL pointer
>
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] be2net: Use Kconfig flag to support for enabling/disabling adapters
From: David Miller @ 2018-08-09 21:09 UTC (permalink / raw)
To: poros
Cc: netdev, ivecera, sathya.perla, ajit.khaparde,
sriharsha.basavapatna, somnath.kotur, linux-kernel
In-Reply-To: <20180808113505.550-1-poros@redhat.com>
From: Petr Oros <poros@redhat.com>
Date: Wed, 8 Aug 2018 13:35:01 +0200
> Add flags to enable/disable supported chips in be2net.
>
> With disable support are removed coresponding PCI IDs and
> also codepaths with [BE2|BE3|BEx|lancer|skyhawk]_chip checks.
>
> Disable chip will reduce module size by:
> BE2 ~2kb
> BE3 ~3kb
> Lancer ~10kb
> Skyhawk ~9kb
>
> When enable skyhawk only it will reduce module size by ~20kb
>
> New help style in Kconfig
>
> Reviewed-by: Ivan Vecera <ivecera@redhat.com>
> Signed-off-by: Petr Oros <poros@redhat.com>
Applied.
^ permalink raw reply
* Re: [PATCH v4 net-next 0/9] Add support for XGMAC2 in stmmac
From: David Miller @ 2018-08-09 18:16 UTC (permalink / raw)
To: Jose.Abreu
Cc: netdev, Joao.Pinto, peppe.cavallaro, alexandre.torgue, andrew,
f.fainelli
In-Reply-To: <cover.1533715274.git.joabreu@synopsys.com>
From: Jose Abreu <Jose.Abreu@synopsys.com>
Date: Wed, 8 Aug 2018 09:04:28 +0100
> This series adds support for 10Gigabit IP in stmmac.
Series applied, thanks Jose.
^ permalink raw reply
* [PATCH net-next 3/3] qede: Ingress tc flower offload (drop action) support.
From: Manish Chopra @ 2018-08-09 18:13 UTC (permalink / raw)
To: davem; +Cc: netdev, ariel.elior, michal.kalderon
In-Reply-To: <20180809181351.32394-1-manish.chopra@cavium.com>
The main motive of this patch is to lay down driver's
tc offload infrastructure in place.
With these changes tc can offload various supported flow
profiles (4 tuples, src-ip, dst-ip, l4 port) for the drop
action. Dropped flows statistic is a global counter for
all the offloaded flows for drop action and is populated
in ethtool statistics as common "gft_filter_drop".
Examples -
tc qdisc add dev p4p1 ingress
tc filter add dev p4p1 protocol ipv4 parent ffff: flower \
skip_sw ip_proto tcp dst_ip 192.168.40.200 action drop
tc filter add dev p4p1 protocol ipv4 parent ffff: flower \
skip_sw ip_proto udp src_ip 192.168.40.100 action drop
tc filter add dev p4p1 protocol ipv4 parent ffff: flower \
skip_sw ip_proto tcp src_ip 192.168.40.100 dst_ip 192.168.40.200 \
src_port 453 dst_port 876 action drop
tc filter add dev p4p1 protocol ipv4 parent ffff: flower \
skip_sw ip_proto tcp dst_port 98 action drop
Signed-off-by: Manish Chopra <manish.chopra@cavium.com>
Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
---
drivers/net/ethernet/qlogic/qede/qede.h | 7 +-
drivers/net/ethernet/qlogic/qede/qede_ethtool.c | 2 +-
drivers/net/ethernet/qlogic/qede/qede_filter.c | 308 +++++++++++++++++++++++-
drivers/net/ethernet/qlogic/qede/qede_main.c | 56 ++++-
4 files changed, 362 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h
index e90c60a..6a4d266 100644
--- a/drivers/net/ethernet/qlogic/qede/qede.h
+++ b/drivers/net/ethernet/qlogic/qede/qede.h
@@ -52,6 +52,9 @@
#include <linux/qed/qed_chain.h>
#include <linux/qed/qed_eth_if.h>
+#include <net/pkt_cls.h>
+#include <net/tc_act/tc_gact.h>
+
#define QEDE_MAJOR_VERSION 8
#define QEDE_MINOR_VERSION 33
#define QEDE_REVISION_VERSION 0
@@ -469,7 +472,7 @@ int qede_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
void qede_free_arfs(struct qede_dev *edev);
int qede_alloc_arfs(struct qede_dev *edev);
int qede_add_cls_rule(struct qede_dev *edev, struct ethtool_rxnfc *info);
-int qede_del_cls_rule(struct qede_dev *edev, struct ethtool_rxnfc *info);
+int qede_delete_flow_filter(struct qede_dev *edev, u64 cookie);
int qede_get_cls_rule_entry(struct qede_dev *edev, struct ethtool_rxnfc *cmd);
int qede_get_cls_rule_all(struct qede_dev *edev, struct ethtool_rxnfc *info,
u32 *rule_locs);
@@ -535,6 +538,8 @@ void qede_reload(struct qede_dev *edev,
int qede_txq_has_work(struct qede_tx_queue *txq);
void qede_recycle_rx_bd_ring(struct qede_rx_queue *rxq, u8 count);
void qede_update_rx_prod(struct qede_dev *edev, struct qede_rx_queue *rxq);
+int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto,
+ struct tc_cls_flower_offload *f);
#define RX_RING_SIZE_POW 13
#define RX_RING_SIZE ((u16)BIT(RX_RING_SIZE_POW))
diff --git a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
index 2bd84d6..19652cd 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
@@ -1285,7 +1285,7 @@ static int qede_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info)
rc = qede_add_cls_rule(edev, info);
break;
case ETHTOOL_SRXCLSRLDEL:
- rc = qede_del_cls_rule(edev, info);
+ rc = qede_delete_flow_filter(edev, info->fs.location);
break;
default:
DP_INFO(edev, "Command parameters not supported\n");
diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c
index d090257..9673d19 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_filter.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c
@@ -83,7 +83,7 @@ struct qede_arfs_fltr_node {
struct qede_arfs_tuple tuple;
u32 flow_id;
- u16 sw_id;
+ u64 sw_id;
u16 rxq_id;
u16 next_rxq_id;
u8 vfid;
@@ -138,7 +138,7 @@ static void qede_configure_arfs_fltr(struct qede_dev *edev,
n->tuple.stringify(&n->tuple, tuple_buffer);
DP_VERBOSE(edev, NETIF_MSG_RX_STATUS,
- "%s sw_id[0x%x]: %s [vf %u queue %d]\n",
+ "%s sw_id[0x%llx]: %s [vf %u queue %d]\n",
add_fltr ? "Adding" : "Deleting",
n->sw_id, tuple_buffer, n->vfid, rxq_id);
}
@@ -152,7 +152,10 @@ static void qede_configure_arfs_fltr(struct qede_dev *edev,
qede_free_arfs_filter(struct qede_dev *edev, struct qede_arfs_fltr_node *fltr)
{
kfree(fltr->data);
- clear_bit(fltr->sw_id, edev->arfs->arfs_fltr_bmap);
+
+ if (fltr->sw_id < QEDE_RFS_MAX_FLTR)
+ clear_bit(fltr->sw_id, edev->arfs->arfs_fltr_bmap);
+
kfree(fltr);
}
@@ -214,7 +217,7 @@ void qede_arfs_filter_op(void *dev, void *filter, u8 fw_rc)
if (fw_rc) {
DP_NOTICE(edev,
- "Failed arfs filter configuration fw_rc=%d, flow_id=%d, sw_id=%d, src_port=%d, dst_port=%d, rxq=%d\n",
+ "Failed arfs filter configuration fw_rc=%d, flow_id=%d, sw_id=0x%llx, src_port=%d, dst_port=%d, rxq=%d\n",
fw_rc, fltr->flow_id, fltr->sw_id,
ntohs(fltr->tuple.src_port),
ntohs(fltr->tuple.dst_port), fltr->rxq_id);
@@ -1348,7 +1351,7 @@ void qede_config_rx_mode(struct net_device *ndev)
}
static struct qede_arfs_fltr_node *
-qede_get_arfs_fltr_by_loc(struct hlist_head *head, u32 location)
+qede_get_arfs_fltr_by_loc(struct hlist_head *head, u64 location)
{
struct qede_arfs_fltr_node *fltr;
@@ -1959,9 +1962,8 @@ int qede_add_cls_rule(struct qede_dev *edev, struct ethtool_rxnfc *info)
return rc;
}
-int qede_del_cls_rule(struct qede_dev *edev, struct ethtool_rxnfc *info)
+int qede_delete_flow_filter(struct qede_dev *edev, u64 cookie)
{
- struct ethtool_rx_flow_spec *fsp = &info->fs;
struct qede_arfs_fltr_node *fltr = NULL;
int rc = -EPERM;
@@ -1970,7 +1972,7 @@ int qede_del_cls_rule(struct qede_dev *edev, struct ethtool_rxnfc *info)
goto unlock;
fltr = qede_get_arfs_fltr_by_loc(QEDE_ARFS_BUCKET_HEAD(edev, 0),
- fsp->location);
+ cookie);
if (!fltr)
goto unlock;
@@ -2000,3 +2002,293 @@ int qede_get_arfs_filter_count(struct qede_dev *edev)
__qede_unlock(edev);
return count;
}
+
+static int qede_parse_actions(struct qede_dev *edev,
+ struct tcf_exts *exts)
+{
+ int rc = -EINVAL, num_act = 0;
+ const struct tc_action *a;
+ bool is_drop = false;
+ LIST_HEAD(actions);
+
+ if (!tcf_exts_has_actions(exts)) {
+ DP_NOTICE(edev, "No tc actions received\n");
+ return rc;
+ }
+
+ tcf_exts_to_list(exts, &actions);
+ list_for_each_entry(a, &actions, list) {
+ num_act++;
+
+ if (is_tcf_gact_shot(a))
+ is_drop = true;
+ }
+
+ if (num_act == 1 && is_drop)
+ return 0;
+
+ return rc;
+}
+
+static int
+qede_tc_parse_ports(struct qede_dev *edev,
+ struct tc_cls_flower_offload *f,
+ struct qede_arfs_tuple *t)
+{
+ if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_PORTS)) {
+ struct flow_dissector_key_ports *key, *mask;
+
+ key = skb_flow_dissector_target(f->dissector,
+ FLOW_DISSECTOR_KEY_PORTS,
+ f->key);
+ mask = skb_flow_dissector_target(f->dissector,
+ FLOW_DISSECTOR_KEY_PORTS,
+ f->mask);
+
+ if ((key->src && mask->src != U16_MAX) ||
+ (key->dst && mask->dst != U16_MAX)) {
+ DP_NOTICE(edev, "Do not support ports masks\n");
+ return -EINVAL;
+ }
+
+ t->src_port = key->src;
+ t->dst_port = key->dst;
+ }
+
+ return 0;
+}
+
+static int
+qede_tc_parse_v6_common(struct qede_dev *edev,
+ struct tc_cls_flower_offload *f,
+ struct qede_arfs_tuple *t)
+{
+ struct in6_addr zero_addr, addr;
+
+ memset(&zero_addr, 0, sizeof(addr));
+ memset(&addr, 0xff, sizeof(addr));
+
+ if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
+ struct flow_dissector_key_ipv6_addrs *key, *mask;
+
+ key = skb_flow_dissector_target(f->dissector,
+ FLOW_DISSECTOR_KEY_IPV6_ADDRS,
+ f->key);
+ mask = skb_flow_dissector_target(f->dissector,
+ FLOW_DISSECTOR_KEY_IPV6_ADDRS,
+ f->mask);
+
+ if ((memcmp(&key->src, &zero_addr, sizeof(addr)) &&
+ memcmp(&mask->src, &addr, sizeof(addr))) ||
+ (memcmp(&key->dst, &zero_addr, sizeof(addr)) &&
+ memcmp(&mask->dst, &addr, sizeof(addr)))) {
+ DP_NOTICE(edev,
+ "Do not support IPv6 address prefix/mask\n");
+ return -EINVAL;
+ }
+
+ memcpy(&t->src_ipv6, &key->src, sizeof(addr));
+ memcpy(&t->dst_ipv6, &key->dst, sizeof(addr));
+ }
+
+ if (qede_tc_parse_ports(edev, f, t))
+ return -EINVAL;
+
+ return qede_set_v6_tuple_to_profile(edev, t, &zero_addr);
+}
+
+static int
+qede_tc_parse_v4_common(struct qede_dev *edev,
+ struct tc_cls_flower_offload *f,
+ struct qede_arfs_tuple *t)
+{
+ if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
+ struct flow_dissector_key_ipv4_addrs *key, *mask;
+
+ key = skb_flow_dissector_target(f->dissector,
+ FLOW_DISSECTOR_KEY_IPV4_ADDRS,
+ f->key);
+ mask = skb_flow_dissector_target(f->dissector,
+ FLOW_DISSECTOR_KEY_IPV4_ADDRS,
+ f->mask);
+
+ if ((key->src && mask->src != U32_MAX) ||
+ (key->dst && mask->dst != U32_MAX)) {
+ DP_NOTICE(edev, "Do not support ipv4 prefix/masks\n");
+ return -EINVAL;
+ }
+
+ t->src_ipv4 = key->src;
+ t->dst_ipv4 = key->dst;
+ }
+
+ if (qede_tc_parse_ports(edev, f, t))
+ return -EINVAL;
+
+ return qede_set_v4_tuple_to_profile(edev, t);
+}
+
+static int
+qede_tc_parse_tcp_v6(struct qede_dev *edev,
+ struct tc_cls_flower_offload *f,
+ struct qede_arfs_tuple *tuple)
+{
+ tuple->ip_proto = IPPROTO_TCP;
+ tuple->eth_proto = htons(ETH_P_IPV6);
+
+ return qede_tc_parse_v6_common(edev, f, tuple);
+}
+
+static int
+qede_tc_parse_tcp_v4(struct qede_dev *edev,
+ struct tc_cls_flower_offload *f,
+ struct qede_arfs_tuple *tuple)
+{
+ tuple->ip_proto = IPPROTO_TCP;
+ tuple->eth_proto = htons(ETH_P_IP);
+
+ return qede_tc_parse_v4_common(edev, f, tuple);
+}
+
+static int
+qede_tc_parse_udp_v6(struct qede_dev *edev,
+ struct tc_cls_flower_offload *f,
+ struct qede_arfs_tuple *tuple)
+{
+ tuple->ip_proto = IPPROTO_UDP;
+ tuple->eth_proto = htons(ETH_P_IPV6);
+
+ return qede_tc_parse_v6_common(edev, f, tuple);
+}
+
+static int
+qede_tc_parse_udp_v4(struct qede_dev *edev,
+ struct tc_cls_flower_offload *f,
+ struct qede_arfs_tuple *tuple)
+{
+ tuple->ip_proto = IPPROTO_UDP;
+ tuple->eth_proto = htons(ETH_P_IP);
+
+ return qede_tc_parse_v4_common(edev, f, tuple);
+}
+
+static int
+qede_parse_flower_attr(struct qede_dev *edev, __be16 proto,
+ struct tc_cls_flower_offload *f,
+ struct qede_arfs_tuple *tuple)
+{
+ int rc = -EINVAL;
+ u8 ip_proto = 0;
+
+ memset(tuple, 0, sizeof(*tuple));
+
+ if (f->dissector->used_keys &
+ ~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |
+ BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
+ BIT(FLOW_DISSECTOR_KEY_BASIC) |
+ BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
+ BIT(FLOW_DISSECTOR_KEY_PORTS))) {
+ DP_NOTICE(edev, "Unsupported key set:0x%x\n",
+ f->dissector->used_keys);
+ return -EOPNOTSUPP;
+ }
+
+ if (proto != htons(ETH_P_IP) &&
+ proto != htons(ETH_P_IPV6)) {
+ DP_NOTICE(edev, "Unsupported proto=0x%x\n", proto);
+ return -EPROTONOSUPPORT;
+ }
+
+ if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
+ struct flow_dissector_key_basic *key;
+
+ key = skb_flow_dissector_target(f->dissector,
+ FLOW_DISSECTOR_KEY_BASIC,
+ f->key);
+ ip_proto = key->ip_proto;
+ }
+
+ if (ip_proto == IPPROTO_TCP && proto == htons(ETH_P_IP))
+ rc = qede_tc_parse_tcp_v4(edev, f, tuple);
+ else if (ip_proto == IPPROTO_TCP && proto == htons(ETH_P_IPV6))
+ rc = qede_tc_parse_tcp_v6(edev, f, tuple);
+ else if (ip_proto == IPPROTO_UDP && proto == htons(ETH_P_IP))
+ rc = qede_tc_parse_udp_v4(edev, f, tuple);
+ else if (ip_proto == IPPROTO_UDP && proto == htons(ETH_P_IPV6))
+ rc = qede_tc_parse_udp_v6(edev, f, tuple);
+ else
+ DP_NOTICE(edev, "Invalid tc protocol request\n");
+
+ return rc;
+}
+
+int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto,
+ struct tc_cls_flower_offload *f)
+{
+ struct qede_arfs_fltr_node *n;
+ int min_hlen, rc = -EINVAL;
+ struct qede_arfs_tuple t;
+
+ __qede_lock(edev);
+
+ if (!edev->arfs) {
+ rc = -EPERM;
+ goto unlock;
+ }
+
+ /* parse flower attribute and prepare filter */
+ if (qede_parse_flower_attr(edev, proto, f, &t))
+ goto unlock;
+
+ /* Validate profile mode and number of filters */
+ if ((edev->arfs->filter_count && edev->arfs->mode != t.mode) ||
+ edev->arfs->filter_count == QEDE_RFS_MAX_FLTR) {
+ DP_NOTICE(edev,
+ "Filter configuration invalidated, filter mode=0x%x, configured mode=0x%x, filter count=0x%x\n",
+ t.mode, edev->arfs->mode, edev->arfs->filter_count);
+ goto unlock;
+ }
+
+ /* parse tc actions and get the vf_id */
+ if (qede_parse_actions(edev, f->exts))
+ goto unlock;
+
+ if (qede_flow_find_fltr(edev, &t)) {
+ rc = -EEXIST;
+ goto unlock;
+ }
+
+ n = kzalloc(sizeof(*n), GFP_KERNEL);
+ if (!n) {
+ rc = -ENOMEM;
+ goto unlock;
+ }
+
+ min_hlen = qede_flow_get_min_header_size(&t);
+
+ n->data = kzalloc(min_hlen, GFP_KERNEL);
+ if (!n->data) {
+ kfree(n);
+ rc = -ENOMEM;
+ goto unlock;
+ }
+
+ memcpy(&n->tuple, &t, sizeof(n->tuple));
+
+ n->buf_len = min_hlen;
+ n->b_is_drop = true;
+ n->sw_id = f->cookie;
+
+ n->tuple.build_hdr(&n->tuple, n->data);
+
+ rc = qede_enqueue_fltr_and_config_searcher(edev, n, 0);
+ if (rc)
+ goto unlock;
+
+ qede_configure_arfs_fltr(edev, n, n->rxq_id, true);
+ rc = qede_poll_arfs_filter_config(edev, n);
+
+unlock:
+ __qede_unlock(edev);
+ return rc;
+}
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index d7299af..4b5d98f 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -557,12 +557,66 @@ int qede_setup_tc(struct net_device *ndev, u8 num_tc)
}
static int
+qede_set_flower(struct qede_dev *edev, struct tc_cls_flower_offload *f,
+ __be16 proto)
+{
+ switch (f->command) {
+ case TC_CLSFLOWER_REPLACE:
+ return qede_add_tc_flower_fltr(edev, proto, f);
+ case TC_CLSFLOWER_DESTROY:
+ return qede_delete_flow_filter(edev, f->cookie);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int qede_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
+ void *cb_priv)
+{
+ struct tc_cls_flower_offload *f;
+ struct qede_dev *edev = cb_priv;
+
+ if (!tc_cls_can_offload_and_chain0(edev->ndev, type_data))
+ return -EOPNOTSUPP;
+
+ switch (type) {
+ case TC_SETUP_CLSFLOWER:
+ f = type_data;
+ return qede_set_flower(edev, f, f->common.protocol);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int qede_setup_tc_block(struct qede_dev *edev,
+ struct tc_block_offload *f)
+{
+ if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
+ return -EOPNOTSUPP;
+
+ switch (f->command) {
+ case TC_BLOCK_BIND:
+ return tcf_block_cb_register(f->block,
+ qede_setup_tc_block_cb,
+ edev, edev, f->extack);
+ case TC_BLOCK_UNBIND:
+ tcf_block_cb_unregister(f->block, qede_setup_tc_block_cb, edev);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int
qede_setup_tc_offload(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
+ struct qede_dev *edev = netdev_priv(dev);
struct tc_mqprio_qopt *mqprio;
switch (type) {
+ case TC_SETUP_BLOCK:
+ return qede_setup_tc_block(edev, type_data);
case TC_SETUP_QDISC_MQPRIO:
mqprio = type_data;
@@ -727,7 +781,7 @@ static void qede_init_ndev(struct qede_dev *edev)
/* user-changeble features */
hw_features = NETIF_F_GRO | NETIF_F_GRO_HW | NETIF_F_SG |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
- NETIF_F_TSO | NETIF_F_TSO6;
+ NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_TC;
if (!IS_VF(edev) && edev->dev_info.common.num_hwfns == 1)
hw_features |= NETIF_F_NTUPLE;
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next 2/3] qede: Add destination ip based flow profile.
From: Manish Chopra @ 2018-08-09 18:13 UTC (permalink / raw)
To: davem; +Cc: netdev, ariel.elior, michal.kalderon
In-Reply-To: <20180809181351.32394-1-manish.chopra@cavium.com>
This patch adds support for dropping and redirecting
the flows based on destination IP in the packet.
This also moves the profile mode settings in their own
functions which can be used through tc flows in successive
patch.
For example -
ethtool -N p5p1 flow-type tcp4 dst-ip 192.168.40.100 action -1
ethtool -N p5p1 flow-type udp4 dst-ip 192.168.50.100 action 1
ethtool -N p5p1 flow-type tcp4 dst-ip 192.168.60.100 action 0x100000000
Signed-off-by: Manish Chopra <manish.chopra@cavium.com>
Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
---
drivers/net/ethernet/qlogic/qede/qede_filter.c | 114 ++++++++++++++-----------
1 file changed, 66 insertions(+), 48 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c
index f9a327c..d090257 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_filter.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c
@@ -1599,6 +1599,69 @@ static int qede_flow_spec_validate_unused(struct qede_dev *edev,
return 0;
}
+static int qede_set_v4_tuple_to_profile(struct qede_dev *edev,
+ struct qede_arfs_tuple *t)
+{
+ /* We must have Only 4-tuples/l4 port/src ip/dst ip
+ * as an input.
+ */
+ if (t->src_port && t->dst_port && t->src_ipv4 && t->dst_ipv4) {
+ t->mode = QED_FILTER_CONFIG_MODE_5_TUPLE;
+ } else if (!t->src_port && t->dst_port &&
+ !t->src_ipv4 && !t->dst_ipv4) {
+ t->mode = QED_FILTER_CONFIG_MODE_L4_PORT;
+ } else if (!t->src_port && !t->dst_port &&
+ !t->dst_ipv4 && t->src_ipv4) {
+ t->mode = QED_FILTER_CONFIG_MODE_IP_SRC;
+ } else if (!t->src_port && !t->dst_port &&
+ t->dst_ipv4 && !t->src_ipv4) {
+ t->mode = QED_FILTER_CONFIG_MODE_IP_DEST;
+ } else {
+ DP_INFO(edev, "Invalid N-tuple\n");
+ return -EOPNOTSUPP;
+ }
+
+ t->ip_comp = qede_flow_spec_ipv4_cmp;
+ t->build_hdr = qede_flow_build_ipv4_hdr;
+ t->stringify = qede_flow_stringify_ipv4_hdr;
+
+ return 0;
+}
+
+static int qede_set_v6_tuple_to_profile(struct qede_dev *edev,
+ struct qede_arfs_tuple *t,
+ struct in6_addr *zaddr)
+{
+ /* We must have Only 4-tuples/l4 port/src ip/dst ip
+ * as an input.
+ */
+ if (t->src_port && t->dst_port &&
+ memcmp(&t->src_ipv6, zaddr, sizeof(struct in6_addr)) &&
+ memcmp(&t->dst_ipv6, zaddr, sizeof(struct in6_addr))) {
+ t->mode = QED_FILTER_CONFIG_MODE_5_TUPLE;
+ } else if (!t->src_port && t->dst_port &&
+ !memcmp(&t->src_ipv6, zaddr, sizeof(struct in6_addr)) &&
+ !memcmp(&t->dst_ipv6, zaddr, sizeof(struct in6_addr))) {
+ t->mode = QED_FILTER_CONFIG_MODE_L4_PORT;
+ } else if (!t->src_port && !t->dst_port &&
+ !memcmp(&t->dst_ipv6, zaddr, sizeof(struct in6_addr)) &&
+ memcmp(&t->src_ipv6, zaddr, sizeof(struct in6_addr))) {
+ t->mode = QED_FILTER_CONFIG_MODE_IP_SRC;
+ } else if (!t->src_port && !t->dst_port &&
+ memcmp(&t->dst_ipv6, zaddr, sizeof(struct in6_addr)) &&
+ !memcmp(&t->src_ipv6, zaddr, sizeof(struct in6_addr))) {
+ t->mode = QED_FILTER_CONFIG_MODE_IP_DEST;
+ } else {
+ DP_INFO(edev, "Invalid N-tuple\n");
+ return -EOPNOTSUPP;
+ }
+
+ t->ip_comp = qede_flow_spec_ipv6_cmp;
+ t->build_hdr = qede_flow_build_ipv6_hdr;
+
+ return 0;
+}
+
static int qede_flow_spec_to_tuple_ipv4_common(struct qede_dev *edev,
struct qede_arfs_tuple *t,
struct ethtool_rx_flow_spec *fs)
@@ -1638,27 +1701,7 @@ static int qede_flow_spec_to_tuple_ipv4_common(struct qede_dev *edev,
t->src_port = fs->h_u.tcp_ip4_spec.psrc;
t->dst_port = fs->h_u.tcp_ip4_spec.pdst;
- /* We must either have a valid 4-tuple or only dst port
- * or only src ip as an input
- */
- if (t->src_port && t->dst_port && t->src_ipv4 && t->dst_ipv4) {
- t->mode = QED_FILTER_CONFIG_MODE_5_TUPLE;
- } else if (!t->src_port && t->dst_port &&
- !t->src_ipv4 && !t->dst_ipv4) {
- t->mode = QED_FILTER_CONFIG_MODE_L4_PORT;
- } else if (!t->src_port && !t->dst_port &&
- !t->dst_ipv4 && t->src_ipv4) {
- t->mode = QED_FILTER_CONFIG_MODE_IP_SRC;
- } else {
- DP_INFO(edev, "Invalid N-tuple\n");
- return -EOPNOTSUPP;
- }
-
- t->ip_comp = qede_flow_spec_ipv4_cmp;
- t->build_hdr = qede_flow_build_ipv4_hdr;
- t->stringify = qede_flow_stringify_ipv4_hdr;
-
- return 0;
+ return qede_set_v4_tuple_to_profile(edev, t);
}
static int qede_flow_spec_to_tuple_tcpv4(struct qede_dev *edev,
@@ -1690,10 +1733,8 @@ static int qede_flow_spec_to_tuple_ipv6_common(struct qede_dev *edev,
struct ethtool_rx_flow_spec *fs)
{
struct in6_addr zero_addr;
- void *p;
- p = &zero_addr;
- memset(p, 0, sizeof(zero_addr));
+ memset(&zero_addr, 0, sizeof(zero_addr));
if ((fs->h_u.tcp_ip6_spec.psrc &
fs->m_u.tcp_ip6_spec.psrc) != fs->h_u.tcp_ip6_spec.psrc) {
@@ -1720,30 +1761,7 @@ static int qede_flow_spec_to_tuple_ipv6_common(struct qede_dev *edev,
t->src_port = fs->h_u.tcp_ip6_spec.psrc;
t->dst_port = fs->h_u.tcp_ip6_spec.pdst;
- /* We must make sure we have a valid 4-tuple or only dest port
- * or only src ip as an input
- */
- if (t->src_port && t->dst_port &&
- memcmp(&t->src_ipv6, p, sizeof(struct in6_addr)) &&
- memcmp(&t->dst_ipv6, p, sizeof(struct in6_addr))) {
- t->mode = QED_FILTER_CONFIG_MODE_5_TUPLE;
- } else if (!t->src_port && t->dst_port &&
- !memcmp(&t->src_ipv6, p, sizeof(struct in6_addr)) &&
- !memcmp(&t->dst_ipv6, p, sizeof(struct in6_addr))) {
- t->mode = QED_FILTER_CONFIG_MODE_L4_PORT;
- } else if (!t->src_port && !t->dst_port &&
- !memcmp(&t->dst_ipv6, p, sizeof(struct in6_addr)) &&
- memcmp(&t->src_ipv6, p, sizeof(struct in6_addr))) {
- t->mode = QED_FILTER_CONFIG_MODE_IP_SRC;
- } else {
- DP_INFO(edev, "Invalid N-tuple\n");
- return -EOPNOTSUPP;
- }
-
- t->ip_comp = qede_flow_spec_ipv6_cmp;
- t->build_hdr = qede_flow_build_ipv6_hdr;
-
- return 0;
+ return qede_set_v6_tuple_to_profile(edev, t, &zero_addr);
}
static int qede_flow_spec_to_tuple_tcpv6(struct qede_dev *edev,
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next 1/3] qed/qede: Multi CoS support.
From: Manish Chopra @ 2018-08-09 18:13 UTC (permalink / raw)
To: davem; +Cc: netdev, ariel.elior, michal.kalderon
In-Reply-To: <20180809181351.32394-1-manish.chopra@cavium.com>
This patch adds support for tc mqprio offload,
using this different traffic classes on the adapter
can be utilized based on configured priority to tc map.
For example -
tc qdisc add dev eth0 root mqprio num_tc 4 map 0 1 2 3
This will cause SKBs with priority 0,1,2,3 to transmit
over tc 0,1,2,3 hardware queues respectively.
Signed-off-by: Manish Chopra <manish.chopra@cavium.com>
Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
---
drivers/net/ethernet/qlogic/qed/qed_l2.c | 9 +-
drivers/net/ethernet/qlogic/qed/qed_main.c | 5 +-
drivers/net/ethernet/qlogic/qede/qede.h | 13 +++
drivers/net/ethernet/qlogic/qede/qede_ethtool.c | 48 ++++++--
drivers/net/ethernet/qlogic/qede/qede_fp.c | 29 +++--
drivers/net/ethernet/qlogic/qede/qede_main.c | 139 +++++++++++++++++++-----
include/linux/qed/qed_eth_if.h | 6 +
7 files changed, 200 insertions(+), 49 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.c b/drivers/net/ethernet/qlogic/qed/qed_l2.c
index 5ede640..82a1bd1 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_l2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c
@@ -2188,16 +2188,17 @@ int qed_get_queue_coalesce(struct qed_hwfn *p_hwfn, u16 *p_coal, void *handle)
static int qed_fill_eth_dev_info(struct qed_dev *cdev,
struct qed_dev_eth_info *info)
{
+ struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
int i;
memset(info, 0, sizeof(*info));
- info->num_tc = 1;
-
if (IS_PF(cdev)) {
int max_vf_vlan_filters = 0;
int max_vf_mac_filters = 0;
+ info->num_tc = p_hwfn->hw_info.num_hw_tc;
+
if (cdev->int_params.out.int_mode == QED_INT_MODE_MSIX) {
u16 num_queues = 0;
@@ -2248,6 +2249,8 @@ static int qed_fill_eth_dev_info(struct qed_dev *cdev,
} else {
u16 total_cids = 0;
+ info->num_tc = 1;
+
/* Determine queues & XDP support */
for_each_hwfn(cdev, i) {
struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
@@ -2554,7 +2557,7 @@ static int qed_start_txq(struct qed_dev *cdev,
rc = qed_eth_tx_queue_start(p_hwfn,
p_hwfn->hw_info.opaque_fid,
- p_params, 0,
+ p_params, p_params->tc,
pbl_addr, pbl_size, ret_params);
if (rc) {
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index dbe8131..2094d86 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -948,13 +948,14 @@ static void qed_update_pf_params(struct qed_dev *cdev,
params->eth_pf_params.num_arfs_filters = 0;
/* In case we might support RDMA, don't allow qede to be greedy
- * with the L2 contexts. Allow for 64 queues [rx, tx, xdp] per hwfn.
+ * with the L2 contexts. Allow for 64 queues [rx, tx cos, xdp]
+ * per hwfn.
*/
if (QED_IS_RDMA_PERSONALITY(QED_LEADING_HWFN(cdev))) {
u16 *num_cons;
num_cons = ¶ms->eth_pf_params.num_cons;
- *num_cons = min_t(u16, *num_cons, 192);
+ *num_cons = min_t(u16, *num_cons, QED_MAX_L2_CONS);
}
for (i = 0; i < cdev->num_hwfns; i++) {
diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h
index d7ed0d3..e90c60a 100644
--- a/drivers/net/ethernet/qlogic/qede/qede.h
+++ b/drivers/net/ethernet/qlogic/qede/qede.h
@@ -386,6 +386,15 @@ struct qede_tx_queue {
#define QEDE_TXQ_XDP_TO_IDX(edev, txq) ((txq)->index - \
QEDE_MAX_TSS_CNT(edev))
#define QEDE_TXQ_IDX_TO_XDP(edev, idx) ((idx) + QEDE_MAX_TSS_CNT(edev))
+#define QEDE_NDEV_TXQ_ID_TO_FP_ID(edev, idx) ((edev)->fp_num_rx + \
+ ((idx) % QEDE_TSS_COUNT(edev)))
+#define QEDE_NDEV_TXQ_ID_TO_TXQ_COS(edev, idx) ((idx) / QEDE_TSS_COUNT(edev))
+#define QEDE_TXQ_TO_NDEV_TXQ_ID(edev, txq) ((QEDE_TSS_COUNT(edev) * \
+ (txq)->cos) + (txq)->index)
+#define QEDE_NDEV_TXQ_ID_TO_TXQ(edev, idx) \
+ (&((edev)->fp_array[QEDE_NDEV_TXQ_ID_TO_FP_ID(edev, idx)].txq \
+ [QEDE_NDEV_TXQ_ID_TO_TXQ_COS(edev, idx)]))
+#define QEDE_FP_TC0_TXQ(fp) (&((fp)->txq[0]))
/* Regular Tx requires skb + metadata for release purpose,
* while XDP requires the pages and the mapped address.
@@ -399,6 +408,8 @@ struct qede_tx_queue {
/* Slowpath; Should be kept in end [unless missing padding] */
void *handle;
+ u16 cos;
+ u16 ndev_txq_id;
};
#define BD_UNMAP_ADDR(bd) HILO_U64(le32_to_cpu((bd)->addr.hi), \
@@ -541,5 +552,7 @@ void qede_reload(struct qede_dev *edev,
#define QEDE_RX_HDR_SIZE 256
#define QEDE_MAX_JUMBO_PACKET_SIZE 9600
#define for_each_queue(i) for (i = 0; i < edev->num_queues; i++)
+#define for_each_cos_in_txq(edev, var) \
+ for ((var) = 0; (var) < (edev)->dev_info.num_tc; (var)++)
#endif /* _QEDE_H_ */
diff --git a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
index b37857f..2bd84d6 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
@@ -222,7 +222,7 @@ static void qede_get_strings_stats_txq(struct qede_dev *edev,
QEDE_TXQ_XDP_TO_IDX(edev, txq),
qede_tqstats_arr[i].string);
else
- sprintf(*buf, "%d: %s", txq->index,
+ sprintf(*buf, "%d_%d: %s", txq->index, txq->cos,
qede_tqstats_arr[i].string);
*buf += ETH_GSTRING_LEN;
}
@@ -262,8 +262,13 @@ static void qede_get_strings_stats(struct qede_dev *edev, u8 *buf)
if (fp->type & QEDE_FASTPATH_XDP)
qede_get_strings_stats_txq(edev, fp->xdp_tx, &buf);
- if (fp->type & QEDE_FASTPATH_TX)
- qede_get_strings_stats_txq(edev, fp->txq, &buf);
+ if (fp->type & QEDE_FASTPATH_TX) {
+ int cos;
+
+ for_each_cos_in_txq(edev, cos)
+ qede_get_strings_stats_txq(edev,
+ &fp->txq[cos], &buf);
+ }
}
/* Account for non-queue statistics */
@@ -338,8 +343,12 @@ static void qede_get_ethtool_stats(struct net_device *dev,
if (fp->type & QEDE_FASTPATH_XDP)
qede_get_ethtool_stats_txq(fp->xdp_tx, &buf);
- if (fp->type & QEDE_FASTPATH_TX)
- qede_get_ethtool_stats_txq(fp->txq, &buf);
+ if (fp->type & QEDE_FASTPATH_TX) {
+ int cos;
+
+ for_each_cos_in_txq(edev, cos)
+ qede_get_ethtool_stats_txq(&fp->txq[cos], &buf);
+ }
}
for (i = 0; i < QEDE_NUM_STATS; i++) {
@@ -366,7 +375,8 @@ static int qede_get_sset_count(struct net_device *dev, int stringset)
num_stats--;
/* Account for the Regular Tx statistics */
- num_stats += QEDE_TSS_COUNT(edev) * QEDE_NUM_TQSTATS;
+ num_stats += QEDE_TSS_COUNT(edev) * QEDE_NUM_TQSTATS *
+ edev->dev_info.num_tc;
/* Account for the Regular Rx statistics */
num_stats += QEDE_RSS_COUNT(edev) * QEDE_NUM_RQSTATS;
@@ -741,9 +751,17 @@ static int qede_get_coalesce(struct net_device *dev,
}
for_each_queue(i) {
+ struct qede_tx_queue *txq;
+
fp = &edev->fp_array[i];
+
+ /* All TX queues of given fastpath uses same
+ * coalescing value, so no need to iterate over
+ * all TCs, TC0 txq should suffice.
+ */
if (fp->type & QEDE_FASTPATH_TX) {
- tx_handle = fp->txq->handle;
+ txq = QEDE_FP_TC0_TXQ(fp);
+ tx_handle = txq->handle;
break;
}
}
@@ -801,9 +819,17 @@ static int qede_set_coalesce(struct net_device *dev,
}
if (edev->fp_array[i].type & QEDE_FASTPATH_TX) {
+ struct qede_tx_queue *txq;
+
+ /* All TX queues of given fastpath uses same
+ * coalescing value, so no need to iterate over
+ * all TCs, TC0 txq should suffice.
+ */
+ txq = QEDE_FP_TC0_TXQ(fp);
+
rc = edev->ops->common->set_coalesce(edev->cdev,
0, txc,
- fp->txq->handle);
+ txq->handle);
if (rc) {
DP_INFO(edev,
"Set TX coalesce error, rc = %d\n", rc);
@@ -1385,8 +1411,10 @@ static int qede_selftest_transmit_traffic(struct qede_dev *edev,
u16 val;
for_each_queue(i) {
- if (edev->fp_array[i].type & QEDE_FASTPATH_TX) {
- txq = edev->fp_array[i].txq;
+ struct qede_fastpath *fp = &edev->fp_array[i];
+
+ if (fp->type & QEDE_FASTPATH_TX) {
+ txq = QEDE_FP_TC0_TXQ(fp);
break;
}
}
diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c
index 8c9e95b..1a78027 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_fp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c
@@ -408,12 +408,12 @@ static void qede_xdp_tx_int(struct qede_dev *edev, struct qede_tx_queue *txq)
static int qede_tx_int(struct qede_dev *edev, struct qede_tx_queue *txq)
{
+ unsigned int pkts_compl = 0, bytes_compl = 0;
struct netdev_queue *netdev_txq;
u16 hw_bd_cons;
- unsigned int pkts_compl = 0, bytes_compl = 0;
int rc;
- netdev_txq = netdev_get_tx_queue(edev->ndev, txq->index);
+ netdev_txq = netdev_get_tx_queue(edev->ndev, txq->ndev_txq_id);
hw_bd_cons = le16_to_cpu(*txq->hw_cons_ptr);
barrier();
@@ -1365,9 +1365,14 @@ static bool qede_poll_is_more_work(struct qede_fastpath *fp)
if (qede_txq_has_work(fp->xdp_tx))
return true;
- if (likely(fp->type & QEDE_FASTPATH_TX))
- if (qede_txq_has_work(fp->txq))
- return true;
+ if (likely(fp->type & QEDE_FASTPATH_TX)) {
+ int cos;
+
+ for_each_cos_in_txq(fp->edev, cos) {
+ if (qede_txq_has_work(&fp->txq[cos]))
+ return true;
+ }
+ }
return false;
}
@@ -1382,8 +1387,14 @@ int qede_poll(struct napi_struct *napi, int budget)
struct qede_dev *edev = fp->edev;
int rx_work_done = 0;
- if (likely(fp->type & QEDE_FASTPATH_TX) && qede_txq_has_work(fp->txq))
- qede_tx_int(edev, fp->txq);
+ if (likely(fp->type & QEDE_FASTPATH_TX)) {
+ int cos;
+
+ for_each_cos_in_txq(fp->edev, cos) {
+ if (qede_txq_has_work(&fp->txq[cos]))
+ qede_tx_int(edev, &fp->txq[cos]);
+ }
+ }
if ((fp->type & QEDE_FASTPATH_XDP) && qede_txq_has_work(fp->xdp_tx))
qede_xdp_tx_int(edev, fp->xdp_tx);
@@ -1444,8 +1455,8 @@ netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev)
/* Get tx-queue context and netdev index */
txq_index = skb_get_queue_mapping(skb);
- WARN_ON(txq_index >= QEDE_TSS_COUNT(edev));
- txq = edev->fp_array[edev->fp_num_rx + txq_index].txq;
+ WARN_ON(txq_index >= QEDE_TSS_COUNT(edev) * edev->dev_info.num_tc);
+ txq = QEDE_NDEV_TXQ_ID_TO_TXQ(edev, txq_index);
netdev_txq = netdev_get_tx_queue(ndev, txq_index);
WARN_ON(qed_chain_get_elem_left(&txq->tx_pbl) < (MAX_SKB_FRAGS + 1));
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index 6a79604..d7299af 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -536,6 +536,43 @@ static int qede_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return 0;
}
+int qede_setup_tc(struct net_device *ndev, u8 num_tc)
+{
+ struct qede_dev *edev = netdev_priv(ndev);
+ int cos, count, offset;
+
+ if (num_tc > edev->dev_info.num_tc)
+ return -EINVAL;
+
+ netdev_reset_tc(ndev);
+ netdev_set_num_tc(ndev, num_tc);
+
+ for_each_cos_in_txq(edev, cos) {
+ count = QEDE_TSS_COUNT(edev);
+ offset = cos * QEDE_TSS_COUNT(edev);
+ netdev_set_tc_queue(ndev, cos, count, offset);
+ }
+
+ return 0;
+}
+
+static int
+qede_setup_tc_offload(struct net_device *dev, enum tc_setup_type type,
+ void *type_data)
+{
+ struct tc_mqprio_qopt *mqprio;
+
+ switch (type) {
+ case TC_SETUP_QDISC_MQPRIO:
+ mqprio = type_data;
+
+ mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+ return qede_setup_tc(dev, mqprio->num_tc);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static const struct net_device_ops qede_netdev_ops = {
.ndo_open = qede_open,
.ndo_stop = qede_close,
@@ -568,6 +605,7 @@ static int qede_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
#ifdef CONFIG_RFS_ACCEL
.ndo_rx_flow_steer = qede_rx_flow_steer,
#endif
+ .ndo_setup_tc = qede_setup_tc_offload,
};
static const struct net_device_ops qede_netdev_vf_ops = {
@@ -621,7 +659,8 @@ static struct qede_dev *qede_alloc_etherdev(struct qed_dev *cdev,
struct qede_dev *edev;
ndev = alloc_etherdev_mqs(sizeof(*edev),
- info->num_queues, info->num_queues);
+ info->num_queues * info->num_tc,
+ info->num_queues);
if (!ndev) {
pr_err("etherdev allocation failed\n");
return NULL;
@@ -830,7 +869,8 @@ static int qede_alloc_fp_array(struct qede_dev *edev)
}
if (fp->type & QEDE_FASTPATH_TX) {
- fp->txq = kzalloc(sizeof(*fp->txq), GFP_KERNEL);
+ fp->txq = kcalloc(edev->dev_info.num_tc,
+ sizeof(*fp->txq), GFP_KERNEL);
if (!fp->txq)
goto err;
}
@@ -879,10 +919,15 @@ static void qede_sp_task(struct work_struct *work)
static void qede_update_pf_params(struct qed_dev *cdev)
{
struct qed_pf_params pf_params;
+ u16 num_cons;
/* 64 rx + 64 tx + 64 XDP */
memset(&pf_params, 0, sizeof(struct qed_pf_params));
- pf_params.eth_pf_params.num_cons = (MAX_SB_PER_PF_MIMD - 1) * 3;
+
+ /* 1 rx + 1 xdp + max tx cos */
+ num_cons = QED_MIN_L2_CONS;
+
+ pf_params.eth_pf_params.num_cons = (MAX_SB_PER_PF_MIMD - 1) * num_cons;
/* Same for VFs - make sure they'll have sufficient connections
* to support XDP Tx queues.
@@ -1363,8 +1408,12 @@ static void qede_free_mem_fp(struct qede_dev *edev, struct qede_fastpath *fp)
if (fp->type & QEDE_FASTPATH_XDP)
qede_free_mem_txq(edev, fp->xdp_tx);
- if (fp->type & QEDE_FASTPATH_TX)
- qede_free_mem_txq(edev, fp->txq);
+ if (fp->type & QEDE_FASTPATH_TX) {
+ int cos;
+
+ for_each_cos_in_txq(edev, cos)
+ qede_free_mem_txq(edev, &fp->txq[cos]);
+ }
}
/* This function allocates all memory needed for a single fp (i.e. an entity
@@ -1391,9 +1440,13 @@ static int qede_alloc_mem_fp(struct qede_dev *edev, struct qede_fastpath *fp)
}
if (fp->type & QEDE_FASTPATH_TX) {
- rc = qede_alloc_mem_txq(edev, fp->txq);
- if (rc)
- goto out;
+ int cos;
+
+ for_each_cos_in_txq(edev, cos) {
+ rc = qede_alloc_mem_txq(edev, &fp->txq[cos]);
+ if (rc)
+ goto out;
+ }
}
out:
@@ -1466,10 +1519,23 @@ static void qede_init_fp(struct qede_dev *edev)
}
if (fp->type & QEDE_FASTPATH_TX) {
- fp->txq->index = txq_index++;
- if (edev->dev_info.is_legacy)
- fp->txq->is_legacy = 1;
- fp->txq->dev = &edev->pdev->dev;
+ int cos;
+
+ for_each_cos_in_txq(edev, cos) {
+ struct qede_tx_queue *txq = &fp->txq[cos];
+ u16 ndev_tx_id;
+
+ txq->cos = cos;
+ txq->index = txq_index;
+ ndev_tx_id = QEDE_TXQ_TO_NDEV_TXQ_ID(edev, txq);
+ txq->ndev_txq_id = ndev_tx_id;
+
+ if (edev->dev_info.is_legacy)
+ txq->is_legacy = 1;
+ txq->dev = &edev->pdev->dev;
+ }
+
+ txq_index++;
}
snprintf(fp->name, sizeof(fp->name), "%s-fp-%d",
@@ -1483,7 +1549,9 @@ static int qede_set_real_num_queues(struct qede_dev *edev)
{
int rc = 0;
- rc = netif_set_real_num_tx_queues(edev->ndev, QEDE_TSS_COUNT(edev));
+ rc = netif_set_real_num_tx_queues(edev->ndev,
+ QEDE_TSS_COUNT(edev) *
+ edev->dev_info.num_tc);
if (rc) {
DP_NOTICE(edev, "Failed to set real number of Tx queues\n");
return rc;
@@ -1685,9 +1753,13 @@ static int qede_stop_queues(struct qede_dev *edev)
fp = &edev->fp_array[i];
if (fp->type & QEDE_FASTPATH_TX) {
- rc = qede_drain_txq(edev, fp->txq, true);
- if (rc)
- return rc;
+ int cos;
+
+ for_each_cos_in_txq(edev, cos) {
+ rc = qede_drain_txq(edev, &fp->txq[cos], true);
+ if (rc)
+ return rc;
+ }
}
if (fp->type & QEDE_FASTPATH_XDP) {
@@ -1703,9 +1775,13 @@ static int qede_stop_queues(struct qede_dev *edev)
/* Stop the Tx Queue(s) */
if (fp->type & QEDE_FASTPATH_TX) {
- rc = qede_stop_txq(edev, fp->txq, i);
- if (rc)
- return rc;
+ int cos;
+
+ for_each_cos_in_txq(edev, cos) {
+ rc = qede_stop_txq(edev, &fp->txq[cos], i);
+ if (rc)
+ return rc;
+ }
}
/* Stop the Rx Queue */
@@ -1758,6 +1834,7 @@ static int qede_start_txq(struct qede_dev *edev,
params.p_sb = fp->sb_info;
params.sb_idx = sb_idx;
+ params.tc = txq->cos;
rc = edev->ops->q_tx_start(edev->cdev, rss_id, ¶ms, phys_table,
page_cnt, &ret_params);
@@ -1877,9 +1954,14 @@ static int qede_start_queues(struct qede_dev *edev, bool clear_stats)
}
if (fp->type & QEDE_FASTPATH_TX) {
- rc = qede_start_txq(edev, fp, fp->txq, i, TX_PI(0));
- if (rc)
- goto out;
+ int cos;
+
+ for_each_cos_in_txq(edev, cos) {
+ rc = qede_start_txq(edev, fp, &fp->txq[cos], i,
+ TX_PI(cos));
+ if (rc)
+ goto out;
+ }
}
}
@@ -1973,6 +2055,7 @@ static int qede_load(struct qede_dev *edev, enum qede_load_mode mode,
bool is_locked)
{
struct qed_link_params link_params;
+ u8 num_tc;
int rc;
DP_INFO(edev, "Starting qede load\n");
@@ -2019,6 +2102,10 @@ static int qede_load(struct qede_dev *edev, enum qede_load_mode mode,
goto err4;
DP_INFO(edev, "Start VPORT, RXQ and TXQ succeeded\n");
+ num_tc = netdev_get_num_tc(edev->ndev);
+ num_tc = num_tc ? num_tc : edev->dev_info.num_tc;
+ qede_setup_tc(edev->ndev, num_tc);
+
/* Program un-configured VLANs */
qede_configure_vlan_filters(edev);
@@ -2143,7 +2230,7 @@ static bool qede_is_txq_full(struct qede_dev *edev, struct qede_tx_queue *txq)
{
struct netdev_queue *netdev_txq;
- netdev_txq = netdev_get_tx_queue(edev->ndev, txq->index);
+ netdev_txq = netdev_get_tx_queue(edev->ndev, txq->ndev_txq_id);
if (netif_xmit_stopped(netdev_txq))
return true;
@@ -2208,9 +2295,11 @@ static void qede_get_eth_tlv_data(void *dev, void *data)
for_each_queue(i) {
fp = &edev->fp_array[i];
if (fp->type & QEDE_FASTPATH_TX) {
- if (fp->txq->sw_tx_cons != fp->txq->sw_tx_prod)
+ struct qede_tx_queue *txq = QEDE_FP_TC0_TXQ(fp);
+
+ if (txq->sw_tx_cons != txq->sw_tx_prod)
etlv->txqs_empty = false;
- if (qede_is_txq_full(edev, fp->txq))
+ if (qede_is_txq_full(edev, txq))
etlv->num_txqs_full++;
}
if (fp->type & QEDE_FASTPATH_RX) {
diff --git a/include/linux/qed/qed_eth_if.h b/include/linux/qed/qed_eth_if.h
index 2978fa4..a131048 100644
--- a/include/linux/qed/qed_eth_if.h
+++ b/include/linux/qed/qed_eth_if.h
@@ -39,6 +39,10 @@
#include <linux/qed/qed_if.h>
#include <linux/qed/qed_iov_if.h>
+/* 64 max queues * (1 rx + 4 tx-cos + 1 xdp) */
+#define QED_MIN_L2_CONS (2 + NUM_PHYS_TCS_4PORT_K2)
+#define QED_MAX_L2_CONS (64 * (QED_MIN_L2_CONS))
+
struct qed_queue_start_common_params {
/* Should always be relative to entity sending this. */
u8 vport_id;
@@ -49,6 +53,8 @@ struct qed_queue_start_common_params {
struct qed_sb_info *p_sb;
u8 sb_idx;
+
+ u8 tc;
};
struct qed_rxq_start_ret_params {
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next 0/3] qed*: Enhancements
From: Manish Chopra @ 2018-08-09 18:13 UTC (permalink / raw)
To: davem; +Cc: netdev, ariel.elior, michal.kalderon
Hi David,
This patch series adds following support in drivers -
1. Egress mqprio offload.
2. Add destination IP based flow profile.
3. Ingress flower offload (for drop action).
Please consider applying this series to "net-next".
Thanks,
Manish
Manish Chopra (3):
qed/qede: Multi CoS support.
qede: Add destination ip based flow profile.
qede: Ingress tc flower offload (drop action) support.
drivers/net/ethernet/qlogic/qed/qed_l2.c | 9 +-
drivers/net/ethernet/qlogic/qed/qed_main.c | 5 +-
drivers/net/ethernet/qlogic/qede/qede.h | 20 +-
drivers/net/ethernet/qlogic/qede/qede_ethtool.c | 50 ++-
drivers/net/ethernet/qlogic/qede/qede_filter.c | 422 ++++++++++++++++++++----
drivers/net/ethernet/qlogic/qede/qede_fp.c | 29 +-
drivers/net/ethernet/qlogic/qede/qede_main.c | 195 +++++++++--
include/linux/qed/qed_eth_if.h | 6 +
8 files changed, 628 insertions(+), 108 deletions(-)
--
1.8.3.1
^ permalink raw reply
* Re: [PATCH net-next 00/13] More complete PHYLINK support for mv88e6xxx
From: David Miller @ 2018-08-09 18:08 UTC (permalink / raw)
To: andrew; +Cc: netdev, rmk+kernel, f.fainelli, nikita.yoush, cphealy,
marek.behun
In-Reply-To: <1533821929-20071-1-git-send-email-andrew@lunn.ch>
From: Andrew Lunn <andrew@lunn.ch>
Date: Thu, 9 Aug 2018 15:38:36 +0200
> Previous patches added sufficient PHYLINK support to the mv88e6xxx
> that it did not break existing use cases, basically fixed-link phys.
>
> This patchset builds out the support so that SFP modules, up to
> 2.5Gbps can be supported, on mv88e6390X, on ports 9 and 10. It also
> provides a framework which can be extended to support SFPs on ports
> 2-8 of mv88e6390X, 10Gbps PHYs, and SFP support on the 6352 family.
>
> Russell King did much of the initial work, implementing the validate
> and mac_link_state calls. However, there is an important TODO in the
> commit message:
>
> needs to call phylink_mac_change() when the port link comes up/goes down.
>
> The remaining patches implement this, by adding more support for the
> SERDES interfaces, in particular, interrupt support so we get notified
> when the SERDES gains/looses sync.
>
> This has been tested on the ZII devel C, using a Clearfog as peer
> device.
Looks good to me, series applied, thanks!
^ permalink raw reply
* [PATCH ethtool v2 3/3] ethtool: Add support for action value -2 (wake-up filter)
From: Florian Fainelli @ 2018-08-09 18:04 UTC (permalink / raw)
To: netdev, linville; +Cc: davem, andrew, Florian Fainelli
In-Reply-To: <20180809180402.19430-1-f.fainelli@gmail.com>
Add the ability to program special filters using ethtool::rxnfc which
are meant to be used for wake-up purposes (in conjuction with
WAKE_FILTER) using the special action value: -2 (RX_CLS_FLOW_WAKE).
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
ethtool.8.in | 1 +
rxclass.c | 8 +++++---
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/ethtool.8.in b/ethtool.8.in
index 3eb9005ada48..97c7330fd373 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -871,6 +871,7 @@ Specifies the Rx queue to send packets to, or some other action.
nokeep;
lB l.
-1 Drop the matched flow
+-2 Use the matched flow as a Wake-on-LAN filter
0 or higher Rx queue to route the flow
.TE
.TP
diff --git a/rxclass.c b/rxclass.c
index 42d122d1ed86..79972651e706 100644
--- a/rxclass.c
+++ b/rxclass.c
@@ -251,7 +251,11 @@ static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp,
if (fsp->flow_type & FLOW_RSS)
fprintf(stdout, "\tRSS Context ID: %u\n", rss_context);
- if (fsp->ring_cookie != RX_CLS_FLOW_DISC) {
+ if (fsp->ring_cookie == RX_CLS_FLOW_DISC) {
+ fprintf(stdout, "\tAction: Drop\n");
+ } else if (fsp->ring_cookie == RX_CLS_FLOW_WAKE) {
+ fprintf(stdout, "\tAction: Wake-on-LAN\n");
+ } else {
u64 vf = ethtool_get_flow_spec_ring_vf(fsp->ring_cookie);
u64 queue = ethtool_get_flow_spec_ring(fsp->ring_cookie);
@@ -266,8 +270,6 @@ static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp,
else
fprintf(stdout, "\tAction: Direct to queue %llu\n",
queue);
- } else {
- fprintf(stdout, "\tAction: Drop\n");
}
fprintf(stdout, "\n");
--
2.17.1
^ permalink raw reply related
* [PATCH ethtool v2 2/3] ethtool: Add support for WAKE_FILTER (WoL using filters)
From: Florian Fainelli @ 2018-08-09 18:04 UTC (permalink / raw)
To: netdev, linville; +Cc: davem, andrew, Florian Fainelli
In-Reply-To: <20180809180402.19430-1-f.fainelli@gmail.com>
Add a new character 'f' which can be used to configure an Ethernet
controller to support Wake-on-LAN using filters programmed with the
ethtool::rxnfc and the special action -2 (wake-up filter). This is
useful in particular in the context of devices that must support wake-up
on more complex patterns such as multicast DNS packets.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
ethtool.8.in | 3 ++-
ethtool.c | 5 +++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/ethtool.8.in b/ethtool.8.in
index 0a366aa536ae..3eb9005ada48 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -58,7 +58,7 @@
.\"
.\" \(*WO - wol flags
.\"
-.ds WO \fBp\fP|\fBu\fP|\fBm\fP|\fBb\fP|\fBa\fP|\fBg\fP|\fBs\fP|\fBd\fP...
+.ds WO \fBp\fP|\fBu\fP|\fBm\fP|\fBb\fP|\fBa\fP|\fBg\fP|\fBs\fP|\fBf|\fBd\fP...
.\"
.\" \(*FL - flow type values
.\"
@@ -679,6 +679,7 @@ b Wake on broadcast messages
a Wake on ARP
g Wake on MagicPacket\[tm]
s Enable SecureOn\[tm] password for MagicPacket\[tm]
+f Wake on filter(s)
d T{
Disable (wake on nothing). This option clears all previous options.
T}
diff --git a/ethtool.c b/ethtool.c
index fb93ae898312..aa2bbe9e4c65 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -931,6 +931,9 @@ static int parse_wolopts(char *optstr, u32 *data)
case 's':
*data |= WAKE_MAGICSECURE;
break;
+ case 'f':
+ *data |= WAKE_FILTER;
+ break;
case 'd':
*data = 0;
break;
@@ -964,6 +967,8 @@ static char *unparse_wolopts(int wolopts)
*p++ = 'g';
if (wolopts & WAKE_MAGICSECURE)
*p++ = 's';
+ if (wolopts & WAKE_FILTER)
+ *p++ = 'f';
} else {
*p = 'd';
}
--
2.17.1
^ permalink raw reply related
* [PATCH ethtool v2 1/3] ethtool-copy.h: sync with net-next
From: Florian Fainelli @ 2018-08-09 18:04 UTC (permalink / raw)
To: netdev, linville; +Cc: davem, andrew, Florian Fainelli
In-Reply-To: <20180809180402.19430-1-f.fainelli@gmail.com>
This covers kernel changes up to commit 6cfef793b558:
ethtool: Add WAKE_FILTER and RX_CLS_FLOW_WAKE
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
ethtool-copy.h | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/ethtool-copy.h b/ethtool-copy.h
index 8cc61e9ab40b..6bfbb85f9402 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -215,12 +215,16 @@ struct ethtool_value {
__u32 data;
};
+#define PFC_STORM_PREVENTION_AUTO 0xffff
+#define PFC_STORM_PREVENTION_DISABLE 0
+
enum tunable_id {
ETHTOOL_ID_UNSPEC,
ETHTOOL_RX_COPYBREAK,
ETHTOOL_TX_COPYBREAK,
+ ETHTOOL_PFC_PREVENTION_TOUT, /* timeout in msecs */
/*
- * Add your fresh new tubale attribute above and remember to update
+ * Add your fresh new tunable attribute above and remember to update
* tunable_strings[] in net/core/ethtool.c
*/
__ETHTOOL_TUNABLE_COUNT,
@@ -864,7 +868,8 @@ struct ethtool_flow_ext {
* includes the %FLOW_EXT or %FLOW_MAC_EXT flag
* (see &struct ethtool_flow_ext description).
* @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC
- * if packets should be discarded
+ * if packets should be discarded, or %RX_CLS_FLOW_WAKE if the
+ * packets should be used for Wake-on-LAN with %WAKE_FILTER
* @location: Location of rule in the table. Locations must be
* numbered such that a flow matching multiple rules will be
* classified according to the first (lowest numbered) rule.
@@ -896,13 +901,13 @@ struct ethtool_rx_flow_spec {
static __inline__ __u64 ethtool_get_flow_spec_ring(__u64 ring_cookie)
{
return ETHTOOL_RX_FLOW_SPEC_RING & ring_cookie;
-};
+}
static __inline__ __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie)
{
return (ETHTOOL_RX_FLOW_SPEC_RING_VF & ring_cookie) >>
ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF;
-};
+}
/**
* struct ethtool_rxnfc - command to get or set RX flow classification rules
@@ -1628,6 +1633,7 @@ static __inline__ int ethtool_validate_duplex(__u8 duplex)
#define WAKE_ARP (1 << 4)
#define WAKE_MAGIC (1 << 5)
#define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */
+#define WAKE_FILTER (1 << 7)
/* L2-L4 network traffic flow types */
#define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */
@@ -1665,6 +1671,7 @@ static __inline__ int ethtool_validate_duplex(__u8 duplex)
#define RXH_DISCARD (1 << 31)
#define RX_CLS_FLOW_DISC 0xffffffffffffffffULL
+#define RX_CLS_FLOW_WAKE 0xfffffffffffffffeULL
/* Special RX classification rule insert location values */
#define RX_CLS_LOC_SPECIAL 0x80000000 /* flag */
--
2.17.1
^ permalink raw reply related
* [PATCH ethtool v2 0/3] ethtool: Wake-on-LAN using filters
From: Florian Fainelli @ 2018-08-09 18:03 UTC (permalink / raw)
To: netdev, linville; +Cc: davem, andrew, Florian Fainelli
Hi John,
This patch series syncs up ethtool-copy.h to get the new definitions
required for supporting wake-on-LAN using filters: WAKE_FILTER and
RX_CLS_FLOW_WAKE and then updates the rxclass.c code to allow us to
specify action -2 (RX_CLS_FLOW_WAKE).
Let me know if you would like this to be done differently.
Thanks!
Changes in v2:
- properly put the man page hunk describing action -2 into patch #3
Florian Fainelli (3):
ethtool-copy.h: sync with net-next
ethtool: Add support for WAKE_FILTER (WoL using filters)
ethtool: Add support for action value -2 (wake-up filter)
ethtool-copy.h | 15 +++++++++++----
ethtool.8.in | 4 +++-
ethtool.c | 5 +++++
rxclass.c | 8 +++++---
4 files changed, 24 insertions(+), 8 deletions(-)
--
2.17.1
^ permalink raw reply
* Re: [PATCH bpf] bpf: fix bpffs non-array map seq_show issue
From: Yonghong Song @ 2018-08-09 17:54 UTC (permalink / raw)
To: Daniel Borkmann, Alexei Starovoitov
Cc: ast, netdev, kernel-team, jakub.kicinski
In-Reply-To: <2adc84c4-2e92-db75-ba27-7e23eb9c95ad@iogearbox.net>
On 8/9/18 10:02 AM, Daniel Borkmann wrote:
> On 08/09/2018 06:55 PM, Yonghong Song wrote:
>> On 8/9/18 8:59 AM, Daniel Borkmann wrote:
>>> On 08/09/2018 05:15 PM, Yonghong Song wrote:
>>>> On 8/9/18 7:24 AM, Daniel Borkmann wrote:
>>>>> On 08/09/2018 05:55 AM, Yonghong Song wrote:
>>>>>> On 8/8/18 7:25 PM, Alexei Starovoitov wrote:
>>>>>>> On Wed, Aug 08, 2018 at 06:25:19PM -0700, Yonghong Song wrote:
>>>>>>>> In function map_seq_next() of kernel/bpf/inode.c,
>>>>>>>> the first key will be the "0" regardless of the map type.
>>>>>>>> This works for array. But for hash type, if it happens
>>>>>>>> key "0" is in the map, the bpffs map show will miss
>>>>>>>> some items if the key "0" is not the first element of
>>>>>>>> the first bucket.
>>>>>>>>
>>>>>>>> This patch fixed the issue by guaranteeing to get
>>>>>>>> the first element, if the seq_show is just started,
>>>>>>>> by passing NULL pointer key to map_get_next_key() callback.
>>>>>>>> This way, no missing elements will occur for
>>>>>>>> bpffs hash table show even if key "0" is in the map.
>>>>>>
>>>>>> Currently, map_seq_show_elem callback is only implemented
>>>>>> for arraymap. So the problem actually is not exposed.
>>>>>>
>>>>>> The issue is discovered when I tried to implement
>>>>>> map_seq_show_elem for hash maps, and I will have followup
>>>>>> patches for it.
>>>
>>> Btw, on that note, I would also prefer if we could decouple
>>> BTF from the map_seq_show_elem() as there is really no reason
>>> to have it on a per-map. I had a patch below which would enable
>>> it for all map types generically, and bpftool works out of the
>>> box for it. Also, array doesn't really have to be 'int' type
>>> enforced as long as it's some data structure with 4 bytes, it's
>>> all fine, so this can be made fully generic (we only eventually
>>> care about the match in size).
>>
>> I agree with a generic map_check_btf as mostly we only care about size
>> and this change should enable btftool btf based pretty print for hash/lru_hash tables.
>
> Yep, agree, the below output from bpftool is from test_xdp_noinline.o
> where both work with it.
>
>>> From 0a8be27cbc2ac0c6fc2632865b5afe37222a1fc7 Mon Sep 17 00:00:00 2001
>>> Message-Id: <0a8be27cbc2ac0c6fc2632865b5afe37222a1fc7.1533830053.git.daniel@iogearbox.net>
>>> From: Daniel Borkmann <daniel@iogearbox.net>
>>> Date: Thu, 9 Aug 2018 16:50:21 +0200
>>> Subject: [PATCH bpf-next] bpf, btf: enable for all maps
>>>
>>> # bpftool m dump id 19
>>> [{
>>> "key": {
>>> "": {
>>> "vip": 0,
>>> "vipv6": []
>>> },
>>> "port": 0,
>>> "family": 0,
>>> "proto": 0
>>> },
>>> "value": {
>>> "flags": 0,
>>> "vip_num": 0
>>> }
>>> }
>>> ]
>>>
>>> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
>>> ---
>>> include/linux/bpf.h | 4 +---
>>> kernel/bpf/arraymap.c | 27 ---------------------------
>>> kernel/bpf/inode.c | 3 ++-
>>> kernel/bpf/syscall.c | 24 ++++++++++++++++++++----
>>> 4 files changed, 23 insertions(+), 35 deletions(-)
>>>
>>> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
>>> index cd8790d..91aa4be 100644
>>> --- a/include/linux/bpf.h
>>> +++ b/include/linux/bpf.h
>>> @@ -48,8 +48,6 @@ struct bpf_map_ops {
>>> u32 (*map_fd_sys_lookup_elem)(void *ptr);
>>> void (*map_seq_show_elem)(struct bpf_map *map, void *key,
>>> struct seq_file *m);
>>> - int (*map_check_btf)(const struct bpf_map *map, const struct btf *btf,
>>> - u32 key_type_id, u32 value_type_id);
>>> };
>>>
>>> struct bpf_map {
>>> @@ -118,7 +116,7 @@ static inline bool bpf_map_offload_neutral(const struct bpf_map *map)
>>>
>>> static inline bool bpf_map_support_seq_show(const struct bpf_map *map)
>>> {
>>> - return map->ops->map_seq_show_elem && map->ops->map_check_btf;
>>> + return map->ops->map_seq_show_elem;
>>> }
>>>
>>> extern const struct bpf_map_ops bpf_map_offload_ops;
>>> diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
>>> index 2aa55d030..67f0bdf 100644
>>> --- a/kernel/bpf/arraymap.c
>>> +++ b/kernel/bpf/arraymap.c
>>> @@ -358,32 +358,6 @@ static void array_map_seq_show_elem(struct bpf_map *map, void *key,
>>> rcu_read_unlock();
>>> }
>>>
>>> -static int array_map_check_btf(const struct bpf_map *map, const struct btf *btf,
>>> - u32 btf_key_id, u32 btf_value_id)
>>> -{
>>> - const struct btf_type *key_type, *value_type;
>>> - u32 key_size, value_size;
>>> - u32 int_data;
>>> -
>>> - key_type = btf_type_id_size(btf, &btf_key_id, &key_size);
>>> - if (!key_type || BTF_INFO_KIND(key_type->info) != BTF_KIND_INT)
>>> - return -EINVAL;
>>> -
>>> - int_data = *(u32 *)(key_type + 1);
>>> - /* bpf array can only take a u32 key. This check makes
>>> - * sure that the btf matches the attr used during map_create.
>>> - */
>>> - if (BTF_INT_BITS(int_data) != 32 || key_size != 4 ||
>>> - BTF_INT_OFFSET(int_data))
>>> - return -EINVAL;
>>> -
>>> - value_type = btf_type_id_size(btf, &btf_value_id, &value_size);
>>> - if (!value_type || value_size != map->value_size)
>>> - return -EINVAL;
>>> -
>>> - return 0;
>>> -}
>>> -
>>> const struct bpf_map_ops array_map_ops = {
>>> .map_alloc_check = array_map_alloc_check,
>>> .map_alloc = array_map_alloc,
>>> @@ -394,7 +368,6 @@ const struct bpf_map_ops array_map_ops = {
>>> .map_delete_elem = array_map_delete_elem,
>>> .map_gen_lookup = array_map_gen_lookup,
>>> .map_seq_show_elem = array_map_seq_show_elem,
>>> - .map_check_btf = array_map_check_btf,
>>> };
>>>
>>> const struct bpf_map_ops percpu_array_map_ops = {
>>> diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
>>> index 76efe9a..400f27d 100644
>>> --- a/kernel/bpf/inode.c
>>> +++ b/kernel/bpf/inode.c
>>> @@ -332,7 +332,8 @@ static int bpf_mkmap(struct dentry *dentry, umode_t mode, void *arg)
>>> struct bpf_map *map = arg;
>>>
>>> return bpf_mkobj_ops(dentry, mode, arg, &bpf_map_iops,
>>> - map->btf ? &bpffs_map_fops : &bpffs_obj_fops);
>>> + bpf_map_support_seq_show(map) ?
>>> + &bpffs_map_fops : &bpffs_obj_fops);
>>
>> There are an issue here, the condition bpf_map_support_seq_show(map) may not be enough since the map specific implementation assumes availability of btf and proper map key/value btf_type_id's.
>> We can either use
>> map->btf && bpf_map_support_seq_show(map)
>> condition here, or check map->btf in each individual implementation
>> of map_support_seq_show().
>
> Good, point, agree. Will fix and cook proper patch later today.
Sounds good. i will wait until this gets merged and then resubmit.
> Thanks Yonghong!
>
>>> }
>>>
>>> static struct dentry *
>>> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
>>> index 5af4e9e..0b6f6e8 100644
>>> --- a/kernel/bpf/syscall.c
>>> +++ b/kernel/bpf/syscall.c
>>> @@ -455,6 +455,23 @@ static int bpf_obj_name_cpy(char *dst, const char *src)
>>> return 0;
>>> }
>>>
>>> +static int map_check_btf(const struct bpf_map *map, const struct btf *btf,
>>> + u32 btf_key_id, u32 btf_value_id)
>>> +{
>>> + const struct btf_type *key_type, *value_type;
>>> + u32 key_size, value_size;
>>> +
>>> + key_type = btf_type_id_size(btf, &btf_key_id, &key_size);
>>> + if (!key_type || key_size != map->key_size)
>>> + return -EINVAL;
>>> +
>>> + value_type = btf_type_id_size(btf, &btf_value_id, &value_size);
>>> + if (!value_type || value_size != map->value_size)
>>> + return -EINVAL;
>>> +
>>> + return 0;
>>> +}
>>> +
>>> #define BPF_MAP_CREATE_LAST_FIELD btf_value_type_id
>>> /* called via syscall */
>>> static int map_create(union bpf_attr *attr)
>>> @@ -489,8 +506,7 @@ static int map_create(union bpf_attr *attr)
>>> atomic_set(&map->refcnt, 1);
>>> atomic_set(&map->usercnt, 1);
>>>
>>> - if (bpf_map_support_seq_show(map) &&
>>> - (attr->btf_key_type_id || attr->btf_value_type_id)) {
>>> + if (attr->btf_key_type_id || attr->btf_value_type_id) {
>>> struct btf *btf;
>>>
>>> if (!attr->btf_key_type_id || !attr->btf_value_type_id) {
>>> @@ -504,8 +520,8 @@ static int map_create(union bpf_attr *attr)
>>> goto free_map_nouncharge;
>>> }
>>>
>>> - err = map->ops->map_check_btf(map, btf, attr->btf_key_type_id,
>>> - attr->btf_value_type_id);
>>> + err = map_check_btf(map, btf, attr->btf_key_type_id,
>>> + attr->btf_value_type_id);
>>> if (err) {
>>> btf_put(btf);
>>> goto free_map_nouncharge;
>>>
>
^ permalink raw reply
* Re: [PATCH 1/3] net:svc_rdma_transport: remove unneeded variable 'ret' in rdma_listen_handler
From: J. Bruce Fields @ 2018-08-09 20:06 UTC (permalink / raw)
To: Anna Schumaker; +Cc: zhong jiang, davem, netdev, linux-kernel
In-Reply-To: <2c343d78-e668-1b97-a4e6-228296da0d70@Netapp.com>
On Tue, Aug 07, 2018 at 10:49:11AM -0400, Anna Schumaker wrote:
> (Adding Bruce since he takes nfs / sunrpc server patches)
Applied, thanks.--b.
>
> On 08/07/2018 07:20 AM, zhong jiang wrote:
> > The ret is not modified after initalization, So just remove the variable
> > and return 0.
> >
> > Signed-off-by: zhong jiang <zhongjiang@huawei.com>
> > ---
> > net/sunrpc/xprtrdma/svc_rdma_transport.c | 3 +--
> > 1 file changed, 1 insertion(+), 2 deletions(-)
> >
> > diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
> > index 547b2cd..2848caf 100644
> > --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
> > +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
> > @@ -296,7 +296,6 @@ static int rdma_listen_handler(struct rdma_cm_id *cma_id,
> > struct rdma_cm_event *event)
> > {
> > struct sockaddr *sap = (struct sockaddr *)&cma_id->route.addr.src_addr;
> > - int ret = 0;
> >
> > trace_svcrdma_cm_event(event, sap);
> >
> > @@ -315,7 +314,7 @@ static int rdma_listen_handler(struct rdma_cm_id *cma_id,
> > break;
> > }
> >
> > - return ret;
> > + return 0;
> > }
> >
> > static int rdma_cma_handler(struct rdma_cm_id *cma_id,
> >
^ permalink raw reply
* Re: [PATCH net-next 0/7] mlxsw: Various updates
From: David Miller @ 2018-08-09 17:37 UTC (permalink / raw)
To: idosch; +Cc: netdev, jiri, mlxsw
In-Reply-To: <20180809085913.20671-1-idosch@mellanox.com>
From: Ido Schimmel <idosch@mellanox.com>
Date: Thu, 9 Aug 2018 11:59:06 +0300
> Patches 1-3 update the driver to use a new firmware version. Due to a
> recently discovered issue, the version (and future ones) does not
> support matching on VLAN ID at egress. This is enforced in the driver
> and reported back to the user via extack.
>
> Patch 4 adds a new selftest for the recently introduced algorithmic
> TCAM.
>
> Patch 5 converts the driver to use SPDX identifiers.
>
> Patches 6-7 fix a bug in ethtool stats reporting and expose counters for
> all 16 TCs, following recent MC-aware changes that utilize TCs 8-15.
Series applied, thanks!
^ permalink raw reply
* Re: kernel BUG at net/ipv4/ip_output.c:LINE!
From: syzbot @ 2018-08-09 20:02 UTC (permalink / raw)
To: davem, kuznet, linux-kernel, netdev, syzkaller-bugs, yoshfuji
In-Reply-To: <000000000000f68d660570dcddd8@google.com>
syzbot has found a reproducer for the following crash on:
HEAD commit: 112cbae26d18 Merge branch 'linus' of git://git.kernel.org/..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=1192ae72400000
kernel config: https://syzkaller.appspot.com/x/.config?x=152cb8ccd35b1f70
dashboard link: https://syzkaller.appspot.com/bug?extid=90d5ec0c05e708f3b66d
compiler: gcc (GCC) 8.0.1 20180413 (experimental)
syzkaller repro:https://syzkaller.appspot.com/x/repro.syz?x=153ed6e2400000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=1539038c400000
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+90d5ec0c05e708f3b66d@syzkaller.appspotmail.com
IPv6: ADDRCONF(NETDEV_UP): veth0: link is not ready
IPv6: ADDRCONF(NETDEV_CHANGE): veth0: link becomes ready
IPv6: ADDRCONF(NETDEV_CHANGE): bond0: link becomes ready
8021q: adding VLAN 0 to HW filter on device team0
------------[ cut here ]------------
kernel BUG at net/ipv4/ip_output.c:775!
invalid opcode: 0000 [#1] SMP KASAN
CPU: 1 PID: 4713 Comm: syz-executor450 Not tainted 4.18.0-rc8+ #182
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
RIP: 0010:ip_do_fragment+0x2436/0x2aa0 net/ipv4/ip_output.c:775
Code: 8b 8d 70 fe ff ff e9 99 e8 ff ff 4c 89 ef e8 a1 65 40 fc e9 7b e9 ff
ff 4c 89 f7 e8 94 65 40 fc e9 f3 e5 ff ff e8 7a 89 02 fc <0f> 0b 4c 89 e7
e8 80 65 40 fc e9 b7 e8 ff ff 4c 89 f7 89 8d 70 fe
RSP: 0018:ffff8801cfe3e880 EFLAGS: 00010293
RAX: ffff8801af542080 RBX: ffff8801c88eaa00 RCX: ffffffff85797886
RDX: 0000000000000000 RSI: ffffffff85798ed6 RDI: 0000000000000005
RBP: ffff8801cfe3ea58 R08: ffff8801af542080 R09: ffffed0039110032
R10: ffffed0039110034 R11: ffff8801c88801a3 R12: ffff8801c88eaac4
R13: 00000000fffffff2 R14: ffff8801c88eaad0 R15: dffffc0000000000
FS: 0000000001479880(0000) GS:ffff8801db100000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffffffff600400 CR3: 00000001cf669000 CR4: 00000000001406e0
Call Trace:
ip_fragment.constprop.49+0x179/0x240 net/ipv4/ip_output.c:548
ip_finish_output+0x6e4/0xfa0 net/ipv4/ip_output.c:315
NF_HOOK_COND include/linux/netfilter.h:276 [inline]
ip_output+0x223/0x880 net/ipv4/ip_output.c:405
dst_output include/net/dst.h:444 [inline]
ip_local_out+0xc5/0x1b0 net/ipv4/ip_output.c:124
iptunnel_xmit+0x53b/0x800 net/ipv4/ip_tunnel_core.c:91
ip_tunnel_xmit+0x1598/0x3af1 net/ipv4/ip_tunnel.c:778
__gre_xmit+0x5b7/0x950 net/ipv4/ip_gre.c:449
ipgre_xmit+0x3e8/0xb50 net/ipv4/ip_gre.c:701
__netdev_start_xmit include/linux/netdevice.h:4148 [inline]
netdev_start_xmit include/linux/netdevice.h:4157 [inline]
xmit_one net/core/dev.c:3034 [inline]
dev_hard_start_xmit+0x26c/0xc30 net/core/dev.c:3050
__dev_queue_xmit+0x29c2/0x38e0 net/core/dev.c:3569
dev_queue_xmit+0x17/0x20 net/core/dev.c:3602
__bpf_tx_skb net/core/filter.c:1995 [inline]
__bpf_redirect_common net/core/filter.c:2033 [inline]
__bpf_redirect+0x563/0xa80 net/core/filter.c:2040
____bpf_clone_redirect net/core/filter.c:2073 [inline]
bpf_clone_redirect+0x2f6/0x490 net/core/filter.c:2045
bpf_prog_bebbfe2050753572+0xef4/0x1000
Modules linked in:
Dumping ftrace buffer:
(ftrace buffer empty)
---[ end trace b3cbe48b5e178b8d ]---
RIP: 0010:ip_do_fragment+0x2436/0x2aa0 net/ipv4/ip_output.c:775
Code: 8b 8d 70 fe ff ff e9 99 e8 ff ff 4c 89 ef e8 a1 65 40 fc e9 7b e9 ff
ff 4c 89 f7 e8 94 65 40 fc e9 f3 e5 ff ff e8 7a 89 02 fc <0f> 0b 4c 89 e7
e8 80 65 40 fc e9 b7 e8 ff ff 4c 89 f7 89 8d 70 fe
RSP: 0018:ffff8801cfe3e880 EFLAGS: 00010293
RAX: ffff8801af542080 RBX: ffff8801c88eaa00 RCX: ffffffff85797886
RDX: 0000000000000000 RSI: ffffffff85798ed6 RDI: 0000000000000005
RBP: ffff8801cfe3ea58 R08: ffff8801af542080 R09: ffffed0039110032
R10: ffffed0039110034 R11: ffff8801c88801a3 R12: ffff8801c88eaac4
R13: 00000000fffffff2 R14: ffff8801c88eaad0 R15: dffffc0000000000
FS: 0000000001479880(0000) GS:ffff8801db100000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffffffff600400 CR3: 00000001cf669000 CR4: 00000000001406e0
^ 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