* Re: [PATCH 0/2] xdp: adjust xdp redirect tracepoint
From: David Miller @ 2017-08-18 23:19 UTC (permalink / raw)
To: brouer; +Cc: netdev, john.fastabend
In-Reply-To: <150298692691.6608.11908184719252996949.stgit@firesoul>
From: Jesper Dangaard Brouer <brouer@redhat.com>
Date: Thu, 17 Aug 2017 18:22:27 +0200
> Working on streamlining the tracepoints for XDP. The eBPF programs
> and XDP have no flow-control or queueing. Investigating using
> tracepoint to provide a feedback on XDP_REDIRECT xmit overflow events.
Series applied, thanks.
^ permalink raw reply
* Re: [PATCH net 1/1] net/mlx4_core: Enable 4K UAR if SRIOV module parameter is not enabled
From: David Miller @ 2017-08-18 23:16 UTC (permalink / raw)
To: saeedm; +Cc: netdev, kamalh, huyn
In-Reply-To: <20170817152952.21592-1-saeedm@mellanox.com>
From: Saeed Mahameed <saeedm@mellanox.com>
Date: Thu, 17 Aug 2017 18:29:52 +0300
> From: Huy Nguyen <huyn@mellanox.com>
>
> enable_4k_uar module parameter was added in patch cited below to
> address the backward compatibility issue in SRIOV when the VM has
> system's PAGE_SIZE uar implementation and the Hypervisor has 4k uar
> implementation.
>
> The above compatibility issue does not exist in the non SRIOV case.
> In this patch, we always enable 4k uar implementation if SRIOV
> is not enabled on mlx4's supported cards.
>
> Fixes: 76e39ccf9c36 ("net/mlx4_core: Fix backward compatibility on VFs")
> Signed-off-by: Huy Nguyen <huyn@mellanox.com>
> Reviewed-by: Daniel Jurgens <danielj@mellanox.com>
> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* Re: [PATCH v2 net-next] net: ipv6: put host and anycast routes on device with address
From: Hannes Frederic Sowa @ 2017-08-18 23:15 UTC (permalink / raw)
To: David Ahern; +Cc: netdev, yoshfuji
In-Reply-To: <1502997440-32334-1-git-send-email-dsahern@gmail.com>
Hello David,
David Ahern <dsahern@gmail.com> writes:
> @@ -2688,15 +2716,9 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
> {
> u32 tb_id;
> struct net *net = dev_net(idev->dev);
> - struct net_device *dev = net->loopback_dev;
> + struct net_device *dev = idev->dev;
> struct rt6_info *rt;
>
> - /* use L3 Master device as loopback for host routes if device
> - * is enslaved and address is not link local or multicast
> - */
> - if (!rt6_need_strict(addr))
> - dev = l3mdev_master_dev_rcu(idev->dev) ? : dev;
> -
> rt = ip6_dst_alloc(net, dev, DST_NOCOUNT);
> if (!rt)
> return ERR_PTR(-ENOMEM);
I am afraid this change might break Java:
<http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/65464a307408/src/java.base/unix/native/libnet/net_util_md.c#l574>
I am all in for this change, but maybe it might be necessary to mask
RTF_LOCAL routes with "lo" somehow.
Bye,
Hannes
^ permalink raw reply
* Re: [PATCH] PCI: Allow PCI express root ports to find themselves
From: David Miller @ 2017-08-18 23:14 UTC (permalink / raw)
To: thierry.reding
Cc: bhelgaas, dingtianhong, mpe, leedom, ashok.raj, werner, ganeshgr,
asit.k.mallick, patrick.j.cramer, Suravee.Suthikulpanit, Bob.Shaw,
l.stach, amira, gabriele.paoloni, David.Laight, jeffrey.t.kirsher,
catalin.marinas, will.deacon, mark.rutland, robin.murphy,
alexander.duyck, eric.dumazet, linux-arm-kernel, netdev,
linux-pci, linux-kernel, linuxarm
In-Reply-To: <20170817110614.11454-1-thierry.reding@gmail.com>
From: Thierry Reding <thierry.reding@gmail.com>
Date: Thu, 17 Aug 2017 13:06:14 +0200
> From: Thierry Reding <treding@nvidia.com>
>
> If the pci_find_pcie_root_port() function is called on a root port
> itself, return the root port rather than NULL.
>
> This effectively reverts commit 0e405232871d6 ("PCI: fix oops when
> try to find Root Port for a PCI device") which added an extra check
> that would now be redundant.
>
> Fixes: a99b646afa8a ("PCI: Disable PCIe Relaxed Ordering if unsupported")
> Fixes: c56d4450eb68 ("PCI: Turn off Request Attributes to avoid Chelsio T5 Completion erratum")
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
> This applies on top of and was tested on next-20170817.
>
> Michael, it'd be great if you could test this one again to clarify
> whether or not the fix that's already in Linus' tree is still needed, or
> whether it's indeed obsoleted by this patch.
Applied, thanks everyone.
^ permalink raw reply
* Re: [PATCH net-next] liquidio: remove support for deprecated f/w cmd OCTNET_CMD_RESET_PF
From: David Miller @ 2017-08-18 23:12 UTC (permalink / raw)
To: felix.manlunas
Cc: netdev, raghu.vatsavayi, derek.chickles, satananda.burla,
ricardo.farrington
In-Reply-To: <20170817013013.GA3149@felix-thinkpad.cavium.com>
From: Felix Manlunas <felix.manlunas@cavium.com>
Date: Wed, 16 Aug 2017 18:30:13 -0700
> From: Rick Farrington <ricardo.farrington@cavium.com>
>
> Signed-off-by: Rick Farrington <ricardo.farrington@cavium.com>
> Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com>
Applied.
^ permalink raw reply
* Re: [PATCH v3] net: inet: diag: expose sockets cgroup classid
From: David Miller @ 2017-08-18 23:11 UTC (permalink / raw)
To: alexander.levin; +Cc: xiyou.wangcong, netdev, linux-kernel
In-Reply-To: <20170817003910.15904-1-alexander.levin@verizon.com>
From: "Levin, Alexander (Sasha Levin)" <alexander.levin@verizon.com>
Date: Thu, 17 Aug 2017 00:35:11 +0000
> From: "Levin, Alexander (Sasha Levin)" <alexander.levin@one.verizon.com>
>
> This is useful for directly looking up a task based on class id rather than
> having to scan through all open file descriptors.
>
> Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Applied to net-next, thanks.
^ permalink raw reply
* Re: [PATCH next] neigh: initialize neigh entry correctly during arp processing
From: David Miller @ 2017-08-18 23:10 UTC (permalink / raw)
To: mahesh
Cc: edumazet, netdev, idosch, ishkamiel, keescook, elena.reshetova,
sowmini.varadhan, fw, roopa, ihrachys, dsa, zhangshengju, maheshb
In-Reply-To: <20170817000251.38469-1-mahesh@bandewar.net>
From: Mahesh Bandewar <mahesh@bandewar.net>
Date: Wed, 16 Aug 2017 17:02:51 -0700
> From: Mahesh Bandewar <maheshb@google.com>
>
> If the ARP processing creates a neigh entry, it's immediately marked
> as STALE without timer and stays that way in that state as long as
> host do not send traffic to that neighbour.
>
> I observed this on hosts which are in IPv6 environment, where there is
> very little to no IPv4 traffic and neigh-entries are stuck in STALE
> mode. Ideally, the host should have PROBEd these neighbours before it
> can send the first packet out.
>
> It happens as a result of following call sequence in an environment
> where host is mostly quiet as far as IPv4 traffic but few connected
> hosts/gateways are sending ARPs.
>
> arp_process()
> neigh_event_ns()
> neigh_lookup()
> neigh_create()
> neigh_alloc()
> nud_state=NUD_NONE
> neigh_update(nud_state=NUD_STALE)
>
> In the above scenario, the neighbour entry does not get a chance to get
> PROBEd as subsequent call to neigh_update() marks this entry STALE.
> This patch initializes the neigh-entry correctly if it was created as a
> result of neigh_lookup instead of just updating it in neigh_event_ns()
> right after creating it.
>
> Signed-off-by: Mahesh Bandewar <maheshb@google.com>
Please provide, in the commit message, a list of events including an
example packet exchange and timers firing which explains how this
situation arises.
Thank you.
^ permalink raw reply
* Re: [PATCH net] tcp: when rearming RTO, if RTO time is in past then fire RTO ASAP
From: David Miller @ 2017-08-18 23:08 UTC (permalink / raw)
To: ncardwell; +Cc: netdev, ycheng, edumazet
In-Reply-To: <20170816215336.30419-1-ncardwell@google.com>
From: Neal Cardwell <ncardwell@google.com>
Date: Wed, 16 Aug 2017 17:53:36 -0400
> In some situations tcp_send_loss_probe() can realize that it's unable
> to send a loss probe (TLP), and falls back to calling tcp_rearm_rto()
> to schedule an RTO timer. In such cases, sometimes tcp_rearm_rto()
> realizes that the RTO was eligible to fire immediately or at some
> point in the past (delta_us <= 0). Previously in such cases
> tcp_rearm_rto() was scheduling such "overdue" RTOs to happen at now +
> icsk_rto, which caused needless delays of hundreds of milliseconds
> (and non-linear behavior that made reproducible testing
> difficult). This commit changes the logic to schedule "overdue" RTOs
> ASAP, rather than at now + icsk_rto.
>
> Suggested-by: Yuchung Cheng <ycheng@google.com>
> Signed-off-by: Neal Cardwell <ncardwell@google.com>
> Signed-off-by: Yuchung Cheng <ycheng@google.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied with Fixes: tag added and queued up for -stable, thanks Neal.
^ permalink raw reply
* [PATCH] net: ibm: emac: Fix some error handling path in 'emac_probe()'
From: Christophe JAILLET @ 2017-08-18 23:07 UTC (permalink / raw)
To: davem, chunkeey, jarod, ivan, ebiggers, tklauser, tremyfr, robh
Cc: netdev, linux-kernel, kernel-janitors, Christophe JAILLET
If 'irq_of_parse_and_map()' or 'of_address_to_resource()' fail, 'err' is
known to be 0 at this point.
So return -ENODEV instead in the first case and propagate the error
returned by 'of_address_to_resource()' in the 2nd case.
While at it, turn a 'err != 0' test into an equivalent 'err' to be more
consistent.
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
---
drivers/net/ethernet/ibm/emac/core.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
index 95135d20458f..1af56a97fb47 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -3032,7 +3032,7 @@ static int emac_probe(struct platform_device *ofdev)
/* Init various config data based on device-tree */
err = emac_init_config(dev);
- if (err != 0)
+ if (err)
goto err_free;
/* Get interrupts. EMAC irq is mandatory, WOL irq is optional */
@@ -3040,12 +3040,14 @@ static int emac_probe(struct platform_device *ofdev)
dev->wol_irq = irq_of_parse_and_map(np, 1);
if (!dev->emac_irq) {
printk(KERN_ERR "%pOF: Can't map main interrupt\n", np);
+ err = -ENODEV;
goto err_free;
}
ndev->irq = dev->emac_irq;
/* Map EMAC regs */
- if (of_address_to_resource(np, 0, &dev->rsrc_regs)) {
+ err = of_address_to_resource(np, 0, &dev->rsrc_regs);
+ if (err) {
printk(KERN_ERR "%pOF: Can't get registers address\n", np);
goto err_irq_unmap;
}
--
2.11.0
^ permalink raw reply related
* RE: [PATCH] vsock: only load vmci transport on VMware hypervisor by default
From: Dexuan Cui @ 2017-08-18 23:07 UTC (permalink / raw)
To: Stefan Hajnoczi
Cc: Jorgen S. Hansen, davem@davemloft.net, netdev@vger.kernel.org,
gregkh@linuxfoundation.org, devel@linuxdriverproject.org,
KY Srinivasan, Haiyang Zhang, Stephen Hemminger, George Zhang,
Michal Kubecek, Asias He, Vitaly Kuznetsov, Cathy Avery,
jasowang@redhat.com, Rolf Neugebauer, Dave Scott, Marcelo Cerri,
apw@canonical.com
In-Reply-To: <20170818153716.GB17572@stefanha-x1.localdomain>
> From: Stefan Hajnoczi [mailto:stefanha@redhat.com]
> > CID is not really used by us, because we only support guest<->host
> communication,
> > and don't support guest<->guest communication. The Hyper-V host
> references
> > every VM by VmID (which is invisible to the VM), and a VM can only talk to
> the
> > host via this feature.
>
> Applications running inside the guest should use VMADDR_CID_HOST (2) to
> connect to the host, even on Hyper-V.
I have no objection, and this patch does support this usage of the
user-space applications.
> By the way, we should collaborate on a test suite and a vsock(7) man
> page that documents the semantics of AF_VSOCK sockets. This way our
> transports will have the same behavior and AF_VSOCK applications will
> work on all 3 hypervisors.
I can't agree more. :-)
BTW, I have been using Rolf's test suite to test my patch:
https://github.com/rn/virtsock/tree/master/c
Maybe this can be a good starting point.
> Not all features need to be supported. For example, VMCI supports
> SOCK_DGRAM while Hyper-V and virtio do not. But features that are
> available should behave identically.
I totally agree, though I'm afraid Hyper-V may have a little more limitations
compared to VMware/KVM duo to the <VM_ID, ServiceID> <--> <cid, port>
mapping.
> > Can we use the 'protocol' parameter in the socket() function:
> > int socket(int domain, int type, int protocol)
> >
> > IMO currently the 'protocol' is not really used.
> > I think we can modify __vsock_core_init() to allow multiple transport layers
> to
> > be registered, and we can define different 'protocol' numbers for
> > VMware/KVM/Hyper-V, and ask the application to explicitly specify what
> should
> > be used. Considering compatibility, we can use the default transport in a
> given
> > VM depending on the underlying hypervisor.
>
> I think AF_VSOCK should hide the transport from users/applications.
Ideally yes, but let's consider the KVM-on-KVM nested scenario: when
an application in the Level-1 VM creates an AF_VSOCK socket and call
connect() for it, how can we know if the app is trying to connect to
the Level-0 host, or connect to the Level-2 VM? We can't. That's why
I propose we should use the 'protocol' parameter to distinguish between
"to guest" and "to host".
With my proposal, in the above scenario, by default (the 'protocol' is 0),
we choose the "to host" transport layer when socket() is called; if the
userspace app explicitly specifies "to guest", we choose the "to guest"
transport layer when socket() is called. This way, the connect(), bind(), etc.
can work automatically.
(Of course, the default transport for a give VM can be better chosen
if we detect which nested level the app is running on.)
> Think of same-on-same nested virtualization: VMware-on-VMware or
> KVM-on-KVM. In that case specifying VMCI or virtio doesn't help.
>
> We'd still need to distinguish between "to guest" and "to host"
> (currently VMCI has code to do this but virtio does not).
>
> The natural place to distinguish the destination is when dealing with
> the sockaddr in connect(), bind(), etc.
>
> Stefan
Thanks,
-- Dexuan
^ permalink raw reply
* Re: [PATCH net-next] macvlan: add offload features for encapsulation
From: David Miller @ 2017-08-18 23:07 UTC (permalink / raw)
To: dmichail; +Cc: netdev
In-Reply-To: <20170816213446.10584-1-dmichail@google.com>
From: Dimitris Michailidis <dmichail@google.com>
Date: Wed, 16 Aug 2017 14:34:46 -0700
> Currently macvlan devices do not set their hw_enc_features making
> encapsulated Tx packets resort to SW fallbacks. Add encapsulation GSO
> offloads to ->features as is done for the other GSOs and set
> ->hw_enc_features.
>
> Signed-off-by: Dimitris Michailidis <dmichail@google.com>
Applied.
^ permalink raw reply
* Re: [PATCH net v2] net: check and errout if res->fi is NULL when RTM_F_FIB_MATCH is set
From: David Miller @ 2017-08-18 23:06 UTC (permalink / raw)
To: roopa; +Cc: netdev, fw, dsa, idaifish, syzkaller, dvyukov, eric.dumazet
In-Reply-To: <1502912332-41154-1-git-send-email-roopa@cumulusnetworks.com>
From: Roopa Prabhu <roopa@cumulusnetworks.com>
Date: Wed, 16 Aug 2017 12:38:52 -0700
> From: Roopa Prabhu <roopa@cumulusnetworks.com>
>
> Syzkaller hit 'general protection fault in fib_dump_info' bug on
> commit 4.13-rc5..
>
> Guilty file: net/ipv4/fib_semantics.c
...
> This patch adds a res->fi NULL check.
>
> example run:
> $ip route get 0.0.0.0 iif virt1-0
> broadcast 0.0.0.0 dev lo
> cache <local,brd> iif virt1-0
>
> $ip route get 0.0.0.0 iif virt1-0 fibmatch
> RTNETLINK answers: No route to host
>
> Reported-by: idaifish <idaifish@gmail.com>
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> Fixes: b61798130f1b ("net: ipv4: RTM_GETROUTE: return matched fib result when requested")
> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Applied, thank you.
^ permalink raw reply
* Re: [net-next PATCH] net: rcu lock and preempt disable missing around generic xdp
From: David Miller @ 2017-08-18 23:04 UTC (permalink / raw)
To: john.fastabend; +Cc: daniel, netdev
In-Reply-To: <20170816183319.7709.87749.stgit@john-Precision-Tower-5810>
From: John Fastabend <john.fastabend@gmail.com>
Date: Wed, 16 Aug 2017 11:33:19 -0700
> do_xdp_generic must be called inside rcu critical section with preempt
> disabled to ensure BPF programs are valid and per-cpu variables used
> for redirect operations are consistent. This patch ensures this is true
> and fixes the splat below.
>
> The netif_receive_skb_internal() code path is now broken into two rcu
> critical sections. I decided it was better to limit the preempt_enable/disable
> block to just the xdp static key portion and the fallout is more
> rcu_read_lock/unlock calls. Seems like the best option to me.
...
> Fixes: d445516966dc ("net: xdp: support xdp generic on virtual devices")
> Fixes: b5cdae3291f7 ("net: Generic XDP")
> Signed-off-by: John Fastabend <john.fastabend@gmail.com>
John you'll need to respin this as these code blocks have changed.
^ permalink raw reply
* Re: [PATCH net] ipv6: reset fn->rr_ptr when replacing route
From: David Miller @ 2017-08-18 23:04 UTC (permalink / raw)
To: weiwan; +Cc: netdev, edumazet
In-Reply-To: <20170816181809.37073-1-tracywwnj@gmail.com>
From: Wei Wang <weiwan@google.com>
Date: Wed, 16 Aug 2017 11:18:09 -0700
> From: Wei Wang <weiwan@google.com>
>
> syzcaller reported the following use-after-free issue in rt6_select():
...
> The root cause of it is that in fib6_add_rt2node(), when it replaces an
> existing route with the new one, it does not update fn->rr_ptr.
> This commit resets fn->rr_ptr to NULL when it points to a route which is
> replaced in fib6_add_rt2node().
>
> Fixes: 27596472473a ("ipv6: fix ECMP route replacement")
> Signed-off-by: Wei Wang <weiwan@google.com>
> Acked-by: Eric Dumazet <edumazet@google.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* Re: [PATCH v3] sctp: fully initialize the IPv6 address in sctp_v6_to_addr()
From: David Miller @ 2017-08-18 23:01 UTC (permalink / raw)
To: glider
Cc: dvyukov, kcc, edumazet, marcelo.leitner, lucien.xin, vyasevich,
hideaki.yoshifuji, linux-kernel, linux-sctp, netdev
In-Reply-To: <20170816181640.40170-1-glider@google.com>
From: Alexander Potapenko <glider@google.com>
Date: Wed, 16 Aug 2017 20:16:40 +0200
> KMSAN reported use of uninitialized sctp_addr->v4.sin_addr.s_addr and
> sctp_addr->v6.sin6_scope_id in sctp_v6_cmp_addr() (see below).
> Make sure all fields of an IPv6 address are initialized, which
> guarantees that the IPv4 fields are also initialized.
...
> Signed-off-by: Alexander Potapenko <glider@google.com>
> Reviewed-by: Xin Long <lucien.xin@gmail.com>
> Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* Re: [PATCH net] tipc: fix use-after-free
From: David Miller @ 2017-08-18 23:00 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, jon.maloy, ying.xue
In-Reply-To: <1502901714.4936.126.camel@edumazet-glaptop3.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 16 Aug 2017 09:41:54 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> syszkaller reported use-after-free in tipc [1]
>
> When msg->rep skb is freed, set the pointer to NULL,
> so that caller does not free it again.
...
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
Applied and queued up for -stable, thanks Eric.
^ permalink raw reply
* Re: [RFC] about net: Fix inconsistent teardown and release of private netdev state.
From: David Miller @ 2017-08-18 22:58 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1503062029.4936.173.camel@edumazet-glaptop3.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 18 Aug 2017 06:13:49 -0700
> On Thu, 2017-08-17 at 22:21 -0700, David Miller wrote:
>> From: Eric Dumazet <eric.dumazet@gmail.com>
>> Date: Thu, 17 Aug 2017 15:30:40 -0700
>>
>> > So we do not really know if we need to clean up or not.
>>
>> We always know, the answer is that whenever register_netdev() fails we
>> never need to perform any cleanup which is done by priv_destructor.
>>
>> > Any idea how to fix the issue ?
>>
>> Your patch is exactly how we should fix this, but without the comment.
>> The logic is straightforward.
>>
>> If register_netdevice() fails any resources handled by priv_destructor
>> are cleaned up, it is guaranteed.
>
> Not in current code.
>
> There are some failures which do a "goto out;"
>
> out:
> return ret;
>
>
> In these cases, priv_destructor is not called.
>
> So we need multiple fixes I think :/
I don't think so.
The cases that "goto out;" in register_netdevce() are those that
execute before ->ndo_init() succeeds.
Only if ->ndo_succeeds() runs successfully should ->priv_destructor()
need execute.
So everything is fine as far as I can see.
^ permalink raw reply
* [PATCH net-next 12/12] nfp: don't reuse pointers in ring dumping
From: Jakub Kicinski @ 2017-08-18 22:48 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
In-Reply-To: <20170818224822.8409-1-jakub.kicinski@netronome.com>
We were reusing skb pointer when reading page frag, since ring
entries contain a union of a skb and frag pointer. This can
be confusing to people reading the code. Refactor the code
to read frag pointer directly.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c b/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c
index 40217ece5fcb..cf81cf95d1d8 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_debugfs.c
@@ -125,7 +125,6 @@ static int nfp_net_debugfs_tx_q_read(struct seq_file *file, void *data)
struct nfp_net_tx_ring *tx_ring;
struct nfp_net_tx_desc *txd;
int d_rd_p, d_wr_p, txd_cnt;
- struct sk_buff *skb;
struct nfp_net *nn;
int i;
@@ -158,13 +157,15 @@ static int nfp_net_debugfs_tx_q_read(struct seq_file *file, void *data)
txd->vals[0], txd->vals[1],
txd->vals[2], txd->vals[3]);
- skb = READ_ONCE(tx_ring->txbufs[i].skb);
- if (skb) {
- if (tx_ring == r_vec->tx_ring)
+ if (tx_ring == r_vec->tx_ring) {
+ struct sk_buff *skb = READ_ONCE(tx_ring->txbufs[i].skb);
+
+ if (skb)
seq_printf(file, " skb->head=%p skb->data=%p",
skb->head, skb->data);
- else
- seq_printf(file, " frag=%p", skb);
+ } else {
+ seq_printf(file, " frag=%p",
+ READ_ONCE(tx_ring->txbufs[i].frag));
}
if (tx_ring->txbufs[i].dma_addr)
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 11/12] nfp: fix copy paste in names and messages regarding vNICs
From: Jakub Kicinski @ 2017-08-18 22:48 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
In-Reply-To: <20170818224822.8409-1-jakub.kicinski@netronome.com>
Data and control vNICs currently use the same area name and
error message. This could lead to confusion. Make sure
the error message says "ctrl" in case of control and the
data area is called "nfp.bar0".
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
drivers/net/ethernet/netronome/nfp/nfp_net_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
index d5e2361f0e86..acdad6f20251 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
@@ -388,7 +388,7 @@ nfp_net_pf_app_init(struct nfp_pf *pf, u8 __iomem *qc_bar, unsigned int stride)
NFP_PF_CSR_SLICE_SIZE,
&pf->ctrl_vnic_bar);
if (IS_ERR(ctrl_bar)) {
- nfp_err(pf->cpp, "Failed to find data vNIC memory symbol\n");
+ nfp_err(pf->cpp, "Failed to find ctrl vNIC memory symbol\n");
err = PTR_ERR(ctrl_bar);
goto err_app_clean;
}
@@ -504,7 +504,7 @@ static int nfp_net_pci_map_mem(struct nfp_pf *pf)
int err;
min_size = pf->max_data_vnics * NFP_PF_CSR_SLICE_SIZE;
- mem = nfp_net_pf_map_rtsym(pf, "net.ctrl", "_pf%d_net_bar0",
+ mem = nfp_net_pf_map_rtsym(pf, "net.bar0", "_pf%d_net_bar0",
min_size, &pf->data_vnic_bar);
if (IS_ERR(mem)) {
nfp_err(pf->cpp, "Failed to find data vNIC memory symbol\n");
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 10/12] nfp: add ethtool statistics for representors
From: Jakub Kicinski @ 2017-08-18 22:48 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
In-Reply-To: <20170818224822.8409-1-jakub.kicinski@netronome.com>
Representors may be associated with both VFs or more importantly
with physical ports. Allow vNIC and MAC statistics to be read
with ethtool -S on representors. In case of vNICs we reuse
the vNIC statistic helper, we just need to swap RX and TX to
give statistics the "switch perspective."
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
.../net/ethernet/netronome/nfp/nfp_net_ethtool.c | 70 ++++++++++++++++++++--
drivers/net/ethernet/netronome/nfp/nfp_port.h | 5 ++
2 files changed, 71 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index f33c341844be..07969f06df10 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -180,6 +180,7 @@ static const struct nfp_et_stat nfp_mac_et_stats[] = {
};
#define NN_ET_GLOBAL_STATS_LEN ARRAY_SIZE(nfp_net_et_stats)
+#define NN_ET_SWITCH_STATS_LEN 9
#define NN_ET_RVEC_GATHER_STATS 7
static void nfp_net_get_nspinfo(struct nfp_app *app, char *version)
@@ -497,11 +498,24 @@ nfp_vnic_get_hw_stats_count(unsigned int rx_rings, unsigned int tx_rings)
static u8 *
nfp_vnic_get_hw_stats_strings(u8 *data, unsigned int rx_rings,
- unsigned int tx_rings)
+ unsigned int tx_rings, bool repr)
{
- int i;
+ int swap_off, i;
- for (i = 0; i < NN_ET_GLOBAL_STATS_LEN; i++)
+ BUILD_BUG_ON(NN_ET_GLOBAL_STATS_LEN < NN_ET_SWITCH_STATS_LEN * 2);
+ /* If repr is true first add SWITCH_STATS_LEN and then subtract it
+ * effectively swapping the RX and TX statistics (giving us the RX
+ * and TX from perspective of the switch).
+ */
+ swap_off = repr * NN_ET_SWITCH_STATS_LEN;
+
+ for (i = 0; i < NN_ET_SWITCH_STATS_LEN; i++)
+ data = nfp_pr_et(data, nfp_net_et_stats[i + swap_off].name);
+
+ for (i = NN_ET_SWITCH_STATS_LEN; i < NN_ET_SWITCH_STATS_LEN * 2; i++)
+ data = nfp_pr_et(data, nfp_net_et_stats[i - swap_off].name);
+
+ for (i = NN_ET_SWITCH_STATS_LEN * 2; i < NN_ET_GLOBAL_STATS_LEN; i++)
data = nfp_pr_et(data, nfp_net_et_stats[i].name);
for (i = 0; i < tx_rings; i++) {
@@ -589,7 +603,8 @@ static void nfp_net_get_strings(struct net_device *netdev,
case ETH_SS_STATS:
data = nfp_vnic_get_sw_stats_strings(netdev, data);
data = nfp_vnic_get_hw_stats_strings(data, nn->dp.num_rx_rings,
- nn->dp.num_tx_rings);
+ nn->dp.num_tx_rings,
+ false);
data = nfp_mac_get_stats_strings(netdev, data);
break;
}
@@ -622,6 +637,50 @@ static int nfp_net_get_sset_count(struct net_device *netdev, int sset)
}
}
+static void nfp_port_get_strings(struct net_device *netdev,
+ u32 stringset, u8 *data)
+{
+ struct nfp_port *port = nfp_port_from_netdev(netdev);
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ if (nfp_port_is_vnic(port))
+ data = nfp_vnic_get_hw_stats_strings(data, 0, 0, true);
+ else
+ data = nfp_mac_get_stats_strings(netdev, data);
+ break;
+ }
+}
+
+static void
+nfp_port_get_stats(struct net_device *netdev, struct ethtool_stats *stats,
+ u64 *data)
+{
+ struct nfp_port *port = nfp_port_from_netdev(netdev);
+
+ if (nfp_port_is_vnic(port))
+ data = nfp_vnic_get_hw_stats(data, port->vnic, 0, 0);
+ else
+ data = nfp_mac_get_stats(netdev, data);
+}
+
+static int nfp_port_get_sset_count(struct net_device *netdev, int sset)
+{
+ struct nfp_port *port = nfp_port_from_netdev(netdev);
+ unsigned int count;
+
+ switch (sset) {
+ case ETH_SS_STATS:
+ if (nfp_port_is_vnic(port))
+ count = nfp_vnic_get_hw_stats_count(0, 0);
+ else
+ count = nfp_mac_get_stats_count(netdev);
+ return count;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
/* RX network flow classification (RSS, filters, etc)
*/
static u32 ethtool_flow_to_nfp_flag(u32 flow_type)
@@ -1085,6 +1144,9 @@ static const struct ethtool_ops nfp_net_ethtool_ops = {
const struct ethtool_ops nfp_port_ethtool_ops = {
.get_drvinfo = nfp_app_get_drvinfo,
.get_link = ethtool_op_get_link,
+ .get_strings = nfp_port_get_strings,
+ .get_ethtool_stats = nfp_port_get_stats,
+ .get_sset_count = nfp_port_get_sset_count,
.set_dump = nfp_app_set_dump,
.get_dump_flag = nfp_app_get_dump_flag,
.get_dump_data = nfp_app_get_dump_data,
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.h b/drivers/net/ethernet/netronome/nfp/nfp_port.h
index 81c034018133..51dcb9c603ee 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_port.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_port.h
@@ -116,6 +116,11 @@ extern const struct switchdev_ops nfp_port_switchdev_ops;
int nfp_port_setup_tc(struct net_device *netdev, enum tc_setup_type type,
void *type_data);
+static inline bool nfp_port_is_vnic(const struct nfp_port *port)
+{
+ return port->type == NFP_PORT_PF_PORT || port->type == NFP_PORT_VF_PORT;
+}
+
struct nfp_port *nfp_port_from_netdev(struct net_device *netdev);
struct nfp_port *
nfp_port_from_id(struct nfp_pf *pf, enum nfp_port_type type, unsigned int id);
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 09/12] nfp: add pointer to vNIC config memory to nfp_port structure
From: Jakub Kicinski @ 2017-08-18 22:48 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
In-Reply-To: <20170818224822.8409-1-jakub.kicinski@netronome.com>
Simplify the statistics handling code by keeping pointer to vNIC's
config memory in nfp_port. Note that this is referring to the
representor side of vNICs, vNIC side has the pointer in nfp_net.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
drivers/net/ethernet/netronome/nfp/flower/main.c | 8 +++-
drivers/net/ethernet/netronome/nfp/nfp_net_repr.c | 45 +++++------------------
drivers/net/ethernet/netronome/nfp/nfp_port.h | 2 +
3 files changed, 18 insertions(+), 37 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c
index 3088e959f2a3..126a6b5233bf 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.c
@@ -159,12 +159,18 @@ nfp_flower_spawn_vnic_reprs(struct nfp_app *app,
goto err_reprs_clean;
}
+ /* For now we only support 1 PF */
+ WARN_ON(repr_type == NFP_REPR_TYPE_PF && i);
+
port = nfp_port_alloc(app, port_type, reprs->reprs[i]);
if (repr_type == NFP_REPR_TYPE_PF) {
port->pf_id = i;
+ port->vnic = priv->nn->dp.ctrl_bar;
} else {
- port->pf_id = 0; /* For now we only support 1 PF */
+ port->pf_id = 0;
port->vf_id = i;
+ port->vnic =
+ app->pf->vf_cfg_mem + i * NFP_NET_CFG_BAR_SZ;
}
eth_hw_addr_random(reprs->reprs[i]);
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
index 28e932eab812..0f9878d1bf40 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
@@ -96,50 +96,25 @@ nfp_repr_phy_port_get_stats64(struct nfp_port *port,
}
static void
-nfp_repr_vf_get_stats64(const struct nfp_app *app, u8 vf,
- struct rtnl_link_stats64 *stats)
+nfp_repr_vnic_get_stats64(struct nfp_port *port,
+ struct rtnl_link_stats64 *stats)
{
- u8 __iomem *mem;
-
- mem = app->pf->vf_cfg_mem + vf * NFP_NET_CFG_BAR_SZ;
-
/* TX and RX stats are flipped as we are returning the stats as seen
* at the switch port corresponding to the VF.
*/
- stats->tx_packets = readq(mem + NFP_NET_CFG_STATS_RX_FRAMES);
- stats->tx_bytes = readq(mem + NFP_NET_CFG_STATS_RX_OCTETS);
- stats->tx_dropped = readq(mem + NFP_NET_CFG_STATS_RX_DISCARDS);
+ stats->tx_packets = readq(port->vnic + NFP_NET_CFG_STATS_RX_FRAMES);
+ stats->tx_bytes = readq(port->vnic + NFP_NET_CFG_STATS_RX_OCTETS);
+ stats->tx_dropped = readq(port->vnic + NFP_NET_CFG_STATS_RX_DISCARDS);
- stats->rx_packets = readq(mem + NFP_NET_CFG_STATS_TX_FRAMES);
- stats->rx_bytes = readq(mem + NFP_NET_CFG_STATS_TX_OCTETS);
- stats->rx_dropped = readq(mem + NFP_NET_CFG_STATS_TX_DISCARDS);
-}
-
-static void
-nfp_repr_pf_get_stats64(const struct nfp_app *app, u8 pf,
- struct rtnl_link_stats64 *stats)
-{
- u8 __iomem *mem;
-
- if (pf)
- return;
-
- mem = nfp_cpp_area_iomem(app->pf->data_vnic_bar);
-
- stats->tx_packets = readq(mem + NFP_NET_CFG_STATS_RX_FRAMES);
- stats->tx_bytes = readq(mem + NFP_NET_CFG_STATS_RX_OCTETS);
- stats->tx_dropped = readq(mem + NFP_NET_CFG_STATS_RX_DISCARDS);
-
- stats->rx_packets = readq(mem + NFP_NET_CFG_STATS_TX_FRAMES);
- stats->rx_bytes = readq(mem + NFP_NET_CFG_STATS_TX_OCTETS);
- stats->rx_dropped = readq(mem + NFP_NET_CFG_STATS_TX_DISCARDS);
+ stats->rx_packets = readq(port->vnic + NFP_NET_CFG_STATS_TX_FRAMES);
+ stats->rx_bytes = readq(port->vnic + NFP_NET_CFG_STATS_TX_OCTETS);
+ stats->rx_dropped = readq(port->vnic + NFP_NET_CFG_STATS_TX_DISCARDS);
}
static void
nfp_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
{
struct nfp_repr *repr = netdev_priv(netdev);
- struct nfp_app *app = repr->app;
if (WARN_ON(!repr->port))
return;
@@ -151,10 +126,8 @@ nfp_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
nfp_repr_phy_port_get_stats64(repr->port, stats);
break;
case NFP_PORT_PF_PORT:
- nfp_repr_pf_get_stats64(app, repr->port->pf_id, stats);
- break;
case NFP_PORT_VF_PORT:
- nfp_repr_vf_get_stats64(app, repr->port->vf_id, stats);
+ nfp_repr_vnic_get_stats64(repr->port, stats);
default:
break;
}
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.h b/drivers/net/ethernet/netronome/nfp/nfp_port.h
index de8ec609b57e..81c034018133 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_port.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_port.h
@@ -79,6 +79,7 @@ enum nfp_port_flags {
* @eth_stats: for %NFP_PORT_PHYS_PORT MAC stats if available
* @pf_id: for %NFP_PORT_PF_PORT, %NFP_PORT_VF_PORT ID of the PCI PF (0-3)
* @vf_id: for %NFP_PORT_VF_PORT ID of the PCI VF within @pf_id
+ * @vnic: for %NFP_PORT_PF_PORT, %NFP_PORT_VF_PORT vNIC ctrl memory
* @port_list: entry on pf's list of ports
*/
struct nfp_port {
@@ -102,6 +103,7 @@ struct nfp_port {
struct {
unsigned int pf_id;
unsigned int vf_id;
+ u8 __iomem *vnic;
};
};
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 08/12] nfp: report MAC statistics in ethtool
From: Jakub Kicinski @ 2017-08-18 22:48 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
In-Reply-To: <20170818224822.8409-1-jakub.kicinski@netronome.com>
Add reporting of MAC statistics in ethtool. MAC statistics
are read out from the MAC IP and accumulated by application
FW, therefore their presence depends on the application FW.
Add missing defines and string names for the statistics and
dump them in ethtool -S.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
.../net/ethernet/netronome/nfp/nfp_net_ethtool.c | 126 ++++++++++++++++++++-
drivers/net/ethernet/netronome/nfp/nfp_port.h | 44 ++++---
2 files changed, 153 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index 169f3e3714fd..f33c341844be 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -99,6 +99,86 @@ static const struct nfp_et_stat nfp_net_et_stats[] = {
{ "bpf_app3_bytes", NFP_NET_CFG_STATS_APP3_BYTES },
};
+static const struct nfp_et_stat nfp_mac_et_stats[] = {
+ { "rx_octets", NFP_MAC_STATS_RX_IN_OCTETS, },
+ { "rx_frame_too_long_errors",
+ NFP_MAC_STATS_RX_FRAME_TOO_LONG_ERRORS, },
+ { "rx_range_length_errors", NFP_MAC_STATS_RX_RANGE_LENGTH_ERRORS, },
+ { "rx_vlan_reveive_ok", NFP_MAC_STATS_RX_VLAN_REVEIVE_OK, },
+ { "rx_errors", NFP_MAC_STATS_RX_IN_ERRORS, },
+ { "rx_broadcast_pkts", NFP_MAC_STATS_RX_IN_BROADCAST_PKTS, },
+ { "rx_drop_events", NFP_MAC_STATS_RX_DROP_EVENTS, },
+ { "rx_alignment_errors", NFP_MAC_STATS_RX_ALIGNMENT_ERRORS, },
+ { "rx_pause_mac_ctrl_frames",
+ NFP_MAC_STATS_RX_PAUSE_MAC_CTRL_FRAMES, },
+ { "rx_frames_received_ok", NFP_MAC_STATS_RX_FRAMES_RECEIVED_OK, },
+ { "rx_frame_check_sequence_errors",
+ NFP_MAC_STATS_RX_FRAME_CHECK_SEQUENCE_ERRORS, },
+ { "rx_unicast_pkts", NFP_MAC_STATS_RX_UNICAST_PKTS, },
+ { "rx_multicast_pkts", NFP_MAC_STATS_RX_MULTICAST_PKTS, },
+ { "rx_pkts", NFP_MAC_STATS_RX_PKTS, },
+ { "rx_undersize_pkts", NFP_MAC_STATS_RX_UNDERSIZE_PKTS, },
+ { "rx_pkts_64_octets", NFP_MAC_STATS_RX_PKTS_64_OCTETS, },
+ { "rx_pkts_65_to_127_octets",
+ NFP_MAC_STATS_RX_PKTS_65_TO_127_OCTETS, },
+ { "rx_pkts_128_to_255_octets",
+ NFP_MAC_STATS_RX_PKTS_128_TO_255_OCTETS, },
+ { "rx_pkts_256_to_511_octets",
+ NFP_MAC_STATS_RX_PKTS_256_TO_511_OCTETS, },
+ { "rx_pkts_512_to_1023_octets",
+ NFP_MAC_STATS_RX_PKTS_512_TO_1023_OCTETS, },
+ { "rx_pkts_1024_to_1518_octets",
+ NFP_MAC_STATS_RX_PKTS_1024_TO_1518_OCTETS, },
+ { "rx_pkts_1519_to_max_octets",
+ NFP_MAC_STATS_RX_PKTS_1519_TO_MAX_OCTETS, },
+ { "rx_jabbers", NFP_MAC_STATS_RX_JABBERS, },
+ { "rx_fragments", NFP_MAC_STATS_RX_FRAGMENTS, },
+ { "rx_oversize_pkts", NFP_MAC_STATS_RX_OVERSIZE_PKTS, },
+ { "rx_pause_frames_class0", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS0, },
+ { "rx_pause_frames_class1", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS1, },
+ { "rx_pause_frames_class2", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS2, },
+ { "rx_pause_frames_class3", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS3, },
+ { "rx_pause_frames_class4", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS4, },
+ { "rx_pause_frames_class5", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS5, },
+ { "rx_pause_frames_class6", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS6, },
+ { "rx_pause_frames_class7", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS7, },
+ { "rx_mac_ctrl_frames_received",
+ NFP_MAC_STATS_RX_MAC_CTRL_FRAMES_RECEIVED, },
+ { "rx_mac_head_drop", NFP_MAC_STATS_RX_MAC_HEAD_DROP, },
+ { "tx_queue_drop", NFP_MAC_STATS_TX_QUEUE_DROP, },
+ { "tx_octets", NFP_MAC_STATS_TX_OUT_OCTETS, },
+ { "tx_vlan_transmitted_ok", NFP_MAC_STATS_TX_VLAN_TRANSMITTED_OK, },
+ { "tx_errors", NFP_MAC_STATS_TX_OUT_ERRORS, },
+ { "tx_broadcast_pkts", NFP_MAC_STATS_TX_BROADCAST_PKTS, },
+ { "tx_pause_mac_ctrl_frames",
+ NFP_MAC_STATS_TX_PAUSE_MAC_CTRL_FRAMES, },
+ { "tx_frames_transmitted_ok",
+ NFP_MAC_STATS_TX_FRAMES_TRANSMITTED_OK, },
+ { "tx_unicast_pkts", NFP_MAC_STATS_TX_UNICAST_PKTS, },
+ { "tx_multicast_pkts", NFP_MAC_STATS_TX_MULTICAST_PKTS, },
+ { "tx_pkts_64_octets", NFP_MAC_STATS_TX_PKTS_64_OCTETS, },
+ { "tx_pkts_65_to_127_octets",
+ NFP_MAC_STATS_TX_PKTS_65_TO_127_OCTETS, },
+ { "tx_pkts_128_to_255_octets",
+ NFP_MAC_STATS_TX_PKTS_128_TO_255_OCTETS, },
+ { "tx_pkts_256_to_511_octets",
+ NFP_MAC_STATS_TX_PKTS_256_TO_511_OCTETS, },
+ { "tx_pkts_512_to_1023_octets",
+ NFP_MAC_STATS_TX_PKTS_512_TO_1023_OCTETS, },
+ { "tx_pkts_1024_to_1518_octets",
+ NFP_MAC_STATS_TX_PKTS_1024_TO_1518_OCTETS, },
+ { "tx_pkts_1519_to_max_octets",
+ NFP_MAC_STATS_TX_PKTS_1519_TO_MAX_OCTETS, },
+ { "tx_pause_frames_class0", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS0, },
+ { "tx_pause_frames_class1", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS1, },
+ { "tx_pause_frames_class2", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS2, },
+ { "tx_pause_frames_class3", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS3, },
+ { "tx_pause_frames_class4", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS4, },
+ { "tx_pause_frames_class5", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS5, },
+ { "tx_pause_frames_class6", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS6, },
+ { "tx_pause_frames_class7", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS7, },
+};
+
#define NN_ET_GLOBAL_STATS_LEN ARRAY_SIZE(nfp_net_et_stats)
#define NN_ET_RVEC_GATHER_STATS 7
@@ -459,6 +539,47 @@ nfp_vnic_get_hw_stats(u64 *data, u8 __iomem *mem,
return data;
}
+static unsigned int nfp_mac_get_stats_count(struct net_device *netdev)
+{
+ struct nfp_port *port;
+
+ port = nfp_port_from_netdev(netdev);
+ if (!__nfp_port_get_eth_port(port) || !port->eth_stats)
+ return 0;
+
+ return ARRAY_SIZE(nfp_mac_et_stats);
+}
+
+static u8 *nfp_mac_get_stats_strings(struct net_device *netdev, u8 *data)
+{
+ struct nfp_port *port;
+ unsigned int i;
+
+ port = nfp_port_from_netdev(netdev);
+ if (!__nfp_port_get_eth_port(port) || !port->eth_stats)
+ return data;
+
+ for (i = 0; i < ARRAY_SIZE(nfp_mac_et_stats); i++)
+ data = nfp_pr_et(data, "mac.%s", nfp_mac_et_stats[i].name);
+
+ return data;
+}
+
+static u64 *nfp_mac_get_stats(struct net_device *netdev, u64 *data)
+{
+ struct nfp_port *port;
+ unsigned int i;
+
+ port = nfp_port_from_netdev(netdev);
+ if (!__nfp_port_get_eth_port(port) || !port->eth_stats)
+ return data;
+
+ for (i = 0; i < ARRAY_SIZE(nfp_mac_et_stats); i++)
+ *data++ = readq(port->eth_stats + nfp_mac_et_stats[i].off);
+
+ return data;
+}
+
static void nfp_net_get_strings(struct net_device *netdev,
u32 stringset, u8 *data)
{
@@ -469,6 +590,7 @@ static void nfp_net_get_strings(struct net_device *netdev,
data = nfp_vnic_get_sw_stats_strings(netdev, data);
data = nfp_vnic_get_hw_stats_strings(data, nn->dp.num_rx_rings,
nn->dp.num_tx_rings);
+ data = nfp_mac_get_stats_strings(netdev, data);
break;
}
}
@@ -482,6 +604,7 @@ nfp_net_get_stats(struct net_device *netdev, struct ethtool_stats *stats,
data = nfp_vnic_get_sw_stats(netdev, data);
data = nfp_vnic_get_hw_stats(data, nn->dp.ctrl_bar,
nn->dp.num_rx_rings, nn->dp.num_tx_rings);
+ data = nfp_mac_get_stats(netdev, data);
}
static int nfp_net_get_sset_count(struct net_device *netdev, int sset)
@@ -492,7 +615,8 @@ static int nfp_net_get_sset_count(struct net_device *netdev, int sset)
case ETH_SS_STATS:
return nfp_vnic_get_sw_stats_count(netdev) +
nfp_vnic_get_hw_stats_count(nn->dp.num_rx_rings,
- nn->dp.num_tx_rings);
+ nn->dp.num_tx_rings) +
+ nfp_mac_get_stats_count(netdev);
default:
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.h b/drivers/net/ethernet/netronome/nfp/nfp_port.h
index cf71ac065e85..de8ec609b57e 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_port.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_port.h
@@ -147,31 +147,32 @@ void nfp_devlink_port_unregister(struct nfp_port *port);
#define NFP_MAC_STATS_SIZE 0x0200
#define NFP_MAC_STATS_RX_IN_OCTETS (NFP_MAC_STATS_BASE + 0x000)
+ /* unused 0x008 */
#define NFP_MAC_STATS_RX_FRAME_TOO_LONG_ERRORS (NFP_MAC_STATS_BASE + 0x010)
#define NFP_MAC_STATS_RX_RANGE_LENGTH_ERRORS (NFP_MAC_STATS_BASE + 0x018)
#define NFP_MAC_STATS_RX_VLAN_REVEIVE_OK (NFP_MAC_STATS_BASE + 0x020)
#define NFP_MAC_STATS_RX_IN_ERRORS (NFP_MAC_STATS_BASE + 0x028)
#define NFP_MAC_STATS_RX_IN_BROADCAST_PKTS (NFP_MAC_STATS_BASE + 0x030)
-#define NFP_MAC_STATS_RX_STATS_DROP_EVENTS (NFP_MAC_STATS_BASE + 0x038)
+#define NFP_MAC_STATS_RX_DROP_EVENTS (NFP_MAC_STATS_BASE + 0x038)
#define NFP_MAC_STATS_RX_ALIGNMENT_ERRORS (NFP_MAC_STATS_BASE + 0x040)
#define NFP_MAC_STATS_RX_PAUSE_MAC_CTRL_FRAMES (NFP_MAC_STATS_BASE + 0x048)
#define NFP_MAC_STATS_RX_FRAMES_RECEIVED_OK (NFP_MAC_STATS_BASE + 0x050)
#define NFP_MAC_STATS_RX_FRAME_CHECK_SEQUENCE_ERRORS (NFP_MAC_STATS_BASE + 0x058)
#define NFP_MAC_STATS_RX_UNICAST_PKTS (NFP_MAC_STATS_BASE + 0x060)
#define NFP_MAC_STATS_RX_MULTICAST_PKTS (NFP_MAC_STATS_BASE + 0x068)
-#define NFP_MAC_STATS_RX_STATS_PKTS (NFP_MAC_STATS_BASE + 0x070)
-#define NFP_MAC_STATS_RX_STATS_UNDERSIZE_PKTS (NFP_MAC_STATS_BASE + 0x078)
-#define NFP_MAC_STATS_RX_STATS_PKTS_64_OCTETS (NFP_MAC_STATS_BASE + 0x080)
-#define NFP_MAC_STATS_RX_STATS_PKTS_65_TO_127_OCTETS (NFP_MAC_STATS_BASE + 0x088)
-#define NFP_MAC_STATS_RX_STATS_PKTS_512_TO_1023_OCTETS (NFP_MAC_STATS_BASE + 0x090)
-#define NFP_MAC_STATS_RX_STATS_PKTS_1024_TO_1518_OCTETS (NFP_MAC_STATS_BASE + 0x098)
-#define NFP_MAC_STATS_RX_STATS_JABBERS (NFP_MAC_STATS_BASE + 0x0a0)
-#define NFP_MAC_STATS_RX_STATS_FRAGMENTS (NFP_MAC_STATS_BASE + 0x0a8)
+#define NFP_MAC_STATS_RX_PKTS (NFP_MAC_STATS_BASE + 0x070)
+#define NFP_MAC_STATS_RX_UNDERSIZE_PKTS (NFP_MAC_STATS_BASE + 0x078)
+#define NFP_MAC_STATS_RX_PKTS_64_OCTETS (NFP_MAC_STATS_BASE + 0x080)
+#define NFP_MAC_STATS_RX_PKTS_65_TO_127_OCTETS (NFP_MAC_STATS_BASE + 0x088)
+#define NFP_MAC_STATS_RX_PKTS_512_TO_1023_OCTETS (NFP_MAC_STATS_BASE + 0x090)
+#define NFP_MAC_STATS_RX_PKTS_1024_TO_1518_OCTETS (NFP_MAC_STATS_BASE + 0x098)
+#define NFP_MAC_STATS_RX_JABBERS (NFP_MAC_STATS_BASE + 0x0a0)
+#define NFP_MAC_STATS_RX_FRAGMENTS (NFP_MAC_STATS_BASE + 0x0a8)
#define NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS2 (NFP_MAC_STATS_BASE + 0x0b0)
#define NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS3 (NFP_MAC_STATS_BASE + 0x0b8)
-#define NFP_MAC_STATS_RX_STATS_PKTS_128_TO_255_OCTETS (NFP_MAC_STATS_BASE + 0x0c0)
-#define NFP_MAC_STATS_RX_STATS_PKTS_256_TO_511_OCTETS (NFP_MAC_STATS_BASE + 0x0c8)
-#define NFP_MAC_STATS_RX_STATS_PKTS_1519_TO_MAX_OCTETS (NFP_MAC_STATS_BASE + 0x0d0)
+#define NFP_MAC_STATS_RX_PKTS_128_TO_255_OCTETS (NFP_MAC_STATS_BASE + 0x0c0)
+#define NFP_MAC_STATS_RX_PKTS_256_TO_511_OCTETS (NFP_MAC_STATS_BASE + 0x0c8)
+#define NFP_MAC_STATS_RX_PKTS_1519_TO_MAX_OCTETS (NFP_MAC_STATS_BASE + 0x0d0)
#define NFP_MAC_STATS_RX_OVERSIZE_PKTS (NFP_MAC_STATS_BASE + 0x0d8)
#define NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS0 (NFP_MAC_STATS_BASE + 0x0e0)
#define NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS1 (NFP_MAC_STATS_BASE + 0x0e8)
@@ -181,9 +182,12 @@ void nfp_devlink_port_unregister(struct nfp_port *port);
#define NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS7 (NFP_MAC_STATS_BASE + 0x108)
#define NFP_MAC_STATS_RX_MAC_CTRL_FRAMES_RECEIVED (NFP_MAC_STATS_BASE + 0x110)
#define NFP_MAC_STATS_RX_MAC_HEAD_DROP (NFP_MAC_STATS_BASE + 0x118)
-
+ /* unused 0x120 */
+ /* unused 0x128 */
+ /* unused 0x130 */
#define NFP_MAC_STATS_TX_QUEUE_DROP (NFP_MAC_STATS_BASE + 0x138)
#define NFP_MAC_STATS_TX_OUT_OCTETS (NFP_MAC_STATS_BASE + 0x140)
+ /* unused 0x148 */
#define NFP_MAC_STATS_TX_VLAN_TRANSMITTED_OK (NFP_MAC_STATS_BASE + 0x150)
#define NFP_MAC_STATS_TX_OUT_ERRORS (NFP_MAC_STATS_BASE + 0x158)
#define NFP_MAC_STATS_TX_BROADCAST_PKTS (NFP_MAC_STATS_BASE + 0x160)
@@ -195,8 +199,16 @@ void nfp_devlink_port_unregister(struct nfp_port *port);
#define NFP_MAC_STATS_TX_UNICAST_PKTS (NFP_MAC_STATS_BASE + 0x190)
#define NFP_MAC_STATS_TX_MULTICAST_PKTS (NFP_MAC_STATS_BASE + 0x198)
#define NFP_MAC_STATS_TX_PKTS_65_TO_127_OCTETS (NFP_MAC_STATS_BASE + 0x1a0)
-#define NFP_MAC_STATS_TX_PKTS_127_TO_512_OCTETS (NFP_MAC_STATS_BASE + 0x1a8)
-#define NFP_MAC_STATS_TX_PKTS_128_TO_1518_OCTETS (NFP_MAC_STATS_BASE + 0x1b0)
-#define NFP_MAC_STATS_TX_PKTS_1518_TO_MAX_OCTETS (NFP_MAC_STATS_BASE + 0x1b8)
+#define NFP_MAC_STATS_TX_PKTS_128_TO_255_OCTETS (NFP_MAC_STATS_BASE + 0x1a8)
+#define NFP_MAC_STATS_TX_PKTS_1024_TO_1518_OCTETS (NFP_MAC_STATS_BASE + 0x1b0)
+#define NFP_MAC_STATS_TX_PKTS_1519_TO_MAX_OCTETS (NFP_MAC_STATS_BASE + 0x1b8)
+#define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS0 (NFP_MAC_STATS_BASE + 0x1c0)
+#define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS1 (NFP_MAC_STATS_BASE + 0x1c8)
+#define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS4 (NFP_MAC_STATS_BASE + 0x1d0)
+#define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS5 (NFP_MAC_STATS_BASE + 0x1d8)
+#define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS2 (NFP_MAC_STATS_BASE + 0x1e0)
+#define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS3 (NFP_MAC_STATS_BASE + 0x1e8)
+#define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS6 (NFP_MAC_STATS_BASE + 0x1f0)
+#define NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS7 (NFP_MAC_STATS_BASE + 0x1f8)
#endif
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 07/12] nfp: store pointer to MAC statistics in nfp_port
From: Jakub Kicinski @ 2017-08-18 22:48 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
In-Reply-To: <20170818224822.8409-1-jakub.kicinski@netronome.com>
Store pointer to device memory containing MAC statistics
in nfp_port. This simplifies representor code and will
be used to dump those statistics in ethtool as well.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
drivers/net/ethernet/netronome/nfp/nfp_net_repr.c | 12 ++++--------
drivers/net/ethernet/netronome/nfp/nfp_port.c | 3 +++
drivers/net/ethernet/netronome/nfp/nfp_port.h | 2 ++
3 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
index 50f7cc057cc9..28e932eab812 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
@@ -78,12 +78,10 @@ void nfp_repr_inc_rx_stats(struct net_device *netdev, unsigned int len)
}
static void
-nfp_repr_phy_port_get_stats64(const struct nfp_app *app, u8 phy_port,
+nfp_repr_phy_port_get_stats64(struct nfp_port *port,
struct rtnl_link_stats64 *stats)
{
- u8 __iomem *mem;
-
- mem = app->pf->mac_stats_mem + phy_port * NFP_MAC_STATS_SIZE;
+ u8 __iomem *mem = port->eth_stats;
/* TX and RX stats are flipped as we are returning the stats as seen
* at the switch port corresponding to the phys port.
@@ -141,7 +139,6 @@ static void
nfp_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
{
struct nfp_repr *repr = netdev_priv(netdev);
- struct nfp_eth_table_port *eth_port;
struct nfp_app *app = repr->app;
if (WARN_ON(!repr->port))
@@ -149,10 +146,9 @@ nfp_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
switch (repr->port->type) {
case NFP_PORT_PHYS_PORT:
- eth_port = __nfp_port_get_eth_port(repr->port);
- if (!eth_port)
+ if (!__nfp_port_get_eth_port(repr->port))
break;
- nfp_repr_phy_port_get_stats64(app, eth_port->index, stats);
+ nfp_repr_phy_port_get_stats64(repr->port, stats);
break;
case NFP_PORT_PF_PORT:
nfp_repr_pf_get_stats64(app, repr->port->pf_id, stats);
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.c b/drivers/net/ethernet/netronome/nfp/nfp_port.c
index 0cf65e57addb..34a6e035fe9a 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_port.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_port.c
@@ -225,6 +225,9 @@ int nfp_port_init_phy_port(struct nfp_pf *pf, struct nfp_app *app,
port->eth_port = &pf->eth_tbl->ports[id];
port->eth_id = pf->eth_tbl->ports[id].index;
+ if (pf->mac_stats_mem)
+ port->eth_stats =
+ pf->mac_stats_mem + port->eth_id * NFP_MAC_STATS_SIZE;
return 0;
}
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.h b/drivers/net/ethernet/netronome/nfp/nfp_port.h
index 784d82c2f32c..cf71ac065e85 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_port.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_port.h
@@ -76,6 +76,7 @@ enum nfp_port_flags {
* @dl_port: devlink port structure
* @eth_id: for %NFP_PORT_PHYS_PORT port ID in NFP enumeration scheme
* @eth_port: for %NFP_PORT_PHYS_PORT translated ETH Table port entry
+ * @eth_stats: for %NFP_PORT_PHYS_PORT MAC stats if available
* @pf_id: for %NFP_PORT_PF_PORT, %NFP_PORT_VF_PORT ID of the PCI PF (0-3)
* @vf_id: for %NFP_PORT_VF_PORT ID of the PCI VF within @pf_id
* @port_list: entry on pf's list of ports
@@ -95,6 +96,7 @@ struct nfp_port {
struct {
unsigned int eth_id;
struct nfp_eth_table_port *eth_port;
+ u8 __iomem *eth_stats;
};
/* NFP_PORT_PF_PORT, NFP_PORT_VF_PORT */
struct {
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 06/12] nfp: split software and hardware vNIC statistics
From: Jakub Kicinski @ 2017-08-18 22:48 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
In-Reply-To: <20170818224822.8409-1-jakub.kicinski@netronome.com>
In preparation for reporting vNIC HW stats on representors
split handling of the SW and HW stats in ethtool -S.
Representors don't have SW stats (since vNIC is assigned
to the VM).
Remove the questionable defines which assume nn variable
exists in the scope.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
.../net/ethernet/netronome/nfp/nfp_net_ethtool.c | 192 +++++++++++++--------
1 file changed, 120 insertions(+), 72 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index ba1c28b8791b..169f3e3714fd 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -100,11 +100,7 @@ static const struct nfp_et_stat nfp_net_et_stats[] = {
};
#define NN_ET_GLOBAL_STATS_LEN ARRAY_SIZE(nfp_net_et_stats)
-#define NN_ET_RVEC_STATS_LEN (nn->dp.num_r_vecs * 3)
#define NN_ET_RVEC_GATHER_STATS 7
-#define NN_ET_QUEUE_STATS_LEN ((nn->dp.num_tx_rings + nn->dp.num_rx_rings) * 2)
-#define NN_ET_STATS_LEN (NN_ET_GLOBAL_STATS_LEN + NN_ET_RVEC_GATHER_STATS + \
- NN_ET_RVEC_STATS_LEN + NN_ET_QUEUE_STATS_LEN)
static void nfp_net_get_nspinfo(struct nfp_app *app, char *version)
{
@@ -346,96 +342,146 @@ static __printf(2, 3) u8 *nfp_pr_et(u8 *data, const char *fmt, ...)
return data + ETH_GSTRING_LEN;
}
-static void nfp_net_get_strings(struct net_device *netdev,
- u32 stringset, u8 *data)
+static unsigned int nfp_vnic_get_sw_stats_count(struct net_device *netdev)
{
struct nfp_net *nn = netdev_priv(netdev);
- int i;
- switch (stringset) {
- case ETH_SS_STATS:
- for (i = 0; i < NN_ET_GLOBAL_STATS_LEN; i++)
- data = nfp_pr_et(data, nfp_net_et_stats[i].name);
+ return NN_ET_RVEC_GATHER_STATS + nn->dp.num_r_vecs * 3;
+}
- for (i = 0; i < nn->dp.num_r_vecs; i++) {
- data = nfp_pr_et(data, "rvec_%u_rx_pkts", i);
- data = nfp_pr_et(data, "rvec_%u_tx_pkts", i);
- data = nfp_pr_et(data, "rvec_%u_tx_busy", i);
- }
+static u8 *nfp_vnic_get_sw_stats_strings(struct net_device *netdev, u8 *data)
+{
+ struct nfp_net *nn = netdev_priv(netdev);
+ int i;
- data = nfp_pr_et(data, "hw_rx_csum_ok");
- data = nfp_pr_et(data, "hw_rx_csum_inner_ok");
- data = nfp_pr_et(data, "hw_rx_csum_err");
- data = nfp_pr_et(data, "hw_tx_csum");
- data = nfp_pr_et(data, "hw_tx_inner_csum");
- data = nfp_pr_et(data, "tx_gather");
- data = nfp_pr_et(data, "tx_lso");
-
- for (i = 0; i < nn->dp.num_tx_rings; i++) {
- data = nfp_pr_et(data, "txq_%u_pkts", i);
- data = nfp_pr_et(data, "txq_%u_bytes", i);
- }
+ for (i = 0; i < nn->dp.num_r_vecs; i++) {
+ data = nfp_pr_et(data, "rvec_%u_rx_pkts", i);
+ data = nfp_pr_et(data, "rvec_%u_tx_pkts", i);
+ data = nfp_pr_et(data, "rvec_%u_tx_busy", i);
+ }
- for (i = 0; i < nn->dp.num_rx_rings; i++) {
- data = nfp_pr_et(data, "rxq_%u_pkts", i);
- data = nfp_pr_et(data, "rxq_%u_bytes", i);
- }
+ data = nfp_pr_et(data, "hw_rx_csum_ok");
+ data = nfp_pr_et(data, "hw_rx_csum_inner_ok");
+ data = nfp_pr_et(data, "hw_rx_csum_err");
+ data = nfp_pr_et(data, "hw_tx_csum");
+ data = nfp_pr_et(data, "hw_tx_inner_csum");
+ data = nfp_pr_et(data, "tx_gather");
+ data = nfp_pr_et(data, "tx_lso");
- break;
- }
+ return data;
}
-static void nfp_net_get_stats(struct net_device *netdev,
- struct ethtool_stats *stats, u64 *data)
+static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data)
{
u64 gathered_stats[NN_ET_RVEC_GATHER_STATS] = {};
struct nfp_net *nn = netdev_priv(netdev);
u64 tmp[NN_ET_RVEC_GATHER_STATS];
- u8 __iomem *io_p;
- int i, j, k;
+ unsigned int i, j;
- for (i = 0; i < NN_ET_GLOBAL_STATS_LEN; i++) {
- io_p = nn->dp.ctrl_bar + nfp_net_et_stats[i].off;
- data[i] = readq(io_p);
- }
- for (j = 0; j < nn->dp.num_r_vecs; j++) {
+ for (i = 0; i < nn->dp.num_r_vecs; i++) {
unsigned int start;
do {
- start = u64_stats_fetch_begin(&nn->r_vecs[j].rx_sync);
- data[i++] = nn->r_vecs[j].rx_pkts;
- tmp[0] = nn->r_vecs[j].hw_csum_rx_ok;
- tmp[1] = nn->r_vecs[j].hw_csum_rx_inner_ok;
- tmp[2] = nn->r_vecs[j].hw_csum_rx_error;
- } while (u64_stats_fetch_retry(&nn->r_vecs[j].rx_sync, start));
+ start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync);
+ *data++ = nn->r_vecs[i].rx_pkts;
+ tmp[0] = nn->r_vecs[i].hw_csum_rx_ok;
+ tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok;
+ tmp[2] = nn->r_vecs[i].hw_csum_rx_error;
+ } while (u64_stats_fetch_retry(&nn->r_vecs[i].rx_sync, start));
do {
- start = u64_stats_fetch_begin(&nn->r_vecs[j].tx_sync);
- data[i++] = nn->r_vecs[j].tx_pkts;
- data[i++] = nn->r_vecs[j].tx_busy;
- tmp[3] = nn->r_vecs[j].hw_csum_tx;
- tmp[4] = nn->r_vecs[j].hw_csum_tx_inner;
- tmp[5] = nn->r_vecs[j].tx_gather;
- tmp[6] = nn->r_vecs[j].tx_lso;
- } while (u64_stats_fetch_retry(&nn->r_vecs[j].tx_sync, start));
-
- for (k = 0; k < NN_ET_RVEC_GATHER_STATS; k++)
- gathered_stats[k] += tmp[k];
+ start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync);
+ *data++ = nn->r_vecs[i].tx_pkts;
+ *data++ = nn->r_vecs[i].tx_busy;
+ tmp[3] = nn->r_vecs[i].hw_csum_tx;
+ tmp[4] = nn->r_vecs[i].hw_csum_tx_inner;
+ tmp[5] = nn->r_vecs[i].tx_gather;
+ tmp[6] = nn->r_vecs[i].tx_lso;
+ } while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start));
+
+ for (j = 0; j < NN_ET_RVEC_GATHER_STATS; j++)
+ gathered_stats[j] += tmp[j];
}
+
for (j = 0; j < NN_ET_RVEC_GATHER_STATS; j++)
- data[i++] = gathered_stats[j];
- for (j = 0; j < nn->dp.num_tx_rings; j++) {
- io_p = nn->dp.ctrl_bar + NFP_NET_CFG_TXR_STATS(j);
- data[i++] = readq(io_p);
- io_p = nn->dp.ctrl_bar + NFP_NET_CFG_TXR_STATS(j) + 8;
- data[i++] = readq(io_p);
+ *data++ = gathered_stats[j];
+
+ return data;
+}
+
+static unsigned int
+nfp_vnic_get_hw_stats_count(unsigned int rx_rings, unsigned int tx_rings)
+{
+ return NN_ET_GLOBAL_STATS_LEN + (rx_rings + tx_rings) * 2;
+}
+
+static u8 *
+nfp_vnic_get_hw_stats_strings(u8 *data, unsigned int rx_rings,
+ unsigned int tx_rings)
+{
+ int i;
+
+ for (i = 0; i < NN_ET_GLOBAL_STATS_LEN; i++)
+ data = nfp_pr_et(data, nfp_net_et_stats[i].name);
+
+ for (i = 0; i < tx_rings; i++) {
+ data = nfp_pr_et(data, "txq_%u_pkts", i);
+ data = nfp_pr_et(data, "txq_%u_bytes", i);
}
- for (j = 0; j < nn->dp.num_rx_rings; j++) {
- io_p = nn->dp.ctrl_bar + NFP_NET_CFG_RXR_STATS(j);
- data[i++] = readq(io_p);
- io_p = nn->dp.ctrl_bar + NFP_NET_CFG_RXR_STATS(j) + 8;
- data[i++] = readq(io_p);
+
+ for (i = 0; i < rx_rings; i++) {
+ data = nfp_pr_et(data, "rxq_%u_pkts", i);
+ data = nfp_pr_et(data, "rxq_%u_bytes", i);
}
+
+ return data;
+}
+
+static u64 *
+nfp_vnic_get_hw_stats(u64 *data, u8 __iomem *mem,
+ unsigned int rx_rings, unsigned int tx_rings)
+{
+ unsigned int i;
+
+ for (i = 0; i < NN_ET_GLOBAL_STATS_LEN; i++)
+ *data++ = readq(mem + nfp_net_et_stats[i].off);
+
+ for (i = 0; i < tx_rings; i++) {
+ *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i));
+ *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i) + 8);
+ }
+
+ for (i = 0; i < rx_rings; i++) {
+ *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i));
+ *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i) + 8);
+ }
+
+ return data;
+}
+
+static void nfp_net_get_strings(struct net_device *netdev,
+ u32 stringset, u8 *data)
+{
+ struct nfp_net *nn = netdev_priv(netdev);
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ data = nfp_vnic_get_sw_stats_strings(netdev, data);
+ data = nfp_vnic_get_hw_stats_strings(data, nn->dp.num_rx_rings,
+ nn->dp.num_tx_rings);
+ break;
+ }
+}
+
+static void
+nfp_net_get_stats(struct net_device *netdev, struct ethtool_stats *stats,
+ u64 *data)
+{
+ struct nfp_net *nn = netdev_priv(netdev);
+
+ data = nfp_vnic_get_sw_stats(netdev, data);
+ data = nfp_vnic_get_hw_stats(data, nn->dp.ctrl_bar,
+ nn->dp.num_rx_rings, nn->dp.num_tx_rings);
}
static int nfp_net_get_sset_count(struct net_device *netdev, int sset)
@@ -444,7 +490,9 @@ static int nfp_net_get_sset_count(struct net_device *netdev, int sset)
switch (sset) {
case ETH_SS_STATS:
- return NN_ET_STATS_LEN;
+ return nfp_vnic_get_sw_stats_count(netdev) +
+ nfp_vnic_get_hw_stats_count(nn->dp.num_rx_rings,
+ nn->dp.num_tx_rings);
default:
return -EOPNOTSUPP;
}
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 05/12] nfp: add helper for printing ethtool strings
From: Jakub Kicinski @ 2017-08-18 22:48 UTC (permalink / raw)
To: netdev; +Cc: oss-drivers, Jakub Kicinski
In-Reply-To: <20170818224822.8409-1-jakub.kicinski@netronome.com>
Add a helper for printing ethtool strings and advancing the
pointer correctly.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
.../net/ethernet/netronome/nfp/nfp_net_ethtool.c | 65 +++++++++++-----------
1 file changed, 32 insertions(+), 33 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index 1753bfbc8b47..ba1c28b8791b 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -335,53 +335,52 @@ static int nfp_net_set_ringparam(struct net_device *netdev,
return nfp_net_set_ring_size(nn, rxd_cnt, txd_cnt);
}
+static __printf(2, 3) u8 *nfp_pr_et(u8 *data, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ vsnprintf(data, ETH_GSTRING_LEN, fmt, args);
+ va_end(args);
+
+ return data + ETH_GSTRING_LEN;
+}
+
static void nfp_net_get_strings(struct net_device *netdev,
u32 stringset, u8 *data)
{
struct nfp_net *nn = netdev_priv(netdev);
- u8 *p = data;
int i;
switch (stringset) {
case ETH_SS_STATS:
- for (i = 0; i < NN_ET_GLOBAL_STATS_LEN; i++) {
- memcpy(p, nfp_net_et_stats[i].name, ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- }
+ for (i = 0; i < NN_ET_GLOBAL_STATS_LEN; i++)
+ data = nfp_pr_et(data, nfp_net_et_stats[i].name);
+
for (i = 0; i < nn->dp.num_r_vecs; i++) {
- sprintf(p, "rvec_%u_rx_pkts", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rvec_%u_tx_pkts", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rvec_%u_tx_busy", i);
- p += ETH_GSTRING_LEN;
+ data = nfp_pr_et(data, "rvec_%u_rx_pkts", i);
+ data = nfp_pr_et(data, "rvec_%u_tx_pkts", i);
+ data = nfp_pr_et(data, "rvec_%u_tx_busy", i);
}
- strncpy(p, "hw_rx_csum_ok", ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- strncpy(p, "hw_rx_csum_inner_ok", ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- strncpy(p, "hw_rx_csum_err", ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- strncpy(p, "hw_tx_csum", ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- strncpy(p, "hw_tx_inner_csum", ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- strncpy(p, "tx_gather", ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- strncpy(p, "tx_lso", ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
+
+ data = nfp_pr_et(data, "hw_rx_csum_ok");
+ data = nfp_pr_et(data, "hw_rx_csum_inner_ok");
+ data = nfp_pr_et(data, "hw_rx_csum_err");
+ data = nfp_pr_et(data, "hw_tx_csum");
+ data = nfp_pr_et(data, "hw_tx_inner_csum");
+ data = nfp_pr_et(data, "tx_gather");
+ data = nfp_pr_et(data, "tx_lso");
+
for (i = 0; i < nn->dp.num_tx_rings; i++) {
- sprintf(p, "txq_%u_pkts", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "txq_%u_bytes", i);
- p += ETH_GSTRING_LEN;
+ data = nfp_pr_et(data, "txq_%u_pkts", i);
+ data = nfp_pr_et(data, "txq_%u_bytes", i);
}
+
for (i = 0; i < nn->dp.num_rx_rings; i++) {
- sprintf(p, "rxq_%u_pkts", i);
- p += ETH_GSTRING_LEN;
- sprintf(p, "rxq_%u_bytes", i);
- p += ETH_GSTRING_LEN;
+ data = nfp_pr_et(data, "rxq_%u_pkts", i);
+ data = nfp_pr_et(data, "rxq_%u_bytes", i);
}
+
break;
}
}
--
2.11.0
^ permalink raw reply related
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