* [PATCHv2 2/2] drivers: net: davinci_mdio: print bus frequency
From: Max Uvarov @ 2017-08-10 7:47 UTC (permalink / raw)
To: netdev; +Cc: linux-omap, grygorii.strashko, Max Uvarov
In-Reply-To: <1502351267-23841-1-git-send-email-muvarov@gmail.com>
Frequency can be adjusted in DT it make sense to
print current used value on driver init.
Signed-off-by: Max Uvarov <muvarov@gmail.com>
---
drivers/net/ethernet/ti/davinci_mdio.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index 611e7cc..3c33f45 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -159,8 +159,10 @@ static int davinci_mdio_reset(struct mii_bus *bus)
/* dump hardware version info */
ver = __raw_readl(&data->regs->version);
- dev_info(data->dev, "davinci mdio revision %d.%d\n",
- (ver >> 8) & 0xff, ver & 0xff);
+ dev_info(data->dev,
+ "davinci mdio revision %d.%d, bus freq %ld\n",
+ (ver >> 8) & 0xff, ver & 0xff,
+ data->pdata.bus_freq);
if (data->skip_scan)
goto done;
--
2.5.0
^ permalink raw reply related
* [PATCHv2 1/2] drivers: net: davinci_mdio: remove busy loop on wait user access
From: Max Uvarov @ 2017-08-10 7:47 UTC (permalink / raw)
To: netdev; +Cc: linux-omap, grygorii.strashko, Max Uvarov
Polling 14 mdio devices on single mdio bus eats 30% of 1Ghz cpu time
due to busy loop in wait(). Add small delay to relax cpu.
Signed-off-by: Max Uvarov <muvarov@gmail.com>
---
v2: fix spelling in commit description.
drivers/net/ethernet/ti/davinci_mdio.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index 33df340..611e7cc 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -198,8 +198,10 @@ static inline int wait_for_user_access(struct davinci_mdio_data *data)
return 0;
reg = __raw_readl(®s->control);
- if ((reg & CONTROL_IDLE) == 0)
+ if ((reg & CONTROL_IDLE) == 0) {
+ usleep_range(100, 200);
continue;
+ }
/*
* An emac soft_reset may have clobbered the mdio controller's
--
2.5.0
^ permalink raw reply related
* [PATCH 2/2] drivers: net: davinci_mdio: print bus frequency
From: Max Uvarov @ 2017-08-10 7:42 UTC (permalink / raw)
To: netdev; +Cc: linux-omap, grygorii.strashko, Max Uvarov
In-Reply-To: <1502350920-22750-1-git-send-email-muvarov@gmail.com>
Frequency can be audjusted in DT it make sense to
print current used value on driver init.
Signed-off-by: Max Uvarov <muvarov@gmail.com>
---
drivers/net/ethernet/ti/davinci_mdio.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index 611e7cc..3c33f45 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -159,8 +159,10 @@ static int davinci_mdio_reset(struct mii_bus *bus)
/* dump hardware version info */
ver = __raw_readl(&data->regs->version);
- dev_info(data->dev, "davinci mdio revision %d.%d\n",
- (ver >> 8) & 0xff, ver & 0xff);
+ dev_info(data->dev,
+ "davinci mdio revision %d.%d, bus freq %ld\n",
+ (ver >> 8) & 0xff, ver & 0xff,
+ data->pdata.bus_freq);
if (data->skip_scan)
goto done;
--
2.5.0
^ permalink raw reply related
* [PATCH 1/2] drivers: net: davinci_mdio: remove busy loop on wait user access
From: Max Uvarov @ 2017-08-10 7:41 UTC (permalink / raw)
To: netdev; +Cc: linux-omap, grygorii.strashko, Max Uvarov
Polling 14 mdio devices on single mdio bus eats 30% of 1Ghz cpu time
due to busy loop in waiti(). Aadd small delay to relax cpu.
Signed-off-by: Max Uvarov <muvarov@gmail.com>
---
drivers/net/ethernet/ti/davinci_mdio.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index 33df340..611e7cc 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -198,8 +198,10 @@ static inline int wait_for_user_access(struct davinci_mdio_data *data)
return 0;
reg = __raw_readl(®s->control);
- if ((reg & CONTROL_IDLE) == 0)
+ if ((reg & CONTROL_IDLE) == 0) {
+ usleep_range(100, 200);
continue;
+ }
/*
* An emac soft_reset may have clobbered the mdio controller's
--
2.5.0
^ permalink raw reply related
* Re: [PATCH] hv_set_ifconfig.sh double check before setting ip
From: Eduardo Otubo @ 2017-08-10 7:40 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-kernel, devel, sthemmin, haiyangz, kys
In-Reply-To: <494db0c8-8c31-f2ce-17fc-7b96b74f0b28@redhat.com>
On 08/09/2017 11:02 AM, Eduardo Otubo wrote:
> On 08/09/2017 06:11 AM, David Miller wrote:
>> From: Eduardo Otubo <otubo@redhat.com>
>> Date: Tue, 8 Aug 2017 15:53:45 +0200
>>
>>> This patch fixes the behavior of the hv_set_ifconfig script when setting
>>> the interface ip. Sometimes the interface has already been configured by
>>> network daemon, in this case hv_set_ifconfig causes "RTNETLINK: file
>>> exists error"; in order to avoid this error this patch makes sure double
>>> checks the interface before trying anything.
>>>
>>> Signed-off-by: Eduardo Otubo <otubo@redhat.com>
>>
>> And if the daemon sets the address after you test it but before
>> you try to set it in the script, what happens?
>>
>> This is why I hate changes like this. They don't remove the problem,
>> they make it smaller. And smaller in a bad way. Smaller makes the
>> problem even more harder to diagnose when it happens.
>>
>> There is implicitly no synchonization between network configuration
>> daemons and things people run by hand like this script.
>>
>> So, caveat emptor.
>>
>> I'm not applying this, sorry.
But also, looking from a different point of view, the current upstream
solution does not avoid the problems you mentioned. My fix at least
avoids double configuration and RTNETLINK errors. So perhaps you could
consider this as "a better version walking towards an ideal fix"?
>>
>
> This is just part of the resolution, actually. For RHEL I also configure
> hyperv-daemons' systemd config file to be run only after network service
> is up.
>
> So perhaps my solution should be distro-agnostic and only involve this
> script as part of it? In this case I'll elaborate a little more then.
>
> Thanks for the comment.
^ permalink raw reply
* Re: [PATCH 0/4] net-next: dsa: fix flow dissection
From: John Crispin @ 2017-08-10 7:40 UTC (permalink / raw)
To: Eric Dumazet, David Miller
Cc: andrew, f.fainelli, muciri, vivien.didelot, netdev, sean.wang,
linux-kernel, shashidhar.lakkavalli, linux-mediatek
In-Reply-To: <1502347335.4936.2.camel@edumazet-glaptop3.roam.corp.google.com>
On 10/08/17 08:42, Eric Dumazet wrote:
> On Wed, 2017-08-09 at 22:52 -0700, David Miller wrote:
>> From: John Crispin <john@phrozen.org>
>> Date: Wed, 9 Aug 2017 14:41:15 +0200
>>
>>> RPS and probably other kernel features are currently broken on some if not
>>> all DSA devices. The root cause of this is that skb_hash will call the
>>> flow_dissector. At this point the skb still contains the magic switch
>>> header and the skb->protocol field is not set up to the correct 802.3
>>> value yet. By the time the tag specific code is called, removing the header
>>> and properly setting the protocol an invalid hash is already set. In the
>>> case of the mt7530 this will result in all flows always having the same
>>> hash.
>>>
>>> Changes since RFC:
>>> * use a callback instead of static values
>>> * add cover letter
>> Series applied, thanks.
> Is this related ?
>
> net/core/flow_dissector.c: In function '__skb_flow_dissect':
> net/core/flow_dissector.c:448:18: error: 'struct net_device' has no member named 'dsa_ptr'
> ops = skb->dev->dsa_ptr->tag_ops;
> ^
> make[3]: *** [net/core/flow_dissector.o] Error 1
>
>
looks like it, I did test the patches against net-next from 24 hours
ago, let me do a test build just now.
John
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* [PATCH v2] net: stmmac: Use the right logging function in stmmac_mdio_register
From: Romain Perier @ 2017-08-10 7:38 UTC (permalink / raw)
To: Giuseppe Cavallaro, Alexandre Torgue
Cc: Andrew Lunn, netdev, linux-kernel, Romain Perier
Currently, the function stmmac_mdio_register() is only used by
stmmac_dvr_probe() from stmmac_main.c, in order to register the MDIO bus
and probe information about the PHY. As this function is called before
calling register_netdev(), all messages logged from stmmac_mdio_register
are prefixed by "(unnamed net_device)". The goal of netdev_info or
netdev_err is to dump useful infos about a net_device, when this data
structure is partially initialized, there is no point for using these
functions.
This commit fixes the issue by replacing all netdev_*() by the
corresponding dev_*() function for logging. The last netdev_info is
replaced by phy_attached_info(), as a valid phydev can be used at this
point.
Signed-off-by: Romain Perier <romain.perier@collabora.com>
---
Changes in v2:
- Replaced dev_info() by phy_attached_print()
- Simplified message because informations were redudant
- Updated commit message
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index db157a47000c..e0fbf8657103 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -204,6 +204,7 @@ int stmmac_mdio_register(struct net_device *ndev)
struct stmmac_priv *priv = netdev_priv(ndev);
struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
struct device_node *mdio_node = priv->plat->mdio_node;
+ struct device *dev = ndev->dev.parent;
int addr, found;
if (!mdio_bus_data)
@@ -237,7 +238,7 @@ int stmmac_mdio_register(struct net_device *ndev)
else
err = mdiobus_register(new_bus);
if (err != 0) {
- netdev_err(ndev, "Cannot register the MDIO bus\n");
+ dev_err(dev, "Cannot register the MDIO bus\n");
goto bus_register_fail;
}
@@ -285,14 +286,14 @@ int stmmac_mdio_register(struct net_device *ndev)
irq_str = irq_num;
break;
}
- netdev_info(ndev, "PHY ID %08x at %d IRQ %s (%s)%s\n",
- phydev->phy_id, addr, irq_str, phydev_name(phydev),
- act ? " active" : "");
+ phy_attached_print(phydev, "PHY ID %08x IRQ %s %s\n",
+ phydev->phy_id, irq_str,
+ act ? " active" : "");
found = 1;
}
if (!found && !mdio_node) {
- netdev_warn(ndev, "No PHY found\n");
+ dev_warn(dev, "No PHY found\n");
mdiobus_unregister(new_bus);
mdiobus_free(new_bus);
return -ENODEV;
--
2.11.0
^ permalink raw reply related
* RE: [PATCH net-next] skbuff: Add BUG_ON in skb_init.
From: Yuan, Linyu (NSB - CN/Shanghai) @ 2017-08-10 6:41 UTC (permalink / raw)
To: Tonghao Zhang, David Miller; +Cc: Linux Kernel Network Developers
In-Reply-To: <CAMDZJNVFP=1f1r4fQN=dnQ4Ve8+VzGfY7cHUe6Vv8tsECUmraw@mail.gmail.com>
Original this function have return value but not used, and check allocate result internal,
When I change this function to void return, I add this BUG_ON.
> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org]
> On Behalf Of Tonghao Zhang
> Sent: Thursday, August 10, 2017 2:10 PM
> To: David Miller
> Cc: Linux Kernel Network Developers
> Subject: Re: [PATCH net-next] skbuff: Add BUG_ON in skb_init.
>
> Thanks a lot. I found it when reviewing this codes. and BUG_ON is
> added in the init_inodecache(). We may remove it or not ?
>
> diff --git a/net/socket.c b/net/socket.c
> index b332d1e..ebee3ee 100644
> --- a/net/socket.c
> +++ b/net/socket.c
> @@ -296,7 +296,6 @@ static void init_inodecache(void)
>
> SLAB_RECLAIM_ACCOUNT |
> SLAB_MEM_SPREAD
> | SLAB_ACCOUNT),
> init_once);
> - BUG_ON(sock_inode_cachep == NULL);
> }
>
> static const struct super_operations sockfs_ops = {
>
> On Thu, Aug 10, 2017 at 1:49 PM, David Miller <davem@davemloft.net>
> wrote:
> > From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> > Date: Wed, 9 Aug 2017 05:04:38 -0700
> >
> >> When initializing the skbuff SLAB cache, we should make
> >> sure it is successful. Adding BUG_ON to check it and
> >> init_inodecache() is in the same case.
> >>
> >> Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> >> ---
> >> net/core/skbuff.c | 2 ++
> >> 1 file changed, 2 insertions(+)
> >>
> >> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> >> index 42b62c716a33..9513de519870 100644
> >> --- a/net/core/skbuff.c
> >> +++ b/net/core/skbuff.c
> >> @@ -3904,6 +3904,8 @@ void __init skb_init(void)
> >> 0,
> >>
> SLAB_HWCACHE_ALIGN|SLAB_PANIC,
> >> NULL);
> >> + BUG_ON(skbuff_head_cache == NULL);
> >> + BUG_ON(skbuff_fclone_cache == NULL);
> >> }
> >
> > I know you guys want every allocation to be explicitly checked so that
> > everything is consistent for static code analysis checkers.
> >
> > But this is just wasted code.
> >
> > The first allocation will take a NULL dereference and the backtrace
> > will make it completely clear which SLAB cache was NULL and couldn't
> > be allocated.
> >
> > So there is no real value to adding these checks.
> >
> > So I'm not applying this, sorry.
> >
> > The same logic goes for your other patch of this nature.
> >
^ permalink raw reply
* [net-next:master 905/906] net/core/flow_dissector.c:448:18: error: 'struct net_device' has no member named 'dsa_ptr'; did you mean 'dn_ptr'?
From: kbuild test robot @ 2017-08-10 6:46 UTC (permalink / raw)
To: John Crispin
Cc: kbuild-all, netdev, Muciri Gatimu, Shashidhar Lakkavalli,
Andrew Lunn
[-- Attachment #1: Type: text/plain, Size: 14184 bytes --]
tree: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git master
head: 7e1ecbcf79b2fdc7349da1bb90d6dadad1f9ac89
commit: 43e665287f931a167cd2eea3387efda901bff0ce [905/906] net-next: dsa: fix flow dissection
config: x86_64-acpi-redef (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
git checkout 43e665287f931a167cd2eea3387efda901bff0ce
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
net/core/flow_dissector.c: In function '__skb_flow_dissect':
>> net/core/flow_dissector.c:448:18: error: 'struct net_device' has no member named 'dsa_ptr'; did you mean 'dn_ptr'?
ops = skb->dev->dsa_ptr->tag_ops;
^~
vim +448 net/core/flow_dissector.c
404
405 /**
406 * __skb_flow_dissect - extract the flow_keys struct and return it
407 * @skb: sk_buff to extract the flow from, can be NULL if the rest are specified
408 * @flow_dissector: list of keys to dissect
409 * @target_container: target structure to put dissected values into
410 * @data: raw buffer pointer to the packet, if NULL use skb->data
411 * @proto: protocol for which to get the flow, if @data is NULL use skb->protocol
412 * @nhoff: network header offset, if @data is NULL use skb_network_offset(skb)
413 * @hlen: packet header length, if @data is NULL use skb_headlen(skb)
414 *
415 * The function will try to retrieve individual keys into target specified
416 * by flow_dissector from either the skbuff or a raw buffer specified by the
417 * rest parameters.
418 *
419 * Caller must take care of zeroing target container memory.
420 */
421 bool __skb_flow_dissect(const struct sk_buff *skb,
422 struct flow_dissector *flow_dissector,
423 void *target_container,
424 void *data, __be16 proto, int nhoff, int hlen,
425 unsigned int flags)
426 {
427 struct flow_dissector_key_control *key_control;
428 struct flow_dissector_key_basic *key_basic;
429 struct flow_dissector_key_addrs *key_addrs;
430 struct flow_dissector_key_ports *key_ports;
431 struct flow_dissector_key_icmp *key_icmp;
432 struct flow_dissector_key_tags *key_tags;
433 struct flow_dissector_key_vlan *key_vlan;
434 bool skip_vlan = false;
435 u8 ip_proto = 0;
436 bool ret;
437
438 if (!data) {
439 data = skb->data;
440 proto = skb_vlan_tag_present(skb) ?
441 skb->vlan_proto : skb->protocol;
442 nhoff = skb_network_offset(skb);
443 hlen = skb_headlen(skb);
444 if (unlikely(netdev_uses_dsa(skb->dev))) {
445 const struct dsa_device_ops *ops;
446 int offset;
447
> 448 ops = skb->dev->dsa_ptr->tag_ops;
449 if (ops->flow_dissect &&
450 !ops->flow_dissect(skb, &proto, &offset)) {
451 hlen -= offset;
452 nhoff += offset;
453 }
454 }
455 }
456
457 /* It is ensured by skb_flow_dissector_init() that control key will
458 * be always present.
459 */
460 key_control = skb_flow_dissector_target(flow_dissector,
461 FLOW_DISSECTOR_KEY_CONTROL,
462 target_container);
463
464 /* It is ensured by skb_flow_dissector_init() that basic key will
465 * be always present.
466 */
467 key_basic = skb_flow_dissector_target(flow_dissector,
468 FLOW_DISSECTOR_KEY_BASIC,
469 target_container);
470
471 if (dissector_uses_key(flow_dissector,
472 FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
473 struct ethhdr *eth = eth_hdr(skb);
474 struct flow_dissector_key_eth_addrs *key_eth_addrs;
475
476 key_eth_addrs = skb_flow_dissector_target(flow_dissector,
477 FLOW_DISSECTOR_KEY_ETH_ADDRS,
478 target_container);
479 memcpy(key_eth_addrs, ð->h_dest, sizeof(*key_eth_addrs));
480 }
481
482 proto_again:
483 switch (proto) {
484 case htons(ETH_P_IP): {
485 const struct iphdr *iph;
486 struct iphdr _iph;
487 ip:
488 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
489 if (!iph || iph->ihl < 5)
490 goto out_bad;
491 nhoff += iph->ihl * 4;
492
493 ip_proto = iph->protocol;
494
495 if (dissector_uses_key(flow_dissector,
496 FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
497 key_addrs = skb_flow_dissector_target(flow_dissector,
498 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
499 target_container);
500
501 memcpy(&key_addrs->v4addrs, &iph->saddr,
502 sizeof(key_addrs->v4addrs));
503 key_control->addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
504 }
505
506 if (ip_is_fragment(iph)) {
507 key_control->flags |= FLOW_DIS_IS_FRAGMENT;
508
509 if (iph->frag_off & htons(IP_OFFSET)) {
510 goto out_good;
511 } else {
512 key_control->flags |= FLOW_DIS_FIRST_FRAG;
513 if (!(flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG))
514 goto out_good;
515 }
516 }
517
518 __skb_flow_dissect_ipv4(skb, flow_dissector,
519 target_container, data, iph);
520
521 if (flags & FLOW_DISSECTOR_F_STOP_AT_L3)
522 goto out_good;
523
524 break;
525 }
526 case htons(ETH_P_IPV6): {
527 const struct ipv6hdr *iph;
528 struct ipv6hdr _iph;
529
530 ipv6:
531 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
532 if (!iph)
533 goto out_bad;
534
535 ip_proto = iph->nexthdr;
536 nhoff += sizeof(struct ipv6hdr);
537
538 if (dissector_uses_key(flow_dissector,
539 FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
540 key_addrs = skb_flow_dissector_target(flow_dissector,
541 FLOW_DISSECTOR_KEY_IPV6_ADDRS,
542 target_container);
543
544 memcpy(&key_addrs->v6addrs, &iph->saddr,
545 sizeof(key_addrs->v6addrs));
546 key_control->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
547 }
548
549 if ((dissector_uses_key(flow_dissector,
550 FLOW_DISSECTOR_KEY_FLOW_LABEL) ||
551 (flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL)) &&
552 ip6_flowlabel(iph)) {
553 __be32 flow_label = ip6_flowlabel(iph);
554
555 if (dissector_uses_key(flow_dissector,
556 FLOW_DISSECTOR_KEY_FLOW_LABEL)) {
557 key_tags = skb_flow_dissector_target(flow_dissector,
558 FLOW_DISSECTOR_KEY_FLOW_LABEL,
559 target_container);
560 key_tags->flow_label = ntohl(flow_label);
561 }
562 if (flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL)
563 goto out_good;
564 }
565
566 __skb_flow_dissect_ipv6(skb, flow_dissector,
567 target_container, data, iph);
568
569 if (flags & FLOW_DISSECTOR_F_STOP_AT_L3)
570 goto out_good;
571
572 break;
573 }
574 case htons(ETH_P_8021AD):
575 case htons(ETH_P_8021Q): {
576 const struct vlan_hdr *vlan;
577 struct vlan_hdr _vlan;
578 bool vlan_tag_present = skb && skb_vlan_tag_present(skb);
579
580 if (vlan_tag_present)
581 proto = skb->protocol;
582
583 if (!vlan_tag_present || eth_type_vlan(skb->protocol)) {
584 vlan = __skb_header_pointer(skb, nhoff, sizeof(_vlan),
585 data, hlen, &_vlan);
586 if (!vlan)
587 goto out_bad;
588 proto = vlan->h_vlan_encapsulated_proto;
589 nhoff += sizeof(*vlan);
590 if (skip_vlan)
591 goto proto_again;
592 }
593
594 skip_vlan = true;
595 if (dissector_uses_key(flow_dissector,
596 FLOW_DISSECTOR_KEY_VLAN)) {
597 key_vlan = skb_flow_dissector_target(flow_dissector,
598 FLOW_DISSECTOR_KEY_VLAN,
599 target_container);
600
601 if (vlan_tag_present) {
602 key_vlan->vlan_id = skb_vlan_tag_get_id(skb);
603 key_vlan->vlan_priority =
604 (skb_vlan_tag_get_prio(skb) >> VLAN_PRIO_SHIFT);
605 } else {
606 key_vlan->vlan_id = ntohs(vlan->h_vlan_TCI) &
607 VLAN_VID_MASK;
608 key_vlan->vlan_priority =
609 (ntohs(vlan->h_vlan_TCI) &
610 VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
611 }
612 }
613
614 goto proto_again;
615 }
616 case htons(ETH_P_PPP_SES): {
617 struct {
618 struct pppoe_hdr hdr;
619 __be16 proto;
620 } *hdr, _hdr;
621 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
622 if (!hdr)
623 goto out_bad;
624 proto = hdr->proto;
625 nhoff += PPPOE_SES_HLEN;
626 switch (proto) {
627 case htons(PPP_IP):
628 goto ip;
629 case htons(PPP_IPV6):
630 goto ipv6;
631 default:
632 goto out_bad;
633 }
634 }
635 case htons(ETH_P_TIPC): {
636 struct {
637 __be32 pre[3];
638 __be32 srcnode;
639 } *hdr, _hdr;
640 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
641 if (!hdr)
642 goto out_bad;
643
644 if (dissector_uses_key(flow_dissector,
645 FLOW_DISSECTOR_KEY_TIPC_ADDRS)) {
646 key_addrs = skb_flow_dissector_target(flow_dissector,
647 FLOW_DISSECTOR_KEY_TIPC_ADDRS,
648 target_container);
649 key_addrs->tipcaddrs.srcnode = hdr->srcnode;
650 key_control->addr_type = FLOW_DISSECTOR_KEY_TIPC_ADDRS;
651 }
652 goto out_good;
653 }
654
655 case htons(ETH_P_MPLS_UC):
656 case htons(ETH_P_MPLS_MC):
657 mpls:
658 switch (__skb_flow_dissect_mpls(skb, flow_dissector,
659 target_container, data,
660 nhoff, hlen)) {
661 case FLOW_DISSECT_RET_OUT_GOOD:
662 goto out_good;
663 case FLOW_DISSECT_RET_OUT_BAD:
664 default:
665 goto out_bad;
666 }
667 case htons(ETH_P_FCOE):
668 if ((hlen - nhoff) < FCOE_HEADER_LEN)
669 goto out_bad;
670
671 nhoff += FCOE_HEADER_LEN;
672 goto out_good;
673
674 case htons(ETH_P_ARP):
675 case htons(ETH_P_RARP):
676 switch (__skb_flow_dissect_arp(skb, flow_dissector,
677 target_container, data,
678 nhoff, hlen)) {
679 case FLOW_DISSECT_RET_OUT_GOOD:
680 goto out_good;
681 case FLOW_DISSECT_RET_OUT_BAD:
682 default:
683 goto out_bad;
684 }
685 default:
686 goto out_bad;
687 }
688
689 ip_proto_again:
690 switch (ip_proto) {
691 case IPPROTO_GRE:
692 switch (__skb_flow_dissect_gre(skb, key_control, flow_dissector,
693 target_container, data,
694 &proto, &nhoff, &hlen, flags)) {
695 case FLOW_DISSECT_RET_OUT_GOOD:
696 goto out_good;
697 case FLOW_DISSECT_RET_OUT_BAD:
698 goto out_bad;
699 case FLOW_DISSECT_RET_OUT_PROTO_AGAIN:
700 goto proto_again;
701 }
702 case NEXTHDR_HOP:
703 case NEXTHDR_ROUTING:
704 case NEXTHDR_DEST: {
705 u8 _opthdr[2], *opthdr;
706
707 if (proto != htons(ETH_P_IPV6))
708 break;
709
710 opthdr = __skb_header_pointer(skb, nhoff, sizeof(_opthdr),
711 data, hlen, &_opthdr);
712 if (!opthdr)
713 goto out_bad;
714
715 ip_proto = opthdr[0];
716 nhoff += (opthdr[1] + 1) << 3;
717
718 goto ip_proto_again;
719 }
720 case NEXTHDR_FRAGMENT: {
721 struct frag_hdr _fh, *fh;
722
723 if (proto != htons(ETH_P_IPV6))
724 break;
725
726 fh = __skb_header_pointer(skb, nhoff, sizeof(_fh),
727 data, hlen, &_fh);
728
729 if (!fh)
730 goto out_bad;
731
732 key_control->flags |= FLOW_DIS_IS_FRAGMENT;
733
734 nhoff += sizeof(_fh);
735 ip_proto = fh->nexthdr;
736
737 if (!(fh->frag_off & htons(IP6_OFFSET))) {
738 key_control->flags |= FLOW_DIS_FIRST_FRAG;
739 if (flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG)
740 goto ip_proto_again;
741 }
742 goto out_good;
743 }
744 case IPPROTO_IPIP:
745 proto = htons(ETH_P_IP);
746
747 key_control->flags |= FLOW_DIS_ENCAPSULATION;
748 if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP)
749 goto out_good;
750
751 goto ip;
752 case IPPROTO_IPV6:
753 proto = htons(ETH_P_IPV6);
754
755 key_control->flags |= FLOW_DIS_ENCAPSULATION;
756 if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP)
757 goto out_good;
758
759 goto ipv6;
760 case IPPROTO_MPLS:
761 proto = htons(ETH_P_MPLS_UC);
762 goto mpls;
763 case IPPROTO_TCP:
764 __skb_flow_dissect_tcp(skb, flow_dissector, target_container,
765 data, nhoff, hlen);
766 break;
767 default:
768 break;
769 }
770
771 if (dissector_uses_key(flow_dissector,
772 FLOW_DISSECTOR_KEY_PORTS)) {
773 key_ports = skb_flow_dissector_target(flow_dissector,
774 FLOW_DISSECTOR_KEY_PORTS,
775 target_container);
776 key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto,
777 data, hlen);
778 }
779
780 if (dissector_uses_key(flow_dissector,
781 FLOW_DISSECTOR_KEY_ICMP)) {
782 key_icmp = skb_flow_dissector_target(flow_dissector,
783 FLOW_DISSECTOR_KEY_ICMP,
784 target_container);
785 key_icmp->icmp = skb_flow_get_be16(skb, nhoff, data, hlen);
786 }
787
788 out_good:
789 ret = true;
790
791 key_control->thoff = (u16)nhoff;
792 out:
793 key_basic->n_proto = proto;
794 key_basic->ip_proto = ip_proto;
795
796 return ret;
797
798 out_bad:
799 ret = false;
800 key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen);
801 goto out;
802 }
803 EXPORT_SYMBOL(__skb_flow_dissect);
804
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 30230 bytes --]
^ permalink raw reply
* Re: [PATCH 0/4] net-next: dsa: fix flow dissection
From: Eric Dumazet @ 2017-08-10 6:42 UTC (permalink / raw)
To: David Miller
Cc: john, andrew, vivien.didelot, f.fainelli, sean.wang, netdev,
linux-mediatek, linux-kernel, muciri, shashidhar.lakkavalli
In-Reply-To: <20170809.225243.2204411285392662424.davem@davemloft.net>
On Wed, 2017-08-09 at 22:52 -0700, David Miller wrote:
> From: John Crispin <john@phrozen.org>
> Date: Wed, 9 Aug 2017 14:41:15 +0200
>
> > RPS and probably other kernel features are currently broken on some if not
> > all DSA devices. The root cause of this is that skb_hash will call the
> > flow_dissector. At this point the skb still contains the magic switch
> > header and the skb->protocol field is not set up to the correct 802.3
> > value yet. By the time the tag specific code is called, removing the header
> > and properly setting the protocol an invalid hash is already set. In the
> > case of the mt7530 this will result in all flows always having the same
> > hash.
> >
> > Changes since RFC:
> > * use a callback instead of static values
> > * add cover letter
>
> Series applied, thanks.
Is this related ?
net/core/flow_dissector.c: In function '__skb_flow_dissect':
net/core/flow_dissector.c:448:18: error: 'struct net_device' has no member named 'dsa_ptr'
ops = skb->dev->dsa_ptr->tag_ops;
^
make[3]: *** [net/core/flow_dissector.o] Error 1
^ permalink raw reply
* [net-next:master 905/906] net/core/flow_dissector.c:448:18: error: 'struct net_device' has no member named 'dsa_ptr'
From: kbuild test robot @ 2017-08-10 6:39 UTC (permalink / raw)
To: John Crispin
Cc: kbuild-all, netdev, Muciri Gatimu, Shashidhar Lakkavalli,
Andrew Lunn
[-- Attachment #1: Type: text/plain, Size: 14165 bytes --]
tree: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git master
head: 7e1ecbcf79b2fdc7349da1bb90d6dadad1f9ac89
commit: 43e665287f931a167cd2eea3387efda901bff0ce [905/906] net-next: dsa: fix flow dissection
config: i386-randconfig-a1-201732 (attached as .config)
compiler: gcc-5 (Debian 5.4.1-2) 5.4.1 20160904
reproduce:
git checkout 43e665287f931a167cd2eea3387efda901bff0ce
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
net/core/flow_dissector.c: In function '__skb_flow_dissect':
>> net/core/flow_dissector.c:448:18: error: 'struct net_device' has no member named 'dsa_ptr'
ops = skb->dev->dsa_ptr->tag_ops;
^
vim +448 net/core/flow_dissector.c
404
405 /**
406 * __skb_flow_dissect - extract the flow_keys struct and return it
407 * @skb: sk_buff to extract the flow from, can be NULL if the rest are specified
408 * @flow_dissector: list of keys to dissect
409 * @target_container: target structure to put dissected values into
410 * @data: raw buffer pointer to the packet, if NULL use skb->data
411 * @proto: protocol for which to get the flow, if @data is NULL use skb->protocol
412 * @nhoff: network header offset, if @data is NULL use skb_network_offset(skb)
413 * @hlen: packet header length, if @data is NULL use skb_headlen(skb)
414 *
415 * The function will try to retrieve individual keys into target specified
416 * by flow_dissector from either the skbuff or a raw buffer specified by the
417 * rest parameters.
418 *
419 * Caller must take care of zeroing target container memory.
420 */
421 bool __skb_flow_dissect(const struct sk_buff *skb,
422 struct flow_dissector *flow_dissector,
423 void *target_container,
424 void *data, __be16 proto, int nhoff, int hlen,
425 unsigned int flags)
426 {
427 struct flow_dissector_key_control *key_control;
428 struct flow_dissector_key_basic *key_basic;
429 struct flow_dissector_key_addrs *key_addrs;
430 struct flow_dissector_key_ports *key_ports;
431 struct flow_dissector_key_icmp *key_icmp;
432 struct flow_dissector_key_tags *key_tags;
433 struct flow_dissector_key_vlan *key_vlan;
434 bool skip_vlan = false;
435 u8 ip_proto = 0;
436 bool ret;
437
438 if (!data) {
439 data = skb->data;
440 proto = skb_vlan_tag_present(skb) ?
441 skb->vlan_proto : skb->protocol;
442 nhoff = skb_network_offset(skb);
443 hlen = skb_headlen(skb);
444 if (unlikely(netdev_uses_dsa(skb->dev))) {
445 const struct dsa_device_ops *ops;
446 int offset;
447
> 448 ops = skb->dev->dsa_ptr->tag_ops;
449 if (ops->flow_dissect &&
450 !ops->flow_dissect(skb, &proto, &offset)) {
451 hlen -= offset;
452 nhoff += offset;
453 }
454 }
455 }
456
457 /* It is ensured by skb_flow_dissector_init() that control key will
458 * be always present.
459 */
460 key_control = skb_flow_dissector_target(flow_dissector,
461 FLOW_DISSECTOR_KEY_CONTROL,
462 target_container);
463
464 /* It is ensured by skb_flow_dissector_init() that basic key will
465 * be always present.
466 */
467 key_basic = skb_flow_dissector_target(flow_dissector,
468 FLOW_DISSECTOR_KEY_BASIC,
469 target_container);
470
471 if (dissector_uses_key(flow_dissector,
472 FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
473 struct ethhdr *eth = eth_hdr(skb);
474 struct flow_dissector_key_eth_addrs *key_eth_addrs;
475
476 key_eth_addrs = skb_flow_dissector_target(flow_dissector,
477 FLOW_DISSECTOR_KEY_ETH_ADDRS,
478 target_container);
479 memcpy(key_eth_addrs, ð->h_dest, sizeof(*key_eth_addrs));
480 }
481
482 proto_again:
483 switch (proto) {
484 case htons(ETH_P_IP): {
485 const struct iphdr *iph;
486 struct iphdr _iph;
487 ip:
488 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
489 if (!iph || iph->ihl < 5)
490 goto out_bad;
491 nhoff += iph->ihl * 4;
492
493 ip_proto = iph->protocol;
494
495 if (dissector_uses_key(flow_dissector,
496 FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
497 key_addrs = skb_flow_dissector_target(flow_dissector,
498 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
499 target_container);
500
501 memcpy(&key_addrs->v4addrs, &iph->saddr,
502 sizeof(key_addrs->v4addrs));
503 key_control->addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
504 }
505
506 if (ip_is_fragment(iph)) {
507 key_control->flags |= FLOW_DIS_IS_FRAGMENT;
508
509 if (iph->frag_off & htons(IP_OFFSET)) {
510 goto out_good;
511 } else {
512 key_control->flags |= FLOW_DIS_FIRST_FRAG;
513 if (!(flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG))
514 goto out_good;
515 }
516 }
517
518 __skb_flow_dissect_ipv4(skb, flow_dissector,
519 target_container, data, iph);
520
521 if (flags & FLOW_DISSECTOR_F_STOP_AT_L3)
522 goto out_good;
523
524 break;
525 }
526 case htons(ETH_P_IPV6): {
527 const struct ipv6hdr *iph;
528 struct ipv6hdr _iph;
529
530 ipv6:
531 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
532 if (!iph)
533 goto out_bad;
534
535 ip_proto = iph->nexthdr;
536 nhoff += sizeof(struct ipv6hdr);
537
538 if (dissector_uses_key(flow_dissector,
539 FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
540 key_addrs = skb_flow_dissector_target(flow_dissector,
541 FLOW_DISSECTOR_KEY_IPV6_ADDRS,
542 target_container);
543
544 memcpy(&key_addrs->v6addrs, &iph->saddr,
545 sizeof(key_addrs->v6addrs));
546 key_control->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
547 }
548
549 if ((dissector_uses_key(flow_dissector,
550 FLOW_DISSECTOR_KEY_FLOW_LABEL) ||
551 (flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL)) &&
552 ip6_flowlabel(iph)) {
553 __be32 flow_label = ip6_flowlabel(iph);
554
555 if (dissector_uses_key(flow_dissector,
556 FLOW_DISSECTOR_KEY_FLOW_LABEL)) {
557 key_tags = skb_flow_dissector_target(flow_dissector,
558 FLOW_DISSECTOR_KEY_FLOW_LABEL,
559 target_container);
560 key_tags->flow_label = ntohl(flow_label);
561 }
562 if (flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL)
563 goto out_good;
564 }
565
566 __skb_flow_dissect_ipv6(skb, flow_dissector,
567 target_container, data, iph);
568
569 if (flags & FLOW_DISSECTOR_F_STOP_AT_L3)
570 goto out_good;
571
572 break;
573 }
574 case htons(ETH_P_8021AD):
575 case htons(ETH_P_8021Q): {
576 const struct vlan_hdr *vlan;
577 struct vlan_hdr _vlan;
578 bool vlan_tag_present = skb && skb_vlan_tag_present(skb);
579
580 if (vlan_tag_present)
581 proto = skb->protocol;
582
583 if (!vlan_tag_present || eth_type_vlan(skb->protocol)) {
584 vlan = __skb_header_pointer(skb, nhoff, sizeof(_vlan),
585 data, hlen, &_vlan);
586 if (!vlan)
587 goto out_bad;
588 proto = vlan->h_vlan_encapsulated_proto;
589 nhoff += sizeof(*vlan);
590 if (skip_vlan)
591 goto proto_again;
592 }
593
594 skip_vlan = true;
595 if (dissector_uses_key(flow_dissector,
596 FLOW_DISSECTOR_KEY_VLAN)) {
597 key_vlan = skb_flow_dissector_target(flow_dissector,
598 FLOW_DISSECTOR_KEY_VLAN,
599 target_container);
600
601 if (vlan_tag_present) {
602 key_vlan->vlan_id = skb_vlan_tag_get_id(skb);
603 key_vlan->vlan_priority =
604 (skb_vlan_tag_get_prio(skb) >> VLAN_PRIO_SHIFT);
605 } else {
606 key_vlan->vlan_id = ntohs(vlan->h_vlan_TCI) &
607 VLAN_VID_MASK;
608 key_vlan->vlan_priority =
609 (ntohs(vlan->h_vlan_TCI) &
610 VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
611 }
612 }
613
614 goto proto_again;
615 }
616 case htons(ETH_P_PPP_SES): {
617 struct {
618 struct pppoe_hdr hdr;
619 __be16 proto;
620 } *hdr, _hdr;
621 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
622 if (!hdr)
623 goto out_bad;
624 proto = hdr->proto;
625 nhoff += PPPOE_SES_HLEN;
626 switch (proto) {
627 case htons(PPP_IP):
628 goto ip;
629 case htons(PPP_IPV6):
630 goto ipv6;
631 default:
632 goto out_bad;
633 }
634 }
635 case htons(ETH_P_TIPC): {
636 struct {
637 __be32 pre[3];
638 __be32 srcnode;
639 } *hdr, _hdr;
640 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
641 if (!hdr)
642 goto out_bad;
643
644 if (dissector_uses_key(flow_dissector,
645 FLOW_DISSECTOR_KEY_TIPC_ADDRS)) {
646 key_addrs = skb_flow_dissector_target(flow_dissector,
647 FLOW_DISSECTOR_KEY_TIPC_ADDRS,
648 target_container);
649 key_addrs->tipcaddrs.srcnode = hdr->srcnode;
650 key_control->addr_type = FLOW_DISSECTOR_KEY_TIPC_ADDRS;
651 }
652 goto out_good;
653 }
654
655 case htons(ETH_P_MPLS_UC):
656 case htons(ETH_P_MPLS_MC):
657 mpls:
658 switch (__skb_flow_dissect_mpls(skb, flow_dissector,
659 target_container, data,
660 nhoff, hlen)) {
661 case FLOW_DISSECT_RET_OUT_GOOD:
662 goto out_good;
663 case FLOW_DISSECT_RET_OUT_BAD:
664 default:
665 goto out_bad;
666 }
667 case htons(ETH_P_FCOE):
668 if ((hlen - nhoff) < FCOE_HEADER_LEN)
669 goto out_bad;
670
671 nhoff += FCOE_HEADER_LEN;
672 goto out_good;
673
674 case htons(ETH_P_ARP):
675 case htons(ETH_P_RARP):
676 switch (__skb_flow_dissect_arp(skb, flow_dissector,
677 target_container, data,
678 nhoff, hlen)) {
679 case FLOW_DISSECT_RET_OUT_GOOD:
680 goto out_good;
681 case FLOW_DISSECT_RET_OUT_BAD:
682 default:
683 goto out_bad;
684 }
685 default:
686 goto out_bad;
687 }
688
689 ip_proto_again:
690 switch (ip_proto) {
691 case IPPROTO_GRE:
692 switch (__skb_flow_dissect_gre(skb, key_control, flow_dissector,
693 target_container, data,
694 &proto, &nhoff, &hlen, flags)) {
695 case FLOW_DISSECT_RET_OUT_GOOD:
696 goto out_good;
697 case FLOW_DISSECT_RET_OUT_BAD:
698 goto out_bad;
699 case FLOW_DISSECT_RET_OUT_PROTO_AGAIN:
700 goto proto_again;
701 }
702 case NEXTHDR_HOP:
703 case NEXTHDR_ROUTING:
704 case NEXTHDR_DEST: {
705 u8 _opthdr[2], *opthdr;
706
707 if (proto != htons(ETH_P_IPV6))
708 break;
709
710 opthdr = __skb_header_pointer(skb, nhoff, sizeof(_opthdr),
711 data, hlen, &_opthdr);
712 if (!opthdr)
713 goto out_bad;
714
715 ip_proto = opthdr[0];
716 nhoff += (opthdr[1] + 1) << 3;
717
718 goto ip_proto_again;
719 }
720 case NEXTHDR_FRAGMENT: {
721 struct frag_hdr _fh, *fh;
722
723 if (proto != htons(ETH_P_IPV6))
724 break;
725
726 fh = __skb_header_pointer(skb, nhoff, sizeof(_fh),
727 data, hlen, &_fh);
728
729 if (!fh)
730 goto out_bad;
731
732 key_control->flags |= FLOW_DIS_IS_FRAGMENT;
733
734 nhoff += sizeof(_fh);
735 ip_proto = fh->nexthdr;
736
737 if (!(fh->frag_off & htons(IP6_OFFSET))) {
738 key_control->flags |= FLOW_DIS_FIRST_FRAG;
739 if (flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG)
740 goto ip_proto_again;
741 }
742 goto out_good;
743 }
744 case IPPROTO_IPIP:
745 proto = htons(ETH_P_IP);
746
747 key_control->flags |= FLOW_DIS_ENCAPSULATION;
748 if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP)
749 goto out_good;
750
751 goto ip;
752 case IPPROTO_IPV6:
753 proto = htons(ETH_P_IPV6);
754
755 key_control->flags |= FLOW_DIS_ENCAPSULATION;
756 if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP)
757 goto out_good;
758
759 goto ipv6;
760 case IPPROTO_MPLS:
761 proto = htons(ETH_P_MPLS_UC);
762 goto mpls;
763 case IPPROTO_TCP:
764 __skb_flow_dissect_tcp(skb, flow_dissector, target_container,
765 data, nhoff, hlen);
766 break;
767 default:
768 break;
769 }
770
771 if (dissector_uses_key(flow_dissector,
772 FLOW_DISSECTOR_KEY_PORTS)) {
773 key_ports = skb_flow_dissector_target(flow_dissector,
774 FLOW_DISSECTOR_KEY_PORTS,
775 target_container);
776 key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto,
777 data, hlen);
778 }
779
780 if (dissector_uses_key(flow_dissector,
781 FLOW_DISSECTOR_KEY_ICMP)) {
782 key_icmp = skb_flow_dissector_target(flow_dissector,
783 FLOW_DISSECTOR_KEY_ICMP,
784 target_container);
785 key_icmp->icmp = skb_flow_get_be16(skb, nhoff, data, hlen);
786 }
787
788 out_good:
789 ret = true;
790
791 key_control->thoff = (u16)nhoff;
792 out:
793 key_basic->n_proto = proto;
794 key_basic->ip_proto = ip_proto;
795
796 return ret;
797
798 out_bad:
799 ret = false;
800 key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen);
801 goto out;
802 }
803 EXPORT_SYMBOL(__skb_flow_dissect);
804
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28079 bytes --]
^ permalink raw reply
* Re: [PATCH net-next] skbuff: Add BUG_ON in skb_init.
From: Tonghao Zhang @ 2017-08-10 6:10 UTC (permalink / raw)
To: David Miller; +Cc: Linux Kernel Network Developers
In-Reply-To: <20170809.224939.550080421760909361.davem@davemloft.net>
Thanks a lot. I found it when reviewing this codes. and BUG_ON is
added in the init_inodecache(). We may remove it or not ?
diff --git a/net/socket.c b/net/socket.c
index b332d1e..ebee3ee 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -296,7 +296,6 @@ static void init_inodecache(void)
SLAB_RECLAIM_ACCOUNT |
SLAB_MEM_SPREAD | SLAB_ACCOUNT),
init_once);
- BUG_ON(sock_inode_cachep == NULL);
}
static const struct super_operations sockfs_ops = {
On Thu, Aug 10, 2017 at 1:49 PM, David Miller <davem@davemloft.net> wrote:
> From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> Date: Wed, 9 Aug 2017 05:04:38 -0700
>
>> When initializing the skbuff SLAB cache, we should make
>> sure it is successful. Adding BUG_ON to check it and
>> init_inodecache() is in the same case.
>>
>> Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com>
>> ---
>> net/core/skbuff.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
>> index 42b62c716a33..9513de519870 100644
>> --- a/net/core/skbuff.c
>> +++ b/net/core/skbuff.c
>> @@ -3904,6 +3904,8 @@ void __init skb_init(void)
>> 0,
>> SLAB_HWCACHE_ALIGN|SLAB_PANIC,
>> NULL);
>> + BUG_ON(skbuff_head_cache == NULL);
>> + BUG_ON(skbuff_fclone_cache == NULL);
>> }
>
> I know you guys want every allocation to be explicitly checked so that
> everything is consistent for static code analysis checkers.
>
> But this is just wasted code.
>
> The first allocation will take a NULL dereference and the backtrace
> will make it completely clear which SLAB cache was NULL and couldn't
> be allocated.
>
> So there is no real value to adding these checks.
>
> So I'm not applying this, sorry.
>
> The same logic goes for your other patch of this nature.
>
^ permalink raw reply related
* Re: [PATCH 0/4] net-next: dsa: fix flow dissection
From: David Miller @ 2017-08-10 5:52 UTC (permalink / raw)
To: john
Cc: andrew, vivien.didelot, f.fainelli, sean.wang, netdev,
linux-mediatek, linux-kernel, muciri, shashidhar.lakkavalli
In-Reply-To: <20170809124119.24320-1-john@phrozen.org>
From: John Crispin <john@phrozen.org>
Date: Wed, 9 Aug 2017 14:41:15 +0200
> RPS and probably other kernel features are currently broken on some if not
> all DSA devices. The root cause of this is that skb_hash will call the
> flow_dissector. At this point the skb still contains the magic switch
> header and the skb->protocol field is not set up to the correct 802.3
> value yet. By the time the tag specific code is called, removing the header
> and properly setting the protocol an invalid hash is already set. In the
> case of the mt7530 this will result in all flows always having the same
> hash.
>
> Changes since RFC:
> * use a callback instead of static values
> * add cover letter
Series applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next] skbuff: Add BUG_ON in skb_init.
From: David Miller @ 2017-08-10 5:49 UTC (permalink / raw)
To: xiangxia.m.yue; +Cc: netdev
In-Reply-To: <1502280278-9970-2-git-send-email-xiangxia.m.yue@gmail.com>
From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
Date: Wed, 9 Aug 2017 05:04:38 -0700
> When initializing the skbuff SLAB cache, we should make
> sure it is successful. Adding BUG_ON to check it and
> init_inodecache() is in the same case.
>
> Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> ---
> net/core/skbuff.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index 42b62c716a33..9513de519870 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -3904,6 +3904,8 @@ void __init skb_init(void)
> 0,
> SLAB_HWCACHE_ALIGN|SLAB_PANIC,
> NULL);
> + BUG_ON(skbuff_head_cache == NULL);
> + BUG_ON(skbuff_fclone_cache == NULL);
> }
I know you guys want every allocation to be explicitly checked so that
everything is consistent for static code analysis checkers.
But this is just wasted code.
The first allocation will take a NULL dereference and the backtrace
will make it completely clear which SLAB cache was NULL and couldn't
be allocated.
So there is no real value to adding these checks.
So I'm not applying this, sorry.
The same logic goes for your other patch of this nature.
^ permalink raw reply
* Re: [PATCHv2] igmp: Fix regression caused by igmp sysctl namespace code.
From: David Miller @ 2017-08-10 5:47 UTC (permalink / raw)
To: nborisov; +Cc: kuznet, yoshfuji, netdev, eric.dumazet, stable
In-Reply-To: <1502278684-11151-1-git-send-email-nborisov@suse.com>
From: Nikolay Borisov <nborisov@suse.com>
Date: Wed, 9 Aug 2017 14:38:04 +0300
> Commit dcd87999d415 ("igmp: net: Move igmp namespace init to correct file")
> moved the igmp sysctls initialization from tcp_sk_init to igmp_net_init. This
> function is only called as part of per-namespace initialization, only if
> CONFIG_IP_MULTICAST is defined, otherwise igmp_mc_init() call in ip_init is
> compiled out, casuing the igmp pernet ops to not be registerd and those sysctl
> being left initialized with 0. However, there are certain functions, such as
> ip_mc_join_group which are always compiled and make use of some of those
> sysctls. Let's do a partial revert of the aforementioned commit and move the
> sysctl initialization into inet_init_net, that way they will always have
> sane values.
>
> Fixes: dcd87999d415 ("igmp: net: Move igmp namespace init to correct file")
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=196595
> Reported-by: Gerardo Exequiel Pozzi <vmlinuz386@gmail.com>
> Cc: <stable@vger.kernel.org> # 4.6
> Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Please do not use "CC: stable.." for networking patches, I take care of
-stable submissions by hand for those.
Applied and queued up for -stable, thanks.
^ permalink raw reply
* Re: [PATCHv2 net] net: sched: set xt_tgchk_param par.nft_compat as 0 in ipt_init_target
From: David Miller @ 2017-08-10 5:47 UTC (permalink / raw)
To: lucien.xin; +Cc: netdev, jiri, xiyou.wangcong
In-Reply-To: <35173c1e2c6272d137c24706186f1641496943ce.1502273719.git.lucien.xin@gmail.com>
From: Xin Long <lucien.xin@gmail.com>
Date: Wed, 9 Aug 2017 18:15:19 +0800
> Commit 55917a21d0cc ("netfilter: x_tables: add context to know if
> extension runs from nft_compat") introduced a member nft_compat to
> xt_tgchk_param structure.
>
> But it didn't set it's value for ipt_init_target. With unexpected
> value in par.nft_compat, it may return unexpected result in some
> target's checkentry.
>
> This patch is to set all it's fields as 0 and only initialize the
> non-zero fields in ipt_init_target.
>
> v1->v2:
> As Wang Cong's suggestion, fix it by setting all it's fields as
> 0 and only initializing the non-zero fields.
>
> Fixes: 55917a21d0cc ("netfilter: x_tables: add context to know if extension runs from nft_compat")
> Suggested-by: Cong Wang <xiyou.wangcong@gmail.com>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
Applied and queued up for -stable.
^ permalink raw reply
* Re: [PATCH 0/2] net-next: mediatek: bring up QDMA RX ring 0
From: David Miller @ 2017-08-10 5:47 UTC (permalink / raw)
To: john
Cc: sean.wang, netdev, linux-mediatek, linux-kernel, muciri,
shashidhar.lakkavalli
In-Reply-To: <20170809100932.10539-1-john@phrozen.org>
From: John Crispin <john@phrozen.org>
Date: Wed, 9 Aug 2017 12:09:30 +0200
> The MT7623 has several DMA rings. Inside the SW path, the core will use
> the PDMA when receiving traffic. While bringing up the HW path we noticed
> that the PPE requires the QDMA RX to also be brought up as it uses this
> ring internally for its flow scheduling.
Series applied.
^ permalink raw reply
* Re: [PATCH] net: atm: make atmdev_ops const
From: David Miller @ 2017-08-10 5:44 UTC (permalink / raw)
To: bhumirks; +Cc: julia.lawall, netdev, linux-kernel
In-Reply-To: <1502271128-6832-1-git-send-email-bhumirks@gmail.com>
From: Bhumika Goyal <bhumirks@gmail.com>
Date: Wed, 9 Aug 2017 15:02:08 +0530
> Make these const as they are only stored in the ops field of a atm_dev
> structure, which is const.
> Done using Coccinelle.
>
> Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH] atm: make atmdev_ops const
From: David Miller @ 2017-08-10 5:44 UTC (permalink / raw)
To: bhumirks; +Cc: julia.lawall, 3chas3, linux-atm-general, netdev, linux-kernel
In-Reply-To: <1502270355-4231-1-git-send-email-bhumirks@gmail.com>
From: Bhumika Goyal <bhumirks@gmail.com>
Date: Wed, 9 Aug 2017 14:49:15 +0530
> Make these structures const as they are either passed to the function
> atm_dev_register having the corresponding argument as const or stored in
> the ops field of a atm_dev structure, which is also const.
> Done using Coccinelle.
>
> Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH] net: dsa: make dsa_switch_ops const
From: David Miller @ 2017-08-10 5:43 UTC (permalink / raw)
To: bhumirks
Cc: julia.lawall, andrew, vivien.didelot, f.fainelli, netdev,
linux-kernel
In-Reply-To: <1502255055-24751-1-git-send-email-bhumirks@gmail.com>
From: Bhumika Goyal <bhumirks@gmail.com>
Date: Wed, 9 Aug 2017 10:34:15 +0530
> Make these structures const as they are only stored in the ops field of
> a dsa_switch structure, which is const.
> Done using Coccinelle.
>
> Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
Applied, thank you.
^ permalink raw reply
* Re: [PATCH net-next] liquidio: napi cleanup
From: David Miller @ 2017-08-10 5:42 UTC (permalink / raw)
To: felix.manlunas
Cc: netdev, raghu.vatsavayi, derek.chickles, satananda.burla,
intiyaz.basha
In-Reply-To: <20170809023428.GA2054@felix-thinkpad.cavium.com>
From: Felix Manlunas <felix.manlunas@cavium.com>
Date: Tue, 8 Aug 2017 19:34:28 -0700
> From: Intiyaz Basha <intiyaz.basha@cavium.com>
>
> Disable napi when interface is going down.
> Delete napi when destroying the interface.
>
> Signed-off-by: Intiyaz Basha <intiyaz.basha@cavium.com>
> Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net] geneve: maximum value of VNI cannot be used
From: David Miller @ 2017-08-10 5:41 UTC (permalink / raw)
To: girish.moodalbail; +Cc: pshelar, netdev
In-Reply-To: <1502238384-14440-1-git-send-email-girish.moodalbail@oracle.com>
From: Girish Moodalbail <girish.moodalbail@oracle.com>
Date: Tue, 8 Aug 2017 17:26:24 -0700
> Geneve's Virtual Network Identifier (VNI) is 24 bit long, so the range
> of values for it would be from 0 to 16777215 (2^24 -1). However, one
> cannot create a geneve device with VNI set to 16777215. This patch fixes
> this issue.
>
> Signed-off-by: Girish Moodalbail <girish.moodalbail@oracle.com>
I always worry that someone, somewhere, might be using this in some
way and this will break things.
But I'll apply this for now.
^ permalink raw reply
* Re: unregister_netdevice: waiting for eth0 to become free. Usage count = 1
From: Wei Wang @ 2017-08-10 5:41 UTC (permalink / raw)
To: John Stultz
Cc: Cong Wang, lkml, Network Development, Linux USB List,
David S. Miller, Felipe Balbi
In-Reply-To: <CAEA6p_C_rEYkJhcniyy6HUHgNxWFoxWzZ-WHsaSmNDwx4D+RXQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3622 bytes --]
Hi John,
Is it possible to try the attached patch?
I am not sure if it actually fixes the issue. But I think it is worth a try.
Also, could you get me all the ipv6 routes when you plug in the usb
using "ip -6 route show"? (If you have multiple routing tables
configured, could you dump them all?)
Thanks a lot.
Wei
On Wed, Aug 9, 2017 at 6:36 PM, Wei Wang <weiwan@google.com> wrote:
> On Wed, Aug 9, 2017 at 6:26 PM, John Stultz <john.stultz@linaro.org> wrote:
>> On Wed, Aug 9, 2017 at 5:36 PM, Wei Wang <weiwan@google.com> wrote:
>>> On Wed, Aug 9, 2017 at 4:44 PM, John Stultz <john.stultz@linaro.org> wrote:
>>>> On Wed, Aug 9, 2017 at 4:34 PM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
>>>>> (Cc'ing Wei whose commit was blamed)
>>>>>
>>>>> On Mon, Aug 7, 2017 at 2:15 PM, John Stultz <john.stultz@linaro.org> wrote:
>>>>>> On Mon, Aug 7, 2017 at 2:05 PM, John Stultz <john.stultz@linaro.org> wrote:
>>>>>>> So, with recent testing with my HiKey board, I've been noticing some
>>>>>>> quirky behavior with my USB eth adapter.
>>>>>>>
>>>>>>> Basically, pluging the usb eth adapter in and then removing it, when
>>>>>>> plugging it back in I often find that its not detected, and the system
>>>>>>> slowly spits out the following message over and over:
>>>>>>> unregister_netdevice: waiting for eth0 to become free. Usage count = 1
>>>>>>
>>>>>> The other bit is that after this starts printing, the board will no
>>>>>> longer reboot (it hangs continuing to occasionally print the above
>>>>>> message), and I have to manually reset the device.
>>>>>>
>>>>>
>>>>> So this warning is not temporarily shown but lasts until a reboot,
>>>>> right? If so it is a dst refcnt leak.
>>>>
>>>> Correct, once I get into the state it lasts until a reboot.
>>>>
>>>>> How reproducible is it for you? From my reading, it seems always
>>>>> reproduced when you unplug and plug your usb eth interface?
>>>>> Is there anything else involved? For example, network namespace.
>>>>
>>>> So with 4.13-rc3/4 I seem to trigger it easily, often with the first
>>>> unplug of the USB eth adapter.
>>>>
>>>> But as I get back closer to 4.12, it seemingly becomes harder to
>>>> trigger, but sometimes still happens.
>>>>
>>>> So far, I've not been able to trigger it with 4.12.
>>>>
>>>> I don't think network namespaces are involved? Though its out of my
>>>> area, so AOSP may be using them these days. Is there a simple way to
>>>> check?
>>>>
>>>> I'll also do another bisection to see if the bad point moves back any further.
>>
>> So I went through another bisection around and got 9514528d92d4 ipv6:
>> call dst_dev_put() properly as the first bad commit again.
>>
>>> If you see the problem starts to happen on commit
>>> 9514528d92d4cbe086499322370155ed69f5d06c, could you try reverting all
>>> the following commits:
>>> (from new to old)
>>> 1eb04e7c9e63 net: reorder all the dst flags
>>> a4c2fd7f7891 net: remove DST_NOCACHE flag
>>> b2a9c0ed75a3 net: remove DST_NOGC flag
>>> 5b7c9a8ff828 net: remove dst gc related code
>>> db916649b5dd ipv6: get rid of icmp6 dst garbage collector
>>> 587fea741134 ipv6: mark DST_NOGC and remove the operation of dst_free()
>>> ad65a2f05695 ipv6: call dst_hold_safe() properly
>>> 9514528d92d4 ipv6: call dst_dev_put() properly
>>
>>
>> And reverting this set off of 4.13-rc4 seems to make the issue go away.
>>
>> Is there anything I can test to help narrow down the specific problem
>> with that patchset?
>>
>
> Thanks John for confirming.
> Let me spend some time on the commits and I will let you know if I
> have some debug image for you to try.
>
> Wei
>
>
>> thanks
>> -john
[-- Attachment #2: 0001-ipv6-unregister-netdev-bug-fix.patch --]
[-- Type: text/x-patch, Size: 3300 bytes --]
From 93f2836679c81915b110ff56617f9f5dae2e6927 Mon Sep 17 00:00:00 2001
From: Wei Wang <weiwan@google.com>
Date: Wed, 9 Aug 2017 22:27:36 -0700
Subject: [PATCH] ipv6: unregister netdev bug fix
Change-Id: I30fa739989ac50fbc7f4cbc6a04130005589cc25
---
include/net/ip6_route.h | 1 +
net/ipv6/addrconf.c | 10 +++++++---
net/ipv6/anycast.c | 3 ++-
net/ipv6/route.c | 2 +-
4 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 907d39a42f6b..dec1424ce619 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -94,6 +94,7 @@ int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg);
int ip6_route_add(struct fib6_config *cfg, struct netlink_ext_ack *extack);
int ip6_ins_rt(struct rt6_info *);
int ip6_del_rt(struct rt6_info *);
+void rt6_uncached_list_add(struct rt6_info *rt);
static inline int ip6_route_get_saddr(struct net *net, struct rt6_info *rt,
const struct in6_addr *daddr,
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 3c46e9513a31..06a27addb93c 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3079,7 +3079,8 @@ static void init_loopback(struct net_device *dev)
/* Failure cases are ignored */
if (!IS_ERR(sp_rt)) {
sp_ifa->rt = sp_rt;
- ip6_ins_rt(sp_rt);
+ if (ip6_ins_rt(sp_rt))
+ rt6_uncached_list_add(sp_rt);
}
}
read_unlock_bh(&idev->lock);
@@ -3711,6 +3712,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
rt = ifa->rt;
ifa->rt = NULL;
} else {
+ rt6_uncached_list_add(ifa->rt);
state = ifa->state;
ifa->state = INET6_IFADDR_STATE_DEAD;
}
@@ -3882,7 +3884,8 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp)
* Frames right away
*/
if (ifp->flags & IFA_F_OPTIMISTIC) {
- ip6_ins_rt(ifp->rt);
+ if (ip6_ins_rt(ifp->rt))
+ rt6_uncached_list_add(ifp->rt);
if (ipv6_use_optimistic_addr(idev)) {
/* Because optimistic nodes can use this address,
* notify listeners. If DAD fails, RTM_DELADDR is sent.
@@ -5557,7 +5560,8 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
* to do it again
*/
if (!(ifp->rt->rt6i_node))
- ip6_ins_rt(ifp->rt);
+ if(ip6_ins_rt(ifp->rt))
+ rt6_uncached_list_add(ifp->rt);
if (ifp->idev->cnf.forwarding)
addrconf_join_anycast(ifp);
if (!ipv6_addr_any(&ifp->peer_addr))
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 0bbab8a4b5d8..e21c2d6d9b95 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -283,7 +283,8 @@ int __ipv6_dev_ac_inc(struct inet6_dev *idev, const struct in6_addr *addr)
aca_get(aca);
write_unlock_bh(&idev->lock);
- ip6_ins_rt(rt);
+ if (!ip6_ins_rt(rt))
+ rt6_uncached_list_add(rt);
addrconf_join_solict(idev->dev, &aca->aca_addr);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 4d30c96a819d..7a7299da4e09 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -124,7 +124,7 @@ struct uncached_list {
static DEFINE_PER_CPU_ALIGNED(struct uncached_list, rt6_uncached_list);
-static void rt6_uncached_list_add(struct rt6_info *rt)
+void rt6_uncached_list_add(struct rt6_info *rt)
{
struct uncached_list *ul = raw_cpu_ptr(&rt6_uncached_list);
--
2.14.0.434.g98096fd7a8-goog
^ permalink raw reply related
* Re: [PATCH net-next] net: ipv6: lower ndisc notifier priority below addrconf
From: David Miller @ 2017-08-10 5:40 UTC (permalink / raw)
To: dsahern; +Cc: netdev
In-Reply-To: <20170808215102.33798-1-dsahern@gmail.com>
From: David Ahern <dsahern@gmail.com>
Date: Tue, 8 Aug 2017 15:51:02 -0600
> ndisc_notify is used to send unsolicited neighbor advertisements
> (e.g., on a link up). Currently, the ndisc notifier is run before the
> addrconf notifer which means NA's are not sent for link-local addresses
> which are added by the addrconf notifier.
>
> Fix by lowering the priority of the ndisc notifier. Setting the priority
> to ADDRCONF_NOTIFY_PRIORITY - 5 means it runs after addrconf and before
> the route notifier which is ADDRCONF_NOTIFY_PRIORITY - 10.
>
> Signed-off-by: David Ahern <dsahern@gmail.com>
Applied, thanks David.
^ permalink raw reply
* Re: [PATCH net v2] net: systemport: Fix software statistics for SYSTEMPORT Lite
From: David Miller @ 2017-08-10 5:39 UTC (permalink / raw)
To: f.fainelli; +Cc: netdev
In-Reply-To: <20170808214509.26252-1-f.fainelli@gmail.com>
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Tue, 8 Aug 2017 14:45:09 -0700
> With SYSTEMPORT Lite we have holes in our statistics layout that make us
> skip over the hardware MIB counters, bcm_sysport_get_stats() was not
> taking that into account resulting in reporting 0 for all SW-maintained
> statistics, fix this by skipping accordingly.
>
> Fixes: 44a4524c54af ("net: systemport: Add support for SYSTEMPORT Lite")
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Applied, thanks.
^ 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