* [PATCH net 6/6] rtnetlink: do not set notification for tx_queue_len in do_setlink
From: Xin Long @ 2017-10-15 10:13 UTC (permalink / raw)
To: network dev; +Cc: davem, David Ahern, hannes
In-Reply-To: <cover.1508062280.git.lucien.xin@gmail.com>
NETDEV_CHANGE_TX_QUEUE_LEN event process in rtnetlink_event would
send a notification for userspace and tx_queue_len's setting in
do_setlink would trigger NETDEV_CHANGE_TX_QUEUE_LEN.
So it shouldn't set DO_SETLINK_NOTIFY status for this change to
send a notification any more.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/core/rtnetlink.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 3e98fb5..a6bcf86 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2093,7 +2093,7 @@ static int do_setlink(const struct sk_buff *skb,
dev->tx_queue_len = orig_len;
goto errout;
}
- status |= DO_SETLINK_NOTIFY;
+ status |= DO_SETLINK_MODIFIED;
}
}
--
2.1.0
^ permalink raw reply related
* [PATCH] ipvs: Fix inappropriate output of procfs
From: KUWAZAWA Takuya @ 2017-10-15 11:54 UTC (permalink / raw)
To: Wensong Zhang, Simon Horman, Julian Anastasov
Cc: Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
David S. Miller, netdev, lvs-devel, netfilter-devel, coreteam,
linux-kernel
Information about ipvs in different network namespace can be seen via procfs.
How to reproduce:
# ip netns add ns01
# ip netns add ns02
# ip netns exec ns01 ip a add dev lo 127.0.0.1/8
# ip netns exec ns02 ip a add dev lo 127.0.0.1/8
# ip netns exec ns01 ipvsadm -A -t 10.1.1.1:80
# ip netns exec ns02 ipvsadm -A -t 10.1.1.2:80
The ipvsadm displays information about its own network namespace only.
# ip netns exec ns01 ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.1.1.1:80 wlc
# ip netns exec ns02 ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.1.1.2:80 wlc
But I can see information about other network namespace via procfs.
# ip netns exec ns01 cat /proc/net/ip_vs
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 0A010101:0050 wlc
TCP 0A010102:0050 wlc
# ip netns exec ns02 cat /proc/net/ip_vs
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 0A010102:0050 wlc
Signed-off-by: KUWAZAWA Takuya <albatross0@gmail.com>
---
net/netfilter/ipvs/ip_vs_ctl.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 4f940d7..b3245f9 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -2034,12 +2034,16 @@ static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
seq_puts(seq,
" -> RemoteAddress:Port Forward Weight ActiveConn InActConn\n");
} else {
+ struct net *net = seq_file_net(seq);
+ struct netns_ipvs *ipvs = net_ipvs(net);
const struct ip_vs_service *svc = v;
const struct ip_vs_iter *iter = seq->private;
const struct ip_vs_dest *dest;
struct ip_vs_scheduler *sched = rcu_dereference(svc->scheduler);
char *sched_name = sched ? sched->name : "none";
+ if (svc->ipvs != ipvs)
+ return 0;
if (iter->table == ip_vs_svc_table) {
#ifdef CONFIG_IP_VS_IPV6
if (svc->af == AF_INET6)
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH net-next] ipv6: only update __use and lastusetime once per jiffy at most
From: Paolo Abeni @ 2017-10-15 13:01 UTC (permalink / raw)
To: Martin KaFai Lau, Wei Wang; +Cc: David Miller, netdev, Eric Dumazet
In-Reply-To: <20171014000924.dcfuqxwlalaigqdq@kafai-mbp.dhcp.thefacebook.com>
On Fri, 2017-10-13 at 17:09 -0700, Martin KaFai Lau wrote:
> On Fri, Oct 13, 2017 at 10:08:07PM +0000, Wei Wang wrote:
> > From: Wei Wang <weiwan@google.com>
> >
> > In order to not dirty the cacheline too often, we try to only update
> > dst->__use and dst->lastusetime at most once per jiffy.
>
>
> > As dst->lastusetime is only used by ipv6 garbage collector, it should
> > be good enough time resolution.
>
> Make sense.
>
> > And __use is only used in ipv6_route_seq_show() to show how many times a
> > dst has been used. And as __use is not atomic_t right now, it does not
> > show the precise number of usage times anyway. So we think it should be
> > OK to only update it at most once per jiffy.
>
> If __use is only bumped HZ number of times per second and we can do ~3Mpps now,
> would __use be way off?
It would, but even nowaday such value could not be trusted, due to the
cuncurrent non atomic operation used to update it.
This:
https://marc.info/?l=linux-netdev&m=150653252930953&w=2
was an attempt to preserve a more meaningful value for '__use', but it
requires an additional cacheline.
I'm fine with either options.
Paolo
^ permalink raw reply
* [REGRESSION] rtl8723bs (r8723bs) WiFi stopped working on 4.14 on Chuwi Hi12 (Intel CherryTrail SoC)
From: Михаил Новоселов, ШЭМ Думалогия @ 2017-10-15 13:37 UTC (permalink / raw)
To: netdev@vger.kernel.org
Hello,
I've found a regression in kernel 4.14, the last tested kernel was the yesterday daily build http://kernel.ubuntu.com/~kernel-ppa/mainline/daily/ , it worked on 4.12 and 4.13 and now on 4.14 it is able to scan for available networks, but is not able to get an IP adress.
I reported a bug to the kernel's bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=197137
---------------------------------------------------------------------------------
Hardware platform: Chuwi Hi12 (intell cherrytrail tablet)
On Linux kernels 4.12 and 4.13 the WiFi does work, starting from 4.14 not release builds it does not, including some dily builds of the times somewhere near rc1, the rc3 release and the letest daily build of the code state for 2017-10-04 http://kernel.ubuntu.com/~kernel-ppa/mainline/daily/2017-10-05/
I will provide logs from 4.14 a bit later, bellow are LOGS FROM 4.13.1 with working WiFi
Full information on hardware and logs (including full dmesg) are here: https://linux-hardware.org/index.php?probe=01521aa6cf (kernel 4.13 and working wifi)
$ dmesg | grep rtl
[ 7.899105] RTL8723BS: rtl8723bs v4.3.5.5_12290.20140916_BTCOEX20140507-4E40
[ 7.899106] RTL8723BS: rtl8723bs BT-Coex version = BTCOEX20140507-4E40
[ 10.570755] rtl8723bs: acquire FW from file:rtlwifi/rtl8723bs_nic.bin
Logs from 4.14 with WiFi not working: https://linux-hardware.org/index.php?probe=5c7b00c4cb
^ permalink raw reply
* (unknown),
From: marketing @ 2017-10-15 13:57 UTC (permalink / raw)
To: netdev
[-- Attachment #1: 29848250.zip --]
[-- Type: application/zip, Size: 2816 bytes --]
^ permalink raw reply
* Re: [PATCH] ipvs: Fix inappropriate output of procfs
From: Julian Anastasov @ 2017-10-15 14:11 UTC (permalink / raw)
To: KUWAZAWA Takuya
Cc: Wensong Zhang, Simon Horman, Pablo Neira Ayuso, Jozsef Kadlecsik,
Florian Westphal, David S. Miller, netdev, lvs-devel,
netfilter-devel, coreteam, linux-kernel
In-Reply-To: <20171015115406.GA11429@nuc02.localdomain>
Hello,
On Sun, 15 Oct 2017, KUWAZAWA Takuya wrote:
> Information about ipvs in different network namespace can be seen via procfs.
>
> How to reproduce:
>
> # ip netns add ns01
> # ip netns add ns02
> # ip netns exec ns01 ip a add dev lo 127.0.0.1/8
> # ip netns exec ns02 ip a add dev lo 127.0.0.1/8
> # ip netns exec ns01 ipvsadm -A -t 10.1.1.1:80
> # ip netns exec ns02 ipvsadm -A -t 10.1.1.2:80
>
> The ipvsadm displays information about its own network namespace only.
>
> # ip netns exec ns01 ipvsadm -Ln
> IP Virtual Server version 1.2.1 (size=4096)
> Prot LocalAddress:Port Scheduler Flags
> -> RemoteAddress:Port Forward Weight ActiveConn InActConn
> TCP 10.1.1.1:80 wlc
>
> # ip netns exec ns02 ipvsadm -Ln
> IP Virtual Server version 1.2.1 (size=4096)
> Prot LocalAddress:Port Scheduler Flags
> -> RemoteAddress:Port Forward Weight ActiveConn InActConn
> TCP 10.1.1.2:80 wlc
>
> But I can see information about other network namespace via procfs.
>
> # ip netns exec ns01 cat /proc/net/ip_vs
> IP Virtual Server version 1.2.1 (size=4096)
> Prot LocalAddress:Port Scheduler Flags
> -> RemoteAddress:Port Forward Weight ActiveConn InActConn
> TCP 0A010101:0050 wlc
> TCP 0A010102:0050 wlc
>
> # ip netns exec ns02 cat /proc/net/ip_vs
> IP Virtual Server version 1.2.1 (size=4096)
> Prot LocalAddress:Port Scheduler Flags
> -> RemoteAddress:Port Forward Weight ActiveConn InActConn
> TCP 0A010102:0050 wlc
>
> Signed-off-by: KUWAZAWA Takuya <albatross0@gmail.com>
Looks good to me
Acked-by: Julian Anastasov <ja@ssi.bg>
Simon, please apply to ipvs tree.
> ---
> net/netfilter/ipvs/ip_vs_ctl.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
> index 4f940d7..b3245f9 100644
> --- a/net/netfilter/ipvs/ip_vs_ctl.c
> +++ b/net/netfilter/ipvs/ip_vs_ctl.c
> @@ -2034,12 +2034,16 @@ static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
> seq_puts(seq,
> " -> RemoteAddress:Port Forward Weight ActiveConn InActConn\n");
> } else {
> + struct net *net = seq_file_net(seq);
> + struct netns_ipvs *ipvs = net_ipvs(net);
> const struct ip_vs_service *svc = v;
> const struct ip_vs_iter *iter = seq->private;
> const struct ip_vs_dest *dest;
> struct ip_vs_scheduler *sched = rcu_dereference(svc->scheduler);
> char *sched_name = sched ? sched->name : "none";
>
> + if (svc->ipvs != ipvs)
> + return 0;
> if (iter->table == ip_vs_svc_table) {
> #ifdef CONFIG_IP_VS_IPV6
> if (svc->af == AF_INET6)
> --
> 1.8.3.1
Regards
^ permalink raw reply
* Re: [PATCH net-next v2 1/2] dt-bindings: net: add DT bindings for Socionext UniPhier AVE
From: Masahiro Yamada @ 2017-10-15 14:52 UTC (permalink / raw)
To: Kunihiko Hayashi
Cc: netdev, Andrew Lunn, Florian Fainelli, Rob Herring, Mark Rutland,
linux-arm-kernel, Linux Kernel Mailing List, devicetree,
Masami Hiramatsu, Jassi Brar
In-Reply-To: <1507854928-4357-2-git-send-email-hayashi.kunihiko@socionext.com>
2017-10-13 9:35 GMT+09:00 Kunihiko Hayashi <hayashi.kunihiko@socionext.com>:
> DT bindings for the AVE ethernet controller found on Socionext's
> UniPhier platforms.
>
> Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> ---
> .../bindings/net/socionext,uniphier-ave4.txt | 53 ++++++++++++++++++++++
> 1 file changed, 53 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt
>
> diff --git a/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt b/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt
> new file mode 100644
> index 0000000..25f4d92
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt
> @@ -0,0 +1,53 @@
> +* Socionext AVE ethernet controller
> +
> +This describes the devicetree bindings for AVE ethernet controller
> +implemented on Socionext UniPhier SoCs.
> +
> +Required properties:
> + - compatible: Should be
> + - "socionext,uniphier-pro4-ave4" : for Pro4 SoC
> + - "socionext,uniphier-pxs2-ave4" : for PXs2 SoC
> + - "socionext,uniphier-ld20-ave4" : for LD20 SoC
> + - "socionext,uniphier-ld11-ave4" : for LD11 SoC
> + - reg: Address where registers are mapped and size of region.
> + - interrupts: Should contain the MAC interrupt.
> + - phy-mode: See ethernet.txt in the same directory. Allow to choose
> + "rgmii", "rmii", or "mii" according to the PHY.
> + - pinctrl-names: List of assigned state names, see pinctrl
> + binding documentation.
> + - pinctrl-0: List of phandles to configure the GPIO pin,
> + see pinctrl binding documentation. Choose this appropriately
> + according to phy-mode.
> + - <&pinctrl_ether_rgmii> if phy-mode is "rgmii".
> + - <&pinctrl_ether_rmii> if phy-mode is "rmii".
> + - <&pinctrl_ether_mii> if phy-mode is "mii".
> + - phy-handle: Should point to the external phy device.
> + See ethernet.txt file in the same directory.
> + - mdio subnode: Should be device tree subnode with the following required
> + properties:
> + - #address-cells: Must be <1>.
> + - #size-cells: Must be <0>.
> + - reg: phy ID number, usually a small integer.
> +
> +Optional properties:
> + - local-mac-address: See ethernet.txt in the same directory.
> +
> +Example:
> +
> + ether: ethernet@65000000 {
> + compatible = "socionext,uniphier-ld20-ave4";
> + reg = <0x65000000 0x8500>;
> + interrupts = <0 66 4>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_ether_rgmii>;
> + phy-mode = "rgmii";
> + phy-handle = <ðphy>;
> + local-mac-address = [00 00 00 00 00 00];
> + mdio {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + ethphy: ethphy@1 {
> + reg = <1>;
> + };
> + };
> + };
> --
> 2.7.4
>
I found the following code in 2/2.
+ /* get clock */
+ priv->clk = clk_get(dev, NULL);
+ if (IS_ERR(priv->clk))
+ priv->clk = NULL;
+
+ /* get reset */
+ priv->rst = reset_control_get(dev, NULL);
+ if (IS_ERR(priv->rst))
+ priv->rst = NULL;
+
This doc needs to describe "clocks", "resets".
--
Best Regards
Masahiro Yamada
^ permalink raw reply
* Re: Linux 4.12+ memory leak on router with i40e NICs
From: Paweł Staszewski @ 2017-10-15 15:03 UTC (permalink / raw)
To: Alexander Duyck
Cc: Anders K. Pedersen | Cohaesio, netdev@vger.kernel.org,
intel-wired-lan@lists.osuosl.org, alexander.h.duyck@intel.com
In-Reply-To: <CAKgT0UcOWxnrsGEjTopPP-JKyKGTG3j6KNKUbhQRgaCStyzr_A@mail.gmail.com>
Previously attached graphs was for:
4.14.0-rc4-next-20171012
from git:
git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
In kernel drivers.
Just tested by replacing cards in server from 8x10G based on 82599 to
02:00.0 Ethernet controller: Intel Corporation Ethernet Controller X710
for 10GbE SFP+ (rev 01)
02:00.1 Ethernet controller: Intel Corporation Ethernet Controller X710
for 10GbE SFP+ (rev 01)
02:00.2 Ethernet controller: Intel Corporation Ethernet Controller X710
for 10GbE SFP+ (rev 01)
02:00.3 Ethernet controller: Intel Corporation Ethernet Controller X710
for 10GbE SFP+ (rev 01)
03:00.0 Ethernet controller: Intel Corporation Ethernet Controller X710
for 10GbE SFP+ (rev 02)
03:00.1 Ethernet controller: Intel Corporation Ethernet Controller X710
for 10GbE SFP+ (rev 02)
03:00.2 Ethernet controller: Intel Corporation Ethernet Controller X710
for 10GbE SFP+ (rev 02)
03:00.3 Ethernet controller: Intel Corporation Ethernet Controller X710
for 10GbE SFP+ (rev 02)
And with same configuration - have leaking memory somewhere - there is
no process that can
ps aux --sort -rss
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 5103 41.2 31.1 10357508 10242860 ? Sl Oct14 1010:33
/usr/local/sbin/bgpd -d -A 127.0.0.1 -u root -g root -I
--ignore_warnings -F /usr/local/etc/Quagga.conf -t
root 5094 0.0 0.8 295372 270868 ? Ss Oct14 1:26
/usr/local/sbin/zebra -d -A 127.0.0.1 -u root -g root -I
--ignore_warnings -F /usr/local/etc/Quagga.conf
root 4356 3.4 0.2 98780 75852 ? S Oct14 84:21
/usr/sbin/snmpd -p /var/run/snmpd.pid -Ln -I -smux
root 3448 0.0 0.0 32172 6204 ? Ss Oct14 0:00
/sbin/udevd --daemon
root 5385 0.0 0.0 61636 5044 ? Ss Oct14 0:00 sshd:
paol [priv]
root 4116 0.0 0.0 346312 4804 ? Ss Oct14 0:33
/usr/sbin/syslog-ng --persist-file /var/lib/syslog-ng/syslog-ng.persist
--cfgfile /etc/syslog-ng/syslog-ng.conf --pidfile /run/syslog-ng.pid
paol 5390 0.0 0.0 61636 3564 ? S Oct14 0:06 sshd:
paol@pts/1
root 5403 0.0 0.0 709344 3520 ? Ssl Oct14 0:26
/opt/collectd/sbin/collectd
root 5397 0.0 0.0 18280 3288 pts/1 S Oct14 0:00 -su
root 4384 0.0 0.0 30472 3016 ? Ss Oct14 0:00
/usr/sbin/sshd
paol 5391 0.0 0.0 18180 2884 pts/1 Ss Oct14 0:00 -bash
root 5394 0.0 0.0 43988 2376 pts/1 S Oct14 0:00 su -
root 20815 0.0 0.0 17744 2312 pts/1 R+ 16:58 0:00 ps aux
--sort -rss
root 4438 0.0 0.0 28820 2256 ? S Oct14 0:00 teamd
-d -f /etc/teamd.conf
root 4030 0.0 0.0 6976 2024 ? Ss Oct14 0:00 mdadm
--monitor --scan --daemonise --pid-file /var/run/mdadm.pid --syslog
root 4408 0.0 0.0 16768 1884 ? Ss Oct14 0:00
/usr/sbin/cron
root 5357 0.0 0.0 120532 1724 tty6 Ss+ Oct14 0:00
/sbin/agetty 38400 tty6 linux
root 5352 0.0 0.0 120532 1712 tty1 Ss+ Oct14 0:00
/sbin/agetty 38400 tty1 linux
root 5356 0.0 0.0 120532 1692 tty5 Ss+ Oct14 0:00
/sbin/agetty 38400 tty5 linux
root 5353 0.0 0.0 120532 1648 tty2 Ss+ Oct14 0:00
/sbin/agetty 38400 tty2 linux
root 5355 0.0 0.0 120532 1628 tty4 Ss+ Oct14 0:00
/sbin/agetty 38400 tty4 linux
root 5354 0.0 0.0 120532 1620 tty3 Ss+ Oct14 0:00
/sbin/agetty 38400 tty3 linux
root 1 0.0 0.0 4184 1420 ? Ss Oct14 0:02 init [3]
root 4115 0.0 0.0 34336 608 ? S Oct14 0:00
supervising syslog-ng
root 2 0.0 0.0 0 0 ? S Oct14 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/0:0H]
root 6 0.0 0.0 0 0 ? I< Oct14 0:00
[mm_percpu_wq]
root 7 0.8 0.0 0 0 ? S Oct14 22:01
[ksoftirqd/0]
root 8 0.0 0.0 0 0 ? I Oct14 1:36 [rcu_sched]
root 9 0.0 0.0 0 0 ? I Oct14 0:00 [rcu_bh]
root 10 0.0 0.0 0 0 ? S Oct14 0:00
[migration/0]
root 11 0.0 0.0 0 0 ? S Oct14 0:00 [cpuhp/0]
root 12 0.0 0.0 0 0 ? S Oct14 0:00 [cpuhp/1]
root 13 0.0 0.0 0 0 ? S Oct14 0:00
[migration/1]
root 14 0.8 0.0 0 0 ? S Oct14 21:39
[ksoftirqd/1]
root 16 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/1:0H]
root 17 0.0 0.0 0 0 ? S Oct14 0:00 [cpuhp/2]
root 18 0.0 0.0 0 0 ? S Oct14 0:00
[migration/2]
root 19 0.8 0.0 0 0 ? S Oct14 20:48
[ksoftirqd/2]
root 21 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/2:0H]
root 22 0.0 0.0 0 0 ? S Oct14 0:00 [cpuhp/3]
root 23 0.0 0.0 0 0 ? S Oct14 0:00
[migration/3]
root 24 1.0 0.0 0 0 ? S Oct14 24:36
[ksoftirqd/3]
root 26 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/3:0H]
root 27 0.0 0.0 0 0 ? S Oct14 0:00 [cpuhp/4]
root 28 0.0 0.0 0 0 ? S Oct14 0:00
[migration/4]
root 29 0.8 0.0 0 0 ? S Oct14 20:14
[ksoftirqd/4]
root 31 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/4:0H]
root 32 0.0 0.0 0 0 ? S Oct14 0:00 [cpuhp/5]
root 33 0.0 0.0 0 0 ? S Oct14 0:00
[migration/5]
root 34 0.8 0.0 0 0 ? S Oct14 20:22
[ksoftirqd/5]
root 36 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/5:0H]
root 37 0.0 0.0 0 0 ? S Oct14 0:00 [cpuhp/6]
root 38 0.0 0.0 0 0 ? S Oct14 0:00
[migration/6]
root 39 0.8 0.0 0 0 ? S Oct14 20:43
[ksoftirqd/6]
root 41 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/6:0H]
root 42 0.0 0.0 0 0 ? S Oct14 0:00 [cpuhp/7]
root 43 0.0 0.0 0 0 ? S Oct14 0:00
[migration/7]
root 44 0.8 0.0 0 0 ? S Oct14 21:51
[ksoftirqd/7]
root 46 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/7:0H]
root 47 0.0 0.0 0 0 ? S Oct14 0:00 [cpuhp/8]
root 48 0.0 0.0 0 0 ? S Oct14 0:00
[migration/8]
root 49 0.7 0.0 0 0 ? S Oct14 18:49
[ksoftirqd/8]
root 51 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/8:0H]
root 52 0.0 0.0 0 0 ? S Oct14 0:00 [cpuhp/9]
root 53 0.0 0.0 0 0 ? S Oct14 0:00
[migration/9]
root 54 0.8 0.0 0 0 ? S Oct14 20:48
[ksoftirqd/9]
root 56 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/9:0H]
root 57 0.0 0.0 0 0 ? S Oct14 0:00 [cpuhp/10]
root 58 0.0 0.0 0 0 ? S Oct14 0:00
[migration/10]
root 59 0.7 0.0 0 0 ? S Oct14 19:07
[ksoftirqd/10]
root 61 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/10:0H]
root 62 0.0 0.0 0 0 ? S Oct14 0:00 [cpuhp/11]
root 63 0.0 0.0 0 0 ? S Oct14 0:00
[migration/11]
root 64 0.8 0.0 0 0 ? S Oct14 19:54
[ksoftirqd/11]
root 66 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/11:0H]
root 67 0.0 0.0 0 0 ? S Oct14 0:00 [kdevtmpfs]
root 70 0.0 0.0 0 0 ? S Oct14 0:00 [kauditd]
root 410 0.0 0.0 0 0 ? S Oct14 0:00
[khungtaskd]
root 411 0.0 0.0 0 0 ? S Oct14 0:00
[oom_reaper]
root 412 0.0 0.0 0 0 ? I< Oct14 0:00 [writeback]
root 414 0.0 0.0 0 0 ? S Oct14 0:00
[kcompactd0]
root 415 0.0 0.0 0 0 ? SN Oct14 0:00 [ksmd]
root 416 0.0 0.0 0 0 ? SN Oct14 0:00
[khugepaged]
root 417 0.0 0.0 0 0 ? I< Oct14 0:00 [crypto]
root 419 0.0 0.0 0 0 ? I< Oct14 0:00 [kblockd]
root 1314 0.0 0.0 0 0 ? I< Oct14 0:00 [ata_sff]
root 1329 0.0 0.0 0 0 ? I< Oct14 0:00 [md]
root 1425 0.0 0.0 0 0 ? I< Oct14 0:00 [rpciod]
root 1426 0.0 0.0 0 0 ? I< Oct14 0:00 [xprtiod]
root 1515 0.0 0.0 0 0 ? S Oct14 0:00 [kswapd0]
root 1614 0.0 0.0 0 0 ? I< Oct14 0:00 [nfsiod]
root 1684 0.0 0.0 0 0 ? I< Oct14 0:00
[acpi_thermal_pm]
root 1801 0.0 0.0 0 0 ? S Oct14 0:00 [scsi_eh_0]
root 1802 0.0 0.0 0 0 ? I< Oct14 0:00
[scsi_tmf_0]
root 1806 0.0 0.0 0 0 ? S Oct14 0:00 [scsi_eh_1]
root 1807 0.0 0.0 0 0 ? I< Oct14 0:00
[scsi_tmf_1]
root 1810 0.0 0.0 0 0 ? S Oct14 0:00 [scsi_eh_2]
root 1811 0.0 0.0 0 0 ? I< Oct14 0:00
[scsi_tmf_2]
root 1814 0.0 0.0 0 0 ? S Oct14 0:00 [scsi_eh_3]
root 1815 0.0 0.0 0 0 ? I< Oct14 0:00
[scsi_tmf_3]
root 1838 0.0 0.0 0 0 ? S Oct14 0:00 [scsi_eh_4]
root 1839 0.0 0.0 0 0 ? I< Oct14 0:00
[scsi_tmf_4]
root 1842 0.0 0.0 0 0 ? S Oct14 0:00 [scsi_eh_5]
root 1843 0.0 0.0 0 0 ? I< Oct14 0:00
[scsi_tmf_5]
root 1846 0.0 0.0 0 0 ? S Oct14 0:00 [scsi_eh_6]
root 1847 0.0 0.0 0 0 ? I< Oct14 0:00
[scsi_tmf_6]
root 1850 0.0 0.0 0 0 ? S Oct14 0:00 [scsi_eh_7]
root 1851 0.0 0.0 0 0 ? I< Oct14 0:00
[scsi_tmf_7]
root 1854 0.0 0.0 0 0 ? S Oct14 0:00 [scsi_eh_8]
root 1855 0.0 0.0 0 0 ? I< Oct14 0:00
[scsi_tmf_8]
root 1858 0.0 0.0 0 0 ? S Oct14 0:00 [scsi_eh_9]
root 1859 0.0 0.0 0 0 ? I< Oct14 0:00
[scsi_tmf_9]
root 1921 0.0 0.0 0 0 ? I< Oct14 0:00 [ixgbe]
root 1923 0.0 0.0 0 0 ? I< Oct14 0:00 [i40e]
root 3058 0.0 0.0 0 0 ? I< Oct14 0:00
[ipv6_addrconf]
root 3087 0.0 0.0 0 0 ? S Oct14 0:01 [md3_raid1]
root 3092 0.0 0.0 0 0 ? S Oct14 0:00 [md2_raid1]
root 3097 0.0 0.0 0 0 ? S Oct14 0:00 [md1_raid1]
root 3099 0.0 0.0 0 0 ? I< Oct14 0:00
[reiserfs/md2]
root 3100 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/0:1H]
root 3124 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/6:1H]
root 3155 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/1:1H]
root 3244 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/11:1H]
root 3351 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/5:1H]
root 3467 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/8:1H]
root 3502 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/9:1H]
root 3503 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/2:1H]
root 3521 0.0 0.0 0 0 ? SN Oct14 0:00 [kipmi0]
root 3757 0.0 0.0 0 0 ? I< Oct14 0:00
[reiserfs/md3]
root 5096 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/10:1H]
root 5280 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/7:1H]
root 5447 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/3:1H]
root 6573 0.0 0.0 0 0 ? I 16:10 0:00
[kworker/3:0]
root 6584 0.0 0.0 0 0 ? I 16:11 0:00
[kworker/6:0]
root 6660 0.0 0.0 0 0 ? I< Oct14 0:00
[kworker/4:1H]
root 6967 0.0 0.0 0 0 ? I 16:15 0:00
[kworker/5:2]
root 6976 0.0 0.0 0 0 ? I 16:17 0:00
[kworker/10:1]
root 7036 0.0 0.0 0 0 ? I 06:19 0:02
[kworker/0:4]
root 7750 0.0 0.0 0 0 ? I 16:22 0:00
[kworker/4:2]
root 9555 0.0 0.0 0 0 ? I 16:25 0:00
[kworker/2:2]
root 9557 0.0 0.0 0 0 ? I 16:26 0:00
[kworker/6:2]
root 10146 0.0 0.0 0 0 ? I 16:27 0:00
[kworker/8:2]
root 10148 0.0 0.0 0 0 ? I 16:27 0:00
[kworker/1:2]
root 13804 0.0 0.0 0 0 ? I 13:42 0:00
[kworker/0:1]
root 16109 0.0 0.0 0 0 ? I 16:33 0:00
[kworker/9:2]
root 16156 0.0 0.0 0 0 ? I 16:39 0:00
[kworker/4:0]
root 16422 0.0 0.0 0 0 ? I 16:39 0:00
[kworker/5:1]
root 16423 0.0 0.0 0 0 ? I 16:39 0:00
[kworker/9:0]
root 17118 0.0 0.0 0 0 ? I 16:40 0:00
[kworker/11:2]
root 17250 0.0 0.0 0 0 ? I 16:42 0:00
[kworker/3:1]
root 17620 0.0 0.0 0 0 ? I 16:43 0:00
[kworker/0:0]
root 17629 0.0 0.0 0 0 ? I 16:45 0:00
[kworker/2:1]
root 17639 0.0 0.0 0 0 ? I 16:47 0:00
[kworker/u24:0]
root 17640 0.0 0.0 0 0 ? I 16:47 0:00
[kworker/10:0]
root 17642 0.0 0.0 0 0 ? I 16:48 0:00
[kworker/0:5]
root 19577 0.0 0.0 0 0 ? I 16:49 0:00
[kworker/8:1]
root 19578 0.0 0.0 0 0 ? I 16:49 0:00
[kworker/8:3]
root 19819 0.0 0.0 0 0 ? I 16:49 0:00
[kworker/1:1]
root 19820 0.0 0.0 0 0 ? I 16:49 0:00
[kworker/1:3]
root 19972 0.0 0.0 0 0 ? I 16:52 0:00
[kworker/7:1]
root 19973 0.0 0.0 0 0 ? I 16:52 0:00
[kworker/7:3]
root 19974 0.0 0.0 0 0 ? I 16:52 0:00
[kworker/11:1]
root 19976 0.0 0.0 0 0 ? I 16:52 0:00
[kworker/u24:1]
root 20106 0.0 0.0 0 0 ? I 16:53 0:00
[kworker/4:1]
root 20107 0.0 0.0 0 0 ? I 16:53 0:00
[kworker/4:3]
root 20108 0.0 0.0 0 0 ? I 16:54 0:00
[kworker/3:2]
root 20109 0.0 0.0 0 0 ? I 16:54 0:00
[kworker/3:3]
root 20110 0.0 0.0 0 0 ? I 16:54 0:00
[kworker/0:6]
root 20217 0.0 0.0 0 0 ? I 16:55 0:00
[kworker/1:0]
root 20219 0.0 0.0 0 0 ? I 16:56 0:00
[kworker/9:1]
root 20222 0.0 0.0 0 0 ? I 16:56 0:00
[kworker/9:3]
root 20354 0.0 0.0 0 0 ? I 16:57 0:00
[kworker/5:0]
root 20355 0.0 0.0 0 0 ? I 16:57 0:00
[kworker/5:3]
root 20814 0.0 0.0 0 0 ? I 16:57 0:00
[kworker/u24:2]
root 26845 0.0 0.0 0 0 ? I 15:40 0:00
[kworker/7:2]
root 26979 0.0 0.0 0 0 ? I 15:43 0:00
[kworker/0:3]
root 27375 0.0 0.0 0 0 ? I 15:48 0:00
[kworker/0:2]
but free -m
free -m
total used free shared buff/cache
available
Mem: 32113 18345 13598 0 169 13419
Swap: 3911 0 3911
less and less about 0.5MB per hour
it looks like this commit:
https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/drivers/net/ethernet/intel/i40e/i40e_txrx.c?id=2b9478ffc550f17c6cd8c69057234e91150f5972
Is not included in:
git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
Ok will upgrade tomorrow - and will check with that fix.
W dniu 2017-10-15 o 02:58, Alexander Duyck pisze:
> Hi Pawel,
>
> To clarify is that Dave Miller's tree or Linus's that you are talking
> about? If it is Dave's tree how long ago was it you pulled it since I
> think the fix was just pushed by Jeff Kirsher a few days ago.
>
> The issue should be fixed in the following commit:
> https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git/commit/drivers/net/ethernet/intel/i40e/i40e_txrx.c?id=2b9478ffc550f17c6cd8c69057234e91150f5972
>
> Thanks.
>
> - Alex
>
> On Sat, Oct 14, 2017 at 3:03 PM, Paweł Staszewski <pstaszewski@itcare.pl> wrote:
>> Forgot to add - this graphs are tested with Kernel 4.14-rc4-next
>>
>>
>> W dniu 2017-10-15 o 00:00, Paweł Staszewski pisze:
>>
>> Same problem here
>>
>> Also only difference is change 82599 intel to x710 and have memleak
>>
>> mem with ixgbe driver over time - same config saame kernel
>>
>>
>>
>> changed NIC's to x710 i40e driver (this is the only change)
>>
>> And mem over time:
>>
>>
>>
>> There is no process that is eating memory - looks like there is some problem
>> with i40e driver - but it not a surprise :) this driver is really buggy -
>> with many things - most tickets on e1000e sourceforge that i openned have no
>> reply for year or more - or if somebody reply after year they are closing
>> ticket after 1 day with info about no activity :)
>>
>>
>>
>> W dniu 2017-10-05 o 07:19, Anders K. Pedersen | Cohaesio pisze:
>>
>> On ons, 2017-10-04 at 08:32 -0700, Alexander Duyck wrote:
>>
>> On Wed, Oct 4, 2017 at 5:56 AM, Anders K. Pedersen | Cohaesio
>> <akp@cohaesio.com> wrote:
>>
>> Hello,
>>
>> After updating one of our Linux based routers to kernel 4.13 it
>> began
>> leaking memory quite fast (about 1 GB every half hour). To narrow
>> we
>> tried various kernel versions and found that 4.11.12 is okay, while
>> 4.12 also leaks, so we did a bisection between 4.11 and 4.12.
>>
>> The first bisection ended at
>> "[6964e53f55837b0c49ed60d36656d2e0ee4fc27b] i40e: fix handling of
>> HW
>> ATR eviction", which fixes some flag handling that was broken by
>> 47994c119a36 "i40e: remove hw_disabled_flags in favor of using
>> separate
>> flag bits", so I did a second bisection, where I added 6964e53f5583
>> "i40e: fix handling of HW ATR eviction" to the steps that had
>> 47994c119a36 "i40e: remove hw_disabled_flags in favor of using
>> separate
>> flag bits" in them.
>>
>> The second bisection ended at
>> "[0e626ff7ccbfc43c6cc4aeea611c40b899682382] i40e: Fix support for
>> flow
>> director programming status", where I don't see any obvious
>> problems,
>> so I'm hoping for some assistance.
>>
>> The router is a PowerEdge R730 server (Haswell based) with three
>> Intel
>> NICs (all using the i40e driver):
>>
>> X710 quad port 10 GbE SFP+: eth0 eth1 eth2 eth3
>> X710 quad port 10 GbE SFP+: eth4 eth5 eth6 eth7
>> XL710 dual port 40 GbE QSFP+: eth8 eth9
>>
>> The NICs are aggregated with LACP with the team driver:
>>
>> team0: eth9 (40 GbE selected primary), and eth3, eth7 (10 GbE non-
>> selected backups)
>> team1: eth0, eth1, eth4, eth5 (all 10 GbE selected)
>>
>> team0 is used for internal networks and has one untagged and four
>> tagged VLAN interfaces, while team1 has an external uplink
>> connection
>> without any VLANs.
>>
>> The router runs an eBGP session on team1 to one of our uplinks, and
>> iBGP via team0 to our other border routers. It also runs OSPF on
>> the
>> internal VLANs on team0. One thing I've noticed is that when OSPF
>> is
>> not announcing a default gateway to the internal networks, so there
>> is
>> almost no traffic coming in on team0 and out on team1, but still
>> plenty
>> of traffic coming in on team1 and out via team0, there's no memory
>> leak
>> (or at least it is so small that we haven't detected it). But as
>> soon
>> as we configure OSPF to announce a default gateway to the internal
>> VLANs, so we get traffic from team0 to team1 the leaking begins.
>> Stopping the OSPF default gateway announcement again also stops the
>> leaking, but does not release already leaked memory.
>>
>> So this leads to me suspect that the leaking is related to RX on
>> team0
>> (where XL710 eth9 is normally the only active interface) or TX on
>> team1
>> (X710 eth0, eth1, eth4, eth5). The first bad commit is related to
>> RX
>> cleaning, which suggests RX on team0. Since we're only seeing the
>> leak
>> for our outbound traffic, I suspect either a difference between the
>> X710 vs. XL710 NICs, or that the inbound traffic is for relatively
>> few
>> destination addresses (only our own systems) while the outbound
>> traffic
>> is for many different addresses on the internet. But I'm just
>> guessing
>> here.
>>
>> I've tried kmemleak, but it only found a few kB of suspected memory
>> leaks (several of which disappeared again after a while).
>>
>> Below I've included more details - git bisect logs, ethtool -i,
>> dmesg,
>> Kernel .config, and various memory related /proc files. Any help or
>> suggestions would be much appreciated, and please let me know if
>> more
>> information is needed or there's something I should try.
>>
>> Regards,
>> Anders K. Pedersen
>>
>> Hi Anders,
>>
>> I think I see the problem and should have a patch submitted shortly
>> to
>> address it. From what I can tell it looks like the issue is that we
>> weren't properly recycling the pages associated with descriptors that
>> contained an Rx programming status. For now the workaround would be
>> to
>> try disabling ATR via the "ethtool --set-priv-flags" command. I
>> should
>> have a patch out in the next hour or so that you can try testing to
>> verify if it addresses the issue.
>>
>> Thanks.
>>
>> - Alex
>>
>> Thanks Alex,
>>
>> I will test the patch in our next service window on Tuesday morning.
>>
>> Regards,
>> Anders
>>
>>
>>
^ permalink raw reply
* Re: [PATCH net-next v2 2/2] net: ethernet: socionext: add AVE ethernet driver
From: Masahiro Yamada @ 2017-10-15 15:08 UTC (permalink / raw)
To: Kunihiko Hayashi
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Andrew Lunn, Florian Fainelli,
Rob Herring, Mark Rutland, linux-arm-kernel,
Linux Kernel Mailing List, devicetree-u79uwXL29TY76Z2rM5mHXA,
Masami Hiramatsu, Jassi Brar
In-Reply-To: <1507854928-4357-3-git-send-email-hayashi.kunihiko-uWyLwvC0a2jby3iVrkZq2A@public.gmane.org>
2017-10-13 9:35 GMT+09:00 Kunihiko Hayashi <hayashi.kunihiko-uWyLwvC0a2jby3iVrkZq2A@public.gmane.org>:
> +static int ave_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + u32 ave_id;
> + struct ave_private *priv;
> + const struct ave_soc_data *data;
> + phy_interface_t phy_mode;
> + struct net_device *ndev;
> + struct resource *res;
> + void __iomem *base;
> + int irq, ret = 0;
> + char buf[ETHTOOL_FWVERS_LEN];
> + const void *mac_addr;
> +
> + data = of_device_get_match_data(dev);
> + if (WARN_ON(!data))
> + return -EINVAL;
> +
> + phy_mode = of_get_phy_mode(np);
> + if (phy_mode < 0) {
> + dev_err(dev, "phy-mode not found\n");
> + return -EINVAL;
> + }
> + if ((!phy_interface_mode_is_rgmii(phy_mode)) &&
> + phy_mode != PHY_INTERFACE_MODE_RMII &&
> + phy_mode != PHY_INTERFACE_MODE_MII) {
> + dev_err(dev, "phy-mode is invalid\n");
> + return -EINVAL;
> + }
> +
> + irq = platform_get_irq(pdev, 0);
> + if (irq < 0) {
> + dev_err(dev, "IRQ not found\n");
> + return irq;
> + }
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + base = devm_ioremap_resource(dev, res);
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> +
> + /* alloc netdevice */
> + ndev = alloc_etherdev(sizeof(struct ave_private));
> + if (!ndev) {
> + dev_err(dev, "can't allocate ethernet device\n");
> + return -ENOMEM;
> + }
> +
> + ndev->netdev_ops = &ave_netdev_ops;
> + ndev->ethtool_ops = &ave_ethtool_ops;
> + SET_NETDEV_DEV(ndev, dev);
> +
> + /* support hardware checksum */
> + ndev->features |= (NETIF_F_IP_CSUM | NETIF_F_RXCSUM);
> + ndev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_RXCSUM);
> +
> + ndev->max_mtu = AVE_MAX_ETHFRAME - (ETH_HLEN + ETH_FCS_LEN);
> +
> + /* get mac address */
> + mac_addr = of_get_mac_address(np);
> + if (mac_addr)
> + ether_addr_copy(ndev->dev_addr, mac_addr);
> +
> + /* if the mac address is invalid, use random mac address */
> + if (!is_valid_ether_addr(ndev->dev_addr)) {
> + eth_hw_addr_random(ndev);
> + dev_warn(dev, "Using random MAC address: %pM\n",
> + ndev->dev_addr);
> + }
> +
> + priv = netdev_priv(ndev);
> + priv->base = base;
> + priv->irq = irq;
> + priv->ndev = ndev;
> + priv->msg_enable = netif_msg_init(-1, AVE_DEFAULT_MSG_ENABLE);
> + priv->phy_mode = phy_mode;
> + priv->data = data;
> +
> + if (IS_DESC_64BIT(priv)) {
> + priv->desc_size = AVE_DESC_SIZE_64;
> + priv->tx.daddr = AVE_TXDM_64;
> + priv->rx.daddr = AVE_RXDM_64;
> + } else {
> + priv->desc_size = AVE_DESC_SIZE_32;
> + priv->tx.daddr = AVE_TXDM_32;
> + priv->rx.daddr = AVE_RXDM_32;
> + }
> + priv->tx.ndesc = AVE_NR_TXDESC;
> + priv->rx.ndesc = AVE_NR_RXDESC;
> +
> + u64_stats_init(&priv->stats_rx.syncp);
> + u64_stats_init(&priv->stats_tx.syncp);
> +
> + /* get clock */
Please remove this super-obvious comment.
> + priv->clk = clk_get(dev, NULL);
Missing clk_put() in the failure path.
Why don't you use devm?
> + if (IS_ERR(priv->clk))
> + priv->clk = NULL;
So, clk is optional, but
you need to check EPROBE_DEFER.
> + /* get reset */
Remove.
> + priv->rst = reset_control_get(dev, NULL);
> + if (IS_ERR(priv->rst))
> + priv->rst = NULL;
reset_control_get() is deprecated. Do not use it in a new driver.
Again, missing reset_control_put(). devm?
The reset seems optional (again, ignoring EPROBE_DEFER)
but you did not use reset_control_get_optional, why?
>From your code, this reset is used as shared.
priv->rst = devm_reset_control_get_optional_shared(dev, NULL);
if (IS_ERR(priv->rst))
return PTR_ERR(priv->rst);
--
Best Regards
Masahiro Yamada
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH net-next 1/5] ipv6: addrconf: cleanup locking in ipv6_add_addr
From: David Ahern @ 2017-10-15 15:24 UTC (permalink / raw)
To: Ido Schimmel; +Cc: netdev, jiri, idosch, kjlx, davem, yoshfuji
In-Reply-To: <20171015075052.GA10604@shredder.mtl.com>
On 10/15/17 1:50 AM, Ido Schimmel wrote:
> On Fri, Oct 13, 2017 at 04:02:09PM -0700, David Ahern wrote:
>> ipv6_add_addr is called in process context with rtnl lock held
>> (e.g., manual config of an address) or during softirq processing
>> (e.g., autoconf and address from a router advertisement).
>>
>> Currently, ipv6_add_addr calls rcu_read_lock_bh shortly after entry
>> and does not call unlock until exit, minus the call around the address
>> validator notifier. Similarly, addrconf_hash_lock is taken after the
>> validator notifier and held until exit. This forces the allocation of
>> inet6_ifaddr to always be atomic.
>>
>> Refactor ipv6_add_addr as follows:
>> 1. add an input boolean to discriminate the call path (process context
>> or softirq). This new flag controls whether the alloc can be done
>> with GFP_KERNEL or GFP_ATOMIC.
>>
>> 2. Move the rcu_read_lock_bh and unlock calls only around functions that
>> do rcu updates.
>>
>> 3. Remove the in6_dev_hold and put added by 3ad7d2468f79f ("Ipvlan should
>> return an error when an address is already in use."). This was done
>> presumably because rcu_read_unlock_bh needs to be called before calling
>> the validator. Since rcu_read_lock is not needed before the validator
>> runs revert the hold and put added by 3ad7d2468f79f and only do the
>> hold when setting ifp->idev.
>>
>> 4. move duplicate address check and insertion of new address in the global
>> address hash into a helper. The helper is called after an ifa is
>> allocated and filled in.
>>
>> This allows the ifa for manually configured addresses to be done with
>> GFP_KERNEL and reduces the overall amount of time with rcu_read_lock held
>> and hash table spinlock held.
>>
>> Signed-off-by: David Ahern <dsahern@gmail.com>
>
> [...]
>
>> @@ -1073,21 +1085,19 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
>>
>> in6_ifa_hold(ifa);
>> write_unlock(&idev->lock);
>> -out2:
>> +
>> rcu_read_unlock_bh();
>>
>> - if (likely(err == 0))
>> - inet6addr_notifier_call_chain(NETDEV_UP, ifa);
>> - else {
>> + inet6addr_notifier_call_chain(NETDEV_UP, ifa);
>> +out:
>> + if (unlikely(err < 0)) {
>> + if (rt)
>> + ip6_rt_put(rt);
>
> I believe 'rt' needs to be set to NULL after addrconf_dst_alloc()
> fails.
The above frees rt and the line below frees the ifa and resets the value
to an error, so after the line above rt is no longer referenced.
Taking a look at this again, I think I am missing an idev put in the
error path here.
>
>> kfree(ifa);
>> - in6_dev_put(idev);
>> ifa = ERR_PTR(err);
>> }
>>
>> return ifa;
>> -out:
>> - spin_unlock(&addrconf_hash_lock);
>> - goto out2;
>> }
^ permalink raw reply
* Re: [PATCH v9 00/20] simplify crypto wait for async op
From: Herbert Xu @ 2017-10-15 15:38 UTC (permalink / raw)
To: Gilad Ben-Yossef
Cc: Mike Snitzer, linux-doc, Gary Hook, David Howells, dm-devel,
keyrings, linux-ima-devel, Alasdair Kergon, Steffen Klassert,
Boris Brezillon, Jonathan Corbet, Alexey Kuznetsov, Mimi Zohar,
Serge E. Hallyn, Tom Lendacky, linux-cifs, linux-ima-user,
Arnaud Ebalard, linux-fscrypt, linux-mediatek, James Morris,
Matthias Brugger, Jaegeuk Kim, linux-arm-kernel, Ofir
In-Reply-To: <1508059209-25529-1-git-send-email-gilad@benyossef.com>
On Sun, Oct 15, 2017 at 10:19:45AM +0100, Gilad Ben-Yossef wrote:
>
> Changes from v8:
> - Remove the translation of EAGAIN return code to the
> previous return code of EBUSY for the user space
> interface of algif as no one seems to rely on it as
> requested by Herbert Xu.
Sorry, but I forgot to mention that EAGAIN is not a good value
to use because it's used by the network system calls for other
meanings (interrupted by a signal).
So if we stop doing the translation then we also need to pick
a different value, perhaps E2BIG or something similar that have
no current use within the crypto API or network API.
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH net-next 1/5] ipv6: addrconf: cleanup locking in ipv6_add_addr
From: Ido Schimmel @ 2017-10-15 15:59 UTC (permalink / raw)
To: David Ahern; +Cc: netdev, jiri, idosch, kjlx, davem, yoshfuji
In-Reply-To: <11052db4-0608-a11b-5d71-896a2154a96c@gmail.com>
On Sun, Oct 15, 2017 at 09:24:07AM -0600, David Ahern wrote:
> On 10/15/17 1:50 AM, Ido Schimmel wrote:
> > On Fri, Oct 13, 2017 at 04:02:09PM -0700, David Ahern wrote:
> >> ipv6_add_addr is called in process context with rtnl lock held
> >> (e.g., manual config of an address) or during softirq processing
> >> (e.g., autoconf and address from a router advertisement).
> >>
> >> Currently, ipv6_add_addr calls rcu_read_lock_bh shortly after entry
> >> and does not call unlock until exit, minus the call around the address
> >> validator notifier. Similarly, addrconf_hash_lock is taken after the
> >> validator notifier and held until exit. This forces the allocation of
> >> inet6_ifaddr to always be atomic.
> >>
> >> Refactor ipv6_add_addr as follows:
> >> 1. add an input boolean to discriminate the call path (process context
> >> or softirq). This new flag controls whether the alloc can be done
> >> with GFP_KERNEL or GFP_ATOMIC.
> >>
> >> 2. Move the rcu_read_lock_bh and unlock calls only around functions that
> >> do rcu updates.
> >>
> >> 3. Remove the in6_dev_hold and put added by 3ad7d2468f79f ("Ipvlan should
> >> return an error when an address is already in use."). This was done
> >> presumably because rcu_read_unlock_bh needs to be called before calling
> >> the validator. Since rcu_read_lock is not needed before the validator
> >> runs revert the hold and put added by 3ad7d2468f79f and only do the
> >> hold when setting ifp->idev.
> >>
> >> 4. move duplicate address check and insertion of new address in the global
> >> address hash into a helper. The helper is called after an ifa is
> >> allocated and filled in.
> >>
> >> This allows the ifa for manually configured addresses to be done with
> >> GFP_KERNEL and reduces the overall amount of time with rcu_read_lock held
> >> and hash table spinlock held.
> >>
> >> Signed-off-by: David Ahern <dsahern@gmail.com>
> >
> > [...]
> >
> >> @@ -1073,21 +1085,19 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
> >>
> >> in6_ifa_hold(ifa);
> >> write_unlock(&idev->lock);
> >> -out2:
> >> +
> >> rcu_read_unlock_bh();
> >>
> >> - if (likely(err == 0))
> >> - inet6addr_notifier_call_chain(NETDEV_UP, ifa);
> >> - else {
> >> + inet6addr_notifier_call_chain(NETDEV_UP, ifa);
> >> +out:
> >> + if (unlikely(err < 0)) {
> >> + if (rt)
> >> + ip6_rt_put(rt);
> >
> > I believe 'rt' needs to be set to NULL after addrconf_dst_alloc()
> > fails.
>
> The above frees rt and the line below frees the ifa and resets the value
> to an error, so after the line above rt is no longer referenced.
Earlier in the code we have:
rt = addrconf_dst_alloc(idev, addr, false);
if (IS_ERR(rt)) {
err = PTR_ERR(rt);
goto out;
}
So we end up calling ip6_rt_put() with an error value. I believe it
should be:
rt = addrconf_dst_alloc(idev, addr, false);
if (IS_ERR(rt)) {
err = PTR_ERR(rt);
rt = NULL;
goto out;
}
^ permalink raw reply
* Re: [PATCH net-next 1/5] ipv6: addrconf: cleanup locking in ipv6_add_addr
From: David Ahern @ 2017-10-15 16:03 UTC (permalink / raw)
To: Ido Schimmel; +Cc: netdev, jiri, idosch, kjlx, davem, yoshfuji
In-Reply-To: <20171015155938.GA24270@shredder.mtl.com>
On 10/15/17 9:59 AM, Ido Schimmel wrote:
> On Sun, Oct 15, 2017 at 09:24:07AM -0600, David Ahern wrote:
>> On 10/15/17 1:50 AM, Ido Schimmel wrote:
>>> On Fri, Oct 13, 2017 at 04:02:09PM -0700, David Ahern wrote:
>>>> ipv6_add_addr is called in process context with rtnl lock held
>>>> (e.g., manual config of an address) or during softirq processing
>>>> (e.g., autoconf and address from a router advertisement).
>>>>
>>>> Currently, ipv6_add_addr calls rcu_read_lock_bh shortly after entry
>>>> and does not call unlock until exit, minus the call around the address
>>>> validator notifier. Similarly, addrconf_hash_lock is taken after the
>>>> validator notifier and held until exit. This forces the allocation of
>>>> inet6_ifaddr to always be atomic.
>>>>
>>>> Refactor ipv6_add_addr as follows:
>>>> 1. add an input boolean to discriminate the call path (process context
>>>> or softirq). This new flag controls whether the alloc can be done
>>>> with GFP_KERNEL or GFP_ATOMIC.
>>>>
>>>> 2. Move the rcu_read_lock_bh and unlock calls only around functions that
>>>> do rcu updates.
>>>>
>>>> 3. Remove the in6_dev_hold and put added by 3ad7d2468f79f ("Ipvlan should
>>>> return an error when an address is already in use."). This was done
>>>> presumably because rcu_read_unlock_bh needs to be called before calling
>>>> the validator. Since rcu_read_lock is not needed before the validator
>>>> runs revert the hold and put added by 3ad7d2468f79f and only do the
>>>> hold when setting ifp->idev.
>>>>
>>>> 4. move duplicate address check and insertion of new address in the global
>>>> address hash into a helper. The helper is called after an ifa is
>>>> allocated and filled in.
>>>>
>>>> This allows the ifa for manually configured addresses to be done with
>>>> GFP_KERNEL and reduces the overall amount of time with rcu_read_lock held
>>>> and hash table spinlock held.
>>>>
>>>> Signed-off-by: David Ahern <dsahern@gmail.com>
>>>
>>> [...]
>>>
>>>> @@ -1073,21 +1085,19 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
>>>>
>>>> in6_ifa_hold(ifa);
>>>> write_unlock(&idev->lock);
>>>> -out2:
>>>> +
>>>> rcu_read_unlock_bh();
>>>>
>>>> - if (likely(err == 0))
>>>> - inet6addr_notifier_call_chain(NETDEV_UP, ifa);
>>>> - else {
>>>> + inet6addr_notifier_call_chain(NETDEV_UP, ifa);
>>>> +out:
>>>> + if (unlikely(err < 0)) {
>>>> + if (rt)
>>>> + ip6_rt_put(rt);
>>>
>>> I believe 'rt' needs to be set to NULL after addrconf_dst_alloc()
>>> fails.
>>
>> The above frees rt and the line below frees the ifa and resets the value
>> to an error, so after the line above rt is no longer referenced.
>
> Earlier in the code we have:
>
> rt = addrconf_dst_alloc(idev, addr, false);
> if (IS_ERR(rt)) {
> err = PTR_ERR(rt);
> goto out;
> }
>
> So we end up calling ip6_rt_put() with an error value. I believe it
> should be:
>
> rt = addrconf_dst_alloc(idev, addr, false);
> if (IS_ERR(rt)) {
> err = PTR_ERR(rt);
> rt = NULL;
> goto out;
> }
>
gotcha. Will fix.
^ permalink raw reply
* [PATCH net-next 01/10] net: korina: optimize korina_send_packet logic
From: Roman Yeryomin @ 2017-10-15 16:22 UTC (permalink / raw)
To: netdev
Signed-off-by: Roman Yeryomin <roman@advem.lv>
---
drivers/net/ethernet/korina.c | 76 ++++++++++++++-----------------------------
1 file changed, 24 insertions(+), 52 deletions(-)
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 7cecd9dbc111..84b2654e2d06 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -200,8 +200,7 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
{
struct korina_private *lp = netdev_priv(dev);
unsigned long flags;
- u32 length;
- u32 chain_prev, chain_next;
+ u32 chain_prev, chain_next, dmandptr;
struct dma_desc *td;
spin_lock_irqsave(&lp->lock, flags);
@@ -211,10 +210,9 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
/* stop queue when full, drop pkts if queue already full */
if (lp->tx_count >= (KORINA_NUM_TDS - 2)) {
lp->tx_full = 1;
+ netif_stop_queue(dev);
- if (lp->tx_count == (KORINA_NUM_TDS - 2))
- netif_stop_queue(dev);
- else {
+ if (lp->tx_count > (KORINA_NUM_TDS - 2)) {
dev->stats.tx_dropped++;
dev_kfree_skb_any(skb);
spin_unlock_irqrestore(&lp->lock, flags);
@@ -224,66 +222,40 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
}
lp->tx_count++;
-
lp->tx_skb[lp->tx_chain_tail] = skb;
- length = skb->len;
dma_cache_wback((u32)skb->data, skb->len);
/* Setup the transmit descriptor. */
dma_cache_inv((u32) td, sizeof(*td));
+
td->ca = CPHYSADDR(skb->data);
chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK;
chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK;
- if (readl(&(lp->tx_dma_regs->dmandptr)) == 0) {
- if (lp->tx_chain_status == desc_empty) {
- /* Update tail */
- td->control = DMA_COUNT(length) |
- DMA_DESC_COF | DMA_DESC_IOF;
- /* Move tail */
- lp->tx_chain_tail = chain_next;
- /* Write to NDPTR */
- writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]),
+ dmandptr = readl(&(lp->tx_dma_regs->dmandptr));
+ /* Update tail */
+ td->control = DMA_COUNT(skb->len) | DMA_DESC_COF | DMA_DESC_IOF;
+ /* Move tail */
+ lp->tx_chain_tail = chain_next;
+
+ if (lp->tx_chain_status != desc_empty) {
+ /* Link to prev */
+ lp->td_ring[chain_prev].control &= ~DMA_DESC_COF;
+ lp->td_ring[chain_prev].link = CPHYSADDR(td);
+ }
+
+ if (!dmandptr) {
+ /* Write to NDPTR */
+ writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]),
&lp->tx_dma_regs->dmandptr);
- /* Move head to tail */
- lp->tx_chain_head = lp->tx_chain_tail;
- } else {
- /* Update tail */
- td->control = DMA_COUNT(length) |
- DMA_DESC_COF | DMA_DESC_IOF;
- /* Link to prev */
- lp->td_ring[chain_prev].control &=
- ~DMA_DESC_COF;
- /* Link to prev */
- lp->td_ring[chain_prev].link = CPHYSADDR(td);
- /* Move tail */
- lp->tx_chain_tail = chain_next;
- /* Write to NDPTR */
- writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]),
- &(lp->tx_dma_regs->dmandptr));
- /* Move head to tail */
- lp->tx_chain_head = lp->tx_chain_tail;
- lp->tx_chain_status = desc_empty;
- }
+ /* Move head to tail */
+ lp->tx_chain_head = lp->tx_chain_tail;
+ lp->tx_chain_status = desc_empty;
} else {
- if (lp->tx_chain_status == desc_empty) {
- /* Update tail */
- td->control = DMA_COUNT(length) |
- DMA_DESC_COF | DMA_DESC_IOF;
- /* Move tail */
- lp->tx_chain_tail = chain_next;
- lp->tx_chain_status = desc_filled;
- } else {
- /* Update tail */
- td->control = DMA_COUNT(length) |
- DMA_DESC_COF | DMA_DESC_IOF;
- lp->td_ring[chain_prev].control &=
- ~DMA_DESC_COF;
- lp->td_ring[chain_prev].link = CPHYSADDR(td);
- lp->tx_chain_tail = chain_next;
- }
+ lp->tx_chain_status = desc_filled;
}
+
dma_cache_wback((u32) td, sizeof(*td));
netif_trans_update(dev);
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 00/10] korina cleanups/optimizations
From: Roman Yeryomin @ 2017-10-15 16:22 UTC (permalink / raw)
To: netdev
TX optimizations have led to ~15% performance increase (35->40Mbps)
in local tx usecase (tested with iperf v3.2).
Roman Yeryomin (10):
net: korina: optimize korina_send_packet logic
net: korina: reorder functions
net: korina: introduce and use interrupt disable/enable helpers
net: korina: optimize tx/rx interrupt handlers
net: korina: remove unused korina_private members
net: korina: optimize tx descriptor flags processing
net: korina: move tx to napi context
net: korina: optimize tx_full condition
net: korina: use dma api instead of dma_cache_* functions
net: korina: bump version
drivers/net/ethernet/korina.c | 503 +++++++++++++++++-------------------------
1 file changed, 204 insertions(+), 299 deletions(-)
--
2.11.0
^ permalink raw reply
* [PATCH net-next 06/10] net: korina: optimize tx descriptor flags processing
From: Roman Yeryomin @ 2017-10-15 16:23 UTC (permalink / raw)
To: netdev
Signed-off-by: Roman Yeryomin <roman@advem.lv>
---
drivers/net/ethernet/korina.c | 23 ++++++-----------------
1 file changed, 6 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 59d4554c43c9..a076b0c49e6e 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -342,43 +342,33 @@ static void korina_tx(struct net_device *dev)
}
devcs = lp->td_ring[lp->tx_next_done].devcs;
- if ((devcs & (ETH_TX_FD | ETH_TX_LD)) !=
- (ETH_TX_FD | ETH_TX_LD)) {
- dev->stats.tx_errors++;
- dev->stats.tx_dropped++;
- /* Should never happen */
- printk(KERN_ERR "%s: split tx ignored\n",
- dev->name);
- } else if (devcs & ETH_TX_TOK) {
- dev->stats.tx_packets++;
- dev->stats.tx_bytes +=
- lp->tx_skb[lp->tx_next_done]->len;
- } else {
+ if (!(devcs & ETH_TX_TOK)) {
dev->stats.tx_errors++;
dev->stats.tx_dropped++;
/* Underflow */
if (devcs & ETH_TX_UND)
dev->stats.tx_fifo_errors++;
-
/* Oversized frame */
if (devcs & ETH_TX_OF)
dev->stats.tx_aborted_errors++;
-
/* Excessive deferrals */
if (devcs & ETH_TX_ED)
dev->stats.tx_carrier_errors++;
-
/* Collisions: medium busy */
if (devcs & ETH_TX_EC)
dev->stats.collisions++;
-
/* Late collision */
if (devcs & ETH_TX_LC)
dev->stats.tx_window_errors++;
+
+ goto next;
}
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += lp->tx_skb[lp->tx_next_done]->len;
+next:
/* We must always free the original skb */
if (lp->tx_skb[lp->tx_next_done]) {
dev_kfree_skb_any(lp->tx_skb[lp->tx_next_done]);
@@ -394,7 +384,6 @@ static void korina_tx(struct net_device *dev)
/* Go on to next transmission */
lp->tx_next_done = (lp->tx_next_done + 1) & KORINA_TDS_MASK;
td = &lp->td_ring[lp->tx_next_done];
-
}
/* Clear the DMA status register */
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 03/10] net: korina: introduce and use interrupt disable/enable helpers
From: Roman Yeryomin @ 2017-10-15 16:23 UTC (permalink / raw)
To: netdev
Signed-off-by: Roman Yeryomin <roman@advem.lv>
---
drivers/net/ethernet/korina.c | 83 +++++++++++++++++++++++++------------------
1 file changed, 48 insertions(+), 35 deletions(-)
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 5545f86aac4a..04c1a3f38a79 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -91,6 +91,10 @@
#define RD_RING_SIZE (KORINA_NUM_RDS * sizeof(struct dma_desc))
#define TD_RING_SIZE (KORINA_NUM_TDS * sizeof(struct dma_desc))
+#define KORINA_INT_TX (DMA_STAT_FINI | DMA_STAT_ERR)
+#define KORINA_INT_RX (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR)
+#define KORINA_INT_TXRX (KORINA_INT_TX | KORINA_INT_RX)
+
#define TX_TIMEOUT (6000 * HZ / 1000)
enum chain_status {
@@ -142,6 +146,38 @@ struct korina_private {
extern unsigned int idt_cpu_freq;
+static inline void korina_int_disable(u32 *dmasm, u32 ints)
+{
+ u32 tmp = readl(dmasm);
+ writel(tmp | ints, dmasm);
+}
+
+static inline void korina_int_enable(u32 *dmasm, u32 ints)
+{
+ u32 tmp = readl(dmasm);
+ writel(tmp & ~ints, dmasm);
+}
+
+static inline void korina_int_disable_tx(struct korina_private *kp)
+{
+ korina_int_disable(&kp->tx_dma_regs->dmasm, KORINA_INT_TX);
+}
+
+static inline void korina_int_disable_rx(struct korina_private *kp)
+{
+ korina_int_disable(&kp->rx_dma_regs->dmasm, KORINA_INT_RX);
+}
+
+static inline void korina_int_enable_tx(struct korina_private *kp)
+{
+ korina_int_enable(&kp->tx_dma_regs->dmasm, KORINA_INT_TX);
+}
+
+static inline void korina_int_enable_rx(struct korina_private *kp)
+{
+ korina_int_enable(&kp->rx_dma_regs->dmasm, KORINA_INT_RX);
+}
+
static inline void korina_start_dma(struct dma_reg *ch, u32 dma_addr)
{
writel(0, &ch->dmandptr);
@@ -369,9 +405,7 @@ static void korina_tx(struct net_device *dev)
dmas = readl(&lp->tx_dma_regs->dmas);
writel(~dmas, &lp->tx_dma_regs->dmas);
- writel(readl(&lp->tx_dma_regs->dmasm) &
- ~(DMA_STAT_FINI | DMA_STAT_ERR),
- &lp->tx_dma_regs->dmasm);
+ korina_int_enable_tx(lp);
spin_unlock(&lp->lock);
}
@@ -497,10 +531,7 @@ static int korina_poll(struct napi_struct *napi, int budget)
work_done = korina_rx(dev, budget);
if (work_done < budget) {
napi_complete_done(napi, work_done);
-
- writel(readl(&lp->rx_dma_regs->dmasm) &
- ~(DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR),
- &lp->rx_dma_regs->dmasm);
+ korina_int_enable_rx(lp);
}
return work_done;
}
@@ -510,15 +541,13 @@ korina_tx_dma_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
struct korina_private *lp = netdev_priv(dev);
- u32 dmas, dmasm;
+ u32 dmas;
irqreturn_t retval;
dmas = readl(&lp->tx_dma_regs->dmas);
if (dmas & (DMA_STAT_FINI | DMA_STAT_ERR)) {
- dmasm = readl(&lp->tx_dma_regs->dmasm);
- writel(dmasm | (DMA_STAT_FINI | DMA_STAT_ERR),
- &lp->tx_dma_regs->dmasm);
+ korina_int_disable_tx(lp);
korina_tx(dev);
@@ -545,15 +574,12 @@ static irqreturn_t korina_rx_dma_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
struct korina_private *lp = netdev_priv(dev);
- u32 dmas, dmasm;
+ u32 dmas;
irqreturn_t retval;
dmas = readl(&lp->rx_dma_regs->dmas);
if (dmas & (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR)) {
- dmasm = readl(&lp->rx_dma_regs->dmasm);
- writel(dmasm | (DMA_STAT_DONE |
- DMA_STAT_HALT | DMA_STAT_ERR),
- &lp->rx_dma_regs->dmasm);
+ korina_int_disable_rx(lp);
napi_schedule(&lp->napi);
@@ -803,12 +829,8 @@ static int korina_init(struct net_device *dev)
/* Start Rx DMA */
korina_start_rx(lp, &lp->rd_ring[0]);
- writel(readl(&lp->tx_dma_regs->dmasm) &
- ~(DMA_STAT_FINI | DMA_STAT_ERR),
- &lp->tx_dma_regs->dmasm);
- writel(readl(&lp->rx_dma_regs->dmasm) &
- ~(DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR),
- &lp->rx_dma_regs->dmasm);
+ korina_int_enable_tx(lp);
+ korina_int_enable_rx(lp);
/* Accept only packets destined for this Ethernet device address */
writel(ETH_ARC_AB, &lp->eth_regs->etharc);
@@ -867,12 +889,8 @@ static void korina_restart_task(struct work_struct *work)
disable_irq(lp->rx_irq);
disable_irq(lp->tx_irq);
- writel(readl(&lp->tx_dma_regs->dmasm) |
- DMA_STAT_FINI | DMA_STAT_ERR,
- &lp->tx_dma_regs->dmasm);
- writel(readl(&lp->rx_dma_regs->dmasm) |
- DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR,
- &lp->rx_dma_regs->dmasm);
+ korina_int_disable_tx(lp);
+ korina_int_disable_rx(lp);
napi_disable(&lp->napi);
@@ -947,7 +965,6 @@ static int korina_open(struct net_device *dev)
static int korina_close(struct net_device *dev)
{
struct korina_private *lp = netdev_priv(dev);
- u32 tmp;
del_timer(&lp->media_check_timer);
@@ -956,14 +973,10 @@ static int korina_close(struct net_device *dev)
disable_irq(lp->tx_irq);
korina_abort_tx(dev);
- tmp = readl(&lp->tx_dma_regs->dmasm);
- tmp = tmp | DMA_STAT_FINI | DMA_STAT_ERR;
- writel(tmp, &lp->tx_dma_regs->dmasm);
+ korina_int_disable_tx(lp);
korina_abort_rx(dev);
- tmp = readl(&lp->rx_dma_regs->dmasm);
- tmp = tmp | DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR;
- writel(tmp, &lp->rx_dma_regs->dmasm);
+ korina_int_disable_rx(lp);
napi_disable(&lp->napi);
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 04/10] net: korina: optimize tx/rx interrupt handlers
From: Roman Yeryomin @ 2017-10-15 16:23 UTC (permalink / raw)
To: netdev
Signed-off-by: Roman Yeryomin <roman@advem.lv>
---
drivers/net/ethernet/korina.c | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 04c1a3f38a79..64ae32af7539 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -542,11 +542,10 @@ korina_tx_dma_interrupt(int irq, void *dev_id)
struct net_device *dev = dev_id;
struct korina_private *lp = netdev_priv(dev);
u32 dmas;
- irqreturn_t retval;
dmas = readl(&lp->tx_dma_regs->dmas);
- if (dmas & (DMA_STAT_FINI | DMA_STAT_ERR)) {
+ if (likely(dmas & KORINA_INT_TX)) {
korina_int_disable_tx(lp);
korina_tx(dev);
@@ -559,14 +558,14 @@ korina_tx_dma_interrupt(int irq, void *dev_id)
lp->tx_chain_head = lp->tx_chain_tail;
netif_trans_update(dev);
}
- if (dmas & DMA_STAT_ERR)
- printk(KERN_ERR "%s: DMA error\n", dev->name);
- retval = IRQ_HANDLED;
- } else
- retval = IRQ_NONE;
+ if (unlikely(dmas & DMA_STAT_ERR))
+ lp->dma_halt_cnt++;
- return retval;
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
}
/* Ethernet Rx DMA interrupt */
@@ -575,22 +574,21 @@ static irqreturn_t korina_rx_dma_interrupt(int irq, void *dev_id)
struct net_device *dev = dev_id;
struct korina_private *lp = netdev_priv(dev);
u32 dmas;
- irqreturn_t retval;
dmas = readl(&lp->rx_dma_regs->dmas);
- if (dmas & (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR)) {
+
+ if (likely(dmas & KORINA_INT_RX)) {
korina_int_disable_rx(lp);
napi_schedule(&lp->napi);
- if (dmas & DMA_STAT_ERR)
- printk(KERN_ERR "%s: DMA error\n", dev->name);
+ if (unlikely(dmas & DMA_STAT_ERR))
+ lp->dma_halt_cnt++;
- retval = IRQ_HANDLED;
- } else
- retval = IRQ_NONE;
+ return IRQ_HANDLED;
+ }
- return retval;
+ return IRQ_NONE;
}
/*
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 02/10] net: korina: reorder functions
From: Roman Yeryomin @ 2017-10-15 16:22 UTC (permalink / raw)
To: netdev
Signed-off-by: Roman Yeryomin <roman@advem.lv>
---
drivers/net/ethernet/korina.c | 317 +++++++++++++++++++++---------------------
1 file changed, 158 insertions(+), 159 deletions(-)
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 84b2654e2d06..5545f86aac4a 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -195,6 +195,35 @@ static void korina_chain_rx(struct korina_private *lp,
korina_chain_dma(lp->rx_dma_regs, CPHYSADDR(rd));
}
+static int mdio_read(struct net_device *dev, int mii_id, int reg)
+{
+ struct korina_private *lp = netdev_priv(dev);
+ int ret;
+
+ mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+
+ writel(0, &lp->eth_regs->miimcfg);
+ writel(0, &lp->eth_regs->miimcmd);
+ writel(mii_id | reg, &lp->eth_regs->miimaddr);
+ writel(ETH_MII_CMD_SCN, &lp->eth_regs->miimcmd);
+
+ ret = (int)(readl(&lp->eth_regs->miimrdd));
+ return ret;
+}
+
+static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
+{
+ struct korina_private *lp = netdev_priv(dev);
+
+ mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+
+ writel(0, &lp->eth_regs->miimcfg);
+ writel(1, &lp->eth_regs->miimcmd);
+ writel(mii_id | reg, &lp->eth_regs->miimaddr);
+ writel(ETH_MII_CMD_SCN, &lp->eth_regs->miimcmd);
+ writel(val, &lp->eth_regs->miimwtd);
+}
+
/* transmit packet */
static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
{
@@ -264,60 +293,87 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
-static int mdio_read(struct net_device *dev, int mii_id, int reg)
+static void korina_tx(struct net_device *dev)
{
struct korina_private *lp = netdev_priv(dev);
- int ret;
+ struct dma_desc *td = &lp->td_ring[lp->tx_next_done];
+ u32 devcs;
+ u32 dmas;
- mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+ spin_lock(&lp->lock);
- writel(0, &lp->eth_regs->miimcfg);
- writel(0, &lp->eth_regs->miimcmd);
- writel(mii_id | reg, &lp->eth_regs->miimaddr);
- writel(ETH_MII_CMD_SCN, &lp->eth_regs->miimcmd);
+ /* Process all desc that are done */
+ while (IS_DMA_FINISHED(td->control)) {
+ if (lp->tx_full == 1) {
+ netif_wake_queue(dev);
+ lp->tx_full = 0;
+ }
- ret = (int)(readl(&lp->eth_regs->miimrdd));
- return ret;
-}
+ devcs = lp->td_ring[lp->tx_next_done].devcs;
+ if ((devcs & (ETH_TX_FD | ETH_TX_LD)) !=
+ (ETH_TX_FD | ETH_TX_LD)) {
+ dev->stats.tx_errors++;
+ dev->stats.tx_dropped++;
-static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
-{
- struct korina_private *lp = netdev_priv(dev);
+ /* Should never happen */
+ printk(KERN_ERR "%s: split tx ignored\n",
+ dev->name);
+ } else if (devcs & ETH_TX_TOK) {
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes +=
+ lp->tx_skb[lp->tx_next_done]->len;
+ } else {
+ dev->stats.tx_errors++;
+ dev->stats.tx_dropped++;
- mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+ /* Underflow */
+ if (devcs & ETH_TX_UND)
+ dev->stats.tx_fifo_errors++;
- writel(0, &lp->eth_regs->miimcfg);
- writel(1, &lp->eth_regs->miimcmd);
- writel(mii_id | reg, &lp->eth_regs->miimaddr);
- writel(ETH_MII_CMD_SCN, &lp->eth_regs->miimcmd);
- writel(val, &lp->eth_regs->miimwtd);
-}
+ /* Oversized frame */
+ if (devcs & ETH_TX_OF)
+ dev->stats.tx_aborted_errors++;
-/* Ethernet Rx DMA interrupt */
-static irqreturn_t korina_rx_dma_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct korina_private *lp = netdev_priv(dev);
- u32 dmas, dmasm;
- irqreturn_t retval;
+ /* Excessive deferrals */
+ if (devcs & ETH_TX_ED)
+ dev->stats.tx_carrier_errors++;
- dmas = readl(&lp->rx_dma_regs->dmas);
- if (dmas & (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR)) {
- dmasm = readl(&lp->rx_dma_regs->dmasm);
- writel(dmasm | (DMA_STAT_DONE |
- DMA_STAT_HALT | DMA_STAT_ERR),
- &lp->rx_dma_regs->dmasm);
+ /* Collisions: medium busy */
+ if (devcs & ETH_TX_EC)
+ dev->stats.collisions++;
- napi_schedule(&lp->napi);
+ /* Late collision */
+ if (devcs & ETH_TX_LC)
+ dev->stats.tx_window_errors++;
+ }
- if (dmas & DMA_STAT_ERR)
- printk(KERN_ERR "%s: DMA error\n", dev->name);
+ /* We must always free the original skb */
+ if (lp->tx_skb[lp->tx_next_done]) {
+ dev_kfree_skb_any(lp->tx_skb[lp->tx_next_done]);
+ lp->tx_skb[lp->tx_next_done] = NULL;
+ }
- retval = IRQ_HANDLED;
- } else
- retval = IRQ_NONE;
+ lp->td_ring[lp->tx_next_done].control = DMA_DESC_IOF;
+ lp->td_ring[lp->tx_next_done].devcs = ETH_TX_FD | ETH_TX_LD;
+ lp->td_ring[lp->tx_next_done].link = 0;
+ lp->td_ring[lp->tx_next_done].ca = 0;
+ lp->tx_count--;
- return retval;
+ /* Go on to next transmission */
+ lp->tx_next_done = (lp->tx_next_done + 1) & KORINA_TDS_MASK;
+ td = &lp->td_ring[lp->tx_next_done];
+
+ }
+
+ /* Clear the DMA status register */
+ dmas = readl(&lp->tx_dma_regs->dmas);
+ writel(~dmas, &lp->tx_dma_regs->dmas);
+
+ writel(readl(&lp->tx_dma_regs->dmasm) &
+ ~(DMA_STAT_FINI | DMA_STAT_ERR),
+ &lp->tx_dma_regs->dmasm);
+
+ spin_unlock(&lp->lock);
}
static int korina_rx(struct net_device *dev, int limit)
@@ -449,6 +505,68 @@ static int korina_poll(struct napi_struct *napi, int budget)
return work_done;
}
+static irqreturn_t
+korina_tx_dma_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct korina_private *lp = netdev_priv(dev);
+ u32 dmas, dmasm;
+ irqreturn_t retval;
+
+ dmas = readl(&lp->tx_dma_regs->dmas);
+
+ if (dmas & (DMA_STAT_FINI | DMA_STAT_ERR)) {
+ dmasm = readl(&lp->tx_dma_regs->dmasm);
+ writel(dmasm | (DMA_STAT_FINI | DMA_STAT_ERR),
+ &lp->tx_dma_regs->dmasm);
+
+ korina_tx(dev);
+
+ if (lp->tx_chain_status == desc_filled &&
+ (readl(&(lp->tx_dma_regs->dmandptr)) == 0)) {
+ writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]),
+ &(lp->tx_dma_regs->dmandptr));
+ lp->tx_chain_status = desc_empty;
+ lp->tx_chain_head = lp->tx_chain_tail;
+ netif_trans_update(dev);
+ }
+ if (dmas & DMA_STAT_ERR)
+ printk(KERN_ERR "%s: DMA error\n", dev->name);
+
+ retval = IRQ_HANDLED;
+ } else
+ retval = IRQ_NONE;
+
+ return retval;
+}
+
+/* Ethernet Rx DMA interrupt */
+static irqreturn_t korina_rx_dma_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct korina_private *lp = netdev_priv(dev);
+ u32 dmas, dmasm;
+ irqreturn_t retval;
+
+ dmas = readl(&lp->rx_dma_regs->dmas);
+ if (dmas & (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR)) {
+ dmasm = readl(&lp->rx_dma_regs->dmasm);
+ writel(dmasm | (DMA_STAT_DONE |
+ DMA_STAT_HALT | DMA_STAT_ERR),
+ &lp->rx_dma_regs->dmasm);
+
+ napi_schedule(&lp->napi);
+
+ if (dmas & DMA_STAT_ERR)
+ printk(KERN_ERR "%s: DMA error\n", dev->name);
+
+ retval = IRQ_HANDLED;
+ } else
+ retval = IRQ_NONE;
+
+ return retval;
+}
+
/*
* Set or clear the multicast filter for this adaptor.
*/
@@ -492,125 +610,6 @@ static void korina_multicast_list(struct net_device *dev)
spin_unlock_irqrestore(&lp->lock, flags);
}
-static void korina_tx(struct net_device *dev)
-{
- struct korina_private *lp = netdev_priv(dev);
- struct dma_desc *td = &lp->td_ring[lp->tx_next_done];
- u32 devcs;
- u32 dmas;
-
- spin_lock(&lp->lock);
-
- /* Process all desc that are done */
- while (IS_DMA_FINISHED(td->control)) {
- if (lp->tx_full == 1) {
- netif_wake_queue(dev);
- lp->tx_full = 0;
- }
-
- devcs = lp->td_ring[lp->tx_next_done].devcs;
- if ((devcs & (ETH_TX_FD | ETH_TX_LD)) !=
- (ETH_TX_FD | ETH_TX_LD)) {
- dev->stats.tx_errors++;
- dev->stats.tx_dropped++;
-
- /* Should never happen */
- printk(KERN_ERR "%s: split tx ignored\n",
- dev->name);
- } else if (devcs & ETH_TX_TOK) {
- dev->stats.tx_packets++;
- dev->stats.tx_bytes +=
- lp->tx_skb[lp->tx_next_done]->len;
- } else {
- dev->stats.tx_errors++;
- dev->stats.tx_dropped++;
-
- /* Underflow */
- if (devcs & ETH_TX_UND)
- dev->stats.tx_fifo_errors++;
-
- /* Oversized frame */
- if (devcs & ETH_TX_OF)
- dev->stats.tx_aborted_errors++;
-
- /* Excessive deferrals */
- if (devcs & ETH_TX_ED)
- dev->stats.tx_carrier_errors++;
-
- /* Collisions: medium busy */
- if (devcs & ETH_TX_EC)
- dev->stats.collisions++;
-
- /* Late collision */
- if (devcs & ETH_TX_LC)
- dev->stats.tx_window_errors++;
- }
-
- /* We must always free the original skb */
- if (lp->tx_skb[lp->tx_next_done]) {
- dev_kfree_skb_any(lp->tx_skb[lp->tx_next_done]);
- lp->tx_skb[lp->tx_next_done] = NULL;
- }
-
- lp->td_ring[lp->tx_next_done].control = DMA_DESC_IOF;
- lp->td_ring[lp->tx_next_done].devcs = ETH_TX_FD | ETH_TX_LD;
- lp->td_ring[lp->tx_next_done].link = 0;
- lp->td_ring[lp->tx_next_done].ca = 0;
- lp->tx_count--;
-
- /* Go on to next transmission */
- lp->tx_next_done = (lp->tx_next_done + 1) & KORINA_TDS_MASK;
- td = &lp->td_ring[lp->tx_next_done];
-
- }
-
- /* Clear the DMA status register */
- dmas = readl(&lp->tx_dma_regs->dmas);
- writel(~dmas, &lp->tx_dma_regs->dmas);
-
- writel(readl(&lp->tx_dma_regs->dmasm) &
- ~(DMA_STAT_FINI | DMA_STAT_ERR),
- &lp->tx_dma_regs->dmasm);
-
- spin_unlock(&lp->lock);
-}
-
-static irqreturn_t
-korina_tx_dma_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct korina_private *lp = netdev_priv(dev);
- u32 dmas, dmasm;
- irqreturn_t retval;
-
- dmas = readl(&lp->tx_dma_regs->dmas);
-
- if (dmas & (DMA_STAT_FINI | DMA_STAT_ERR)) {
- dmasm = readl(&lp->tx_dma_regs->dmasm);
- writel(dmasm | (DMA_STAT_FINI | DMA_STAT_ERR),
- &lp->tx_dma_regs->dmasm);
-
- korina_tx(dev);
-
- if (lp->tx_chain_status == desc_filled &&
- (readl(&(lp->tx_dma_regs->dmandptr)) == 0)) {
- writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]),
- &(lp->tx_dma_regs->dmandptr));
- lp->tx_chain_status = desc_empty;
- lp->tx_chain_head = lp->tx_chain_tail;
- netif_trans_update(dev);
- }
- if (dmas & DMA_STAT_ERR)
- printk(KERN_ERR "%s: DMA error\n", dev->name);
-
- retval = IRQ_HANDLED;
- } else
- retval = IRQ_NONE;
-
- return retval;
-}
-
-
static void korina_check_media(struct net_device *dev, unsigned int init_media)
{
struct korina_private *lp = netdev_priv(dev);
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 05/10] net: korina: remove unused korina_private members
From: Roman Yeryomin @ 2017-10-15 16:23 UTC (permalink / raw)
To: netdev
Signed-off-by: Roman Yeryomin <roman@advem.lv>
---
drivers/net/ethernet/korina.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 64ae32af7539..59d4554c43c9 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -118,9 +118,6 @@ struct korina_private {
struct sk_buff *rx_skb[KORINA_NUM_RDS];
int rx_next_done;
- int rx_chain_head;
- int rx_chain_tail;
- enum chain_status rx_chain_status;
int tx_next_done;
int tx_chain_head;
@@ -135,7 +132,6 @@ struct korina_private {
spinlock_t lock; /* NIC xmit lock */
int dma_halt_cnt;
- int dma_run_cnt;
struct napi_struct napi;
struct timer_list media_check_timer;
struct mii_if_info mii_if;
@@ -770,9 +766,6 @@ static int korina_alloc_ring(struct net_device *dev)
lp->rd_ring[i - 1].control |= DMA_DESC_COD;
lp->rx_next_done = 0;
- lp->rx_chain_head = 0;
- lp->rx_chain_tail = 0;
- lp->rx_chain_status = desc_empty;
return 0;
}
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 10/10] net: korina: bump version
From: Roman Yeryomin @ 2017-10-15 16:24 UTC (permalink / raw)
To: netdev
Signed-off-by: Roman Yeryomin <roman@advem.lv>
---
drivers/net/ethernet/korina.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 8fa60d1fe022..fc8e80487507 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -66,8 +66,8 @@
#include <asm/mach-rc32434/dma_v.h>
#define DRV_NAME "korina"
-#define DRV_VERSION "0.20"
-#define DRV_RELDATE "15Sep2017"
+#define DRV_VERSION "0.21"
+#define DRV_RELDATE "15Oct2017"
#define STATION_ADDRESS_HIGH(dev) (((dev)->dev_addr[0] << 8) | \
((dev)->dev_addr[1]))
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 08/10] net: korina: optimize tx_full condition
From: Roman Yeryomin @ 2017-10-15 16:24 UTC (permalink / raw)
To: netdev
Signed-off-by: Roman Yeryomin <roman@advem.lv>
---
drivers/net/ethernet/korina.c | 20 ++++----------------
1 file changed, 4 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index f606f1e01af1..9520fa1e35a2 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -124,7 +124,6 @@ struct korina_private {
int tx_chain_tail;
enum chain_status tx_chain_status;
int tx_count;
- int tx_full;
int rx_irq;
int tx_irq;
@@ -261,19 +260,10 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
td = &lp->td_ring[lp->tx_chain_tail];
- /* stop queue when full, drop pkts if queue already full */
- if (lp->tx_count >= (KORINA_NUM_TDS - 2)) {
- lp->tx_full = 1;
+ /* stop queue when full */
+ if (unlikely(lp->tx_count > (KORINA_NUM_TDS - 3)))
netif_stop_queue(dev);
- if (lp->tx_count > (KORINA_NUM_TDS - 2)) {
- dev->stats.tx_dropped++;
- dev_kfree_skb_any(skb);
-
- return NETDEV_TX_BUSY;
- }
- }
-
lp->tx_count++;
lp->tx_skb[lp->tx_chain_tail] = skb;
@@ -323,10 +313,8 @@ static void korina_tx(struct net_device *dev)
/* Process all desc that are done */
while (IS_DMA_FINISHED(td->control)) {
- if (lp->tx_full == 1) {
+ if (unlikely(lp->tx_count > (KORINA_NUM_TDS - 2)))
netif_wake_queue(dev);
- lp->tx_full = 0;
- }
devcs = lp->td_ring[lp->tx_next_done].devcs;
@@ -696,7 +684,7 @@ static int korina_alloc_ring(struct net_device *dev)
lp->td_ring[i].link = 0;
}
lp->tx_next_done = lp->tx_chain_head = lp->tx_chain_tail =
- lp->tx_full = lp->tx_count = 0;
+ lp->tx_count = 0;
lp->tx_chain_status = desc_empty;
/* Initialize the receive descriptors */
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 09/10] net: korina: use dma api instead of dma_cache_* functions
From: Roman Yeryomin @ 2017-10-15 16:24 UTC (permalink / raw)
To: netdev
Signed-off-by: Roman Yeryomin <roman@advem.lv>
---
drivers/net/ethernet/korina.c | 44 ++++++++++++++++++-------------------------
1 file changed, 18 insertions(+), 26 deletions(-)
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 9520fa1e35a2..8fa60d1fe022 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -113,6 +113,7 @@ struct korina_private {
struct dma_reg *tx_dma_regs;
struct dma_desc *td_ring; /* transmit descriptor ring */
struct dma_desc *rd_ring; /* receive descriptor ring */
+ dma_addr_t ring_dma;
struct sk_buff *tx_skb[KORINA_NUM_TDS];
struct sk_buff *rx_skb[KORINA_NUM_RDS];
@@ -257,6 +258,7 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
struct korina_private *lp = netdev_priv(dev);
u32 chain_prev, chain_next, dmandptr;
struct dma_desc *td;
+ dma_addr_t dma_addr;
td = &lp->td_ring[lp->tx_chain_tail];
@@ -267,10 +269,10 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
lp->tx_count++;
lp->tx_skb[lp->tx_chain_tail] = skb;
- dma_cache_wback((u32)skb->data, skb->len);
+ dma_addr = dma_map_single(&dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
- /* Setup the transmit descriptor. */
- dma_cache_inv((u32) td, sizeof(*td));
+ /* flush descriptor */
+ wmb();
td->ca = CPHYSADDR(skb->data);
chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK;
@@ -299,7 +301,7 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
lp->tx_chain_status = desc_filled;
}
- dma_cache_wback((u32) td, sizeof(*td));
+ dma_unmap_single(&dev->dev, dma_addr, skb->len, DMA_TO_DEVICE);
return NETDEV_TX_OK;
}
@@ -375,8 +377,6 @@ static int korina_rx(struct net_device *dev, int limit)
u32 devcs, pkt_len, dmas;
int count;
- dma_cache_inv((u32)rd, sizeof(*rd));
-
for (count = 0; count < limit; count++) {
skb = lp->rx_skb[lp->rx_next_done];
skb_new = NULL;
@@ -416,9 +416,6 @@ static int korina_rx(struct net_device *dev, int limit)
* descriptor then */
pkt_buf = (u8 *)lp->rx_skb[lp->rx_next_done]->data;
- /* invalidate the cache */
- dma_cache_inv((unsigned long)pkt_buf, pkt_len - 4);
-
/* Malloc up new buffer. */
skb_new = netdev_alloc_skb_ip_align(dev, KORINA_RBSIZE);
@@ -455,7 +452,6 @@ static int korina_rx(struct net_device *dev, int limit)
~DMA_DESC_COD;
lp->rx_next_done = (lp->rx_next_done + 1) & KORINA_RDS_MASK;
- dma_cache_wback((u32)rd, sizeof(*rd));
rd = &lp->rd_ring[lp->rx_next_done];
writel(~DMA_STAT_DONE, &lp->rx_dma_regs->dmas);
}
@@ -470,7 +466,6 @@ static int korina_rx(struct net_device *dev, int limit)
rd->devcs = 0;
skb = lp->rx_skb[lp->rx_next_done];
rd->ca = CPHYSADDR(skb->data);
- dma_cache_wback((u32)rd, sizeof(*rd));
korina_chain_rx(lp, rd);
}
@@ -676,6 +671,13 @@ static int korina_alloc_ring(struct net_device *dev)
struct sk_buff *skb;
int i;
+ lp->td_ring = dma_alloc_coherent(NULL, TD_RING_SIZE + RD_RING_SIZE,
+ &lp->ring_dma, GFP_ATOMIC);
+ if (!lp->td_ring)
+ return -ENOMEM;
+
+ lp->rd_ring = &lp->td_ring[KORINA_NUM_TDS];
+
/* Initialize the transmit descriptors */
for (i = 0; i < KORINA_NUM_TDS; i++) {
lp->td_ring[i].control = DMA_DESC_IOF;
@@ -707,6 +709,8 @@ static int korina_alloc_ring(struct net_device *dev)
lp->rx_next_done = 0;
+ wmb();
+
return 0;
}
@@ -728,6 +732,9 @@ static void korina_free_ring(struct net_device *dev)
dev_kfree_skb_any(lp->tx_skb[i]);
lp->tx_skb[i] = NULL;
}
+
+ dma_free_coherent(NULL, TD_RING_SIZE + RD_RING_SIZE,
+ lp->td_ring, lp->ring_dma);
}
/*
@@ -979,19 +986,6 @@ static int korina_probe(struct platform_device *pdev)
goto probe_err_dma_tx;
}
- lp->td_ring = kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL);
- if (!lp->td_ring) {
- rc = -ENXIO;
- goto probe_err_td_ring;
- }
-
- dma_cache_inv((unsigned long)(lp->td_ring),
- TD_RING_SIZE + RD_RING_SIZE);
-
- /* now convert TD_RING pointer to KSEG1 */
- lp->td_ring = (struct dma_desc *)KSEG1ADDR(lp->td_ring);
- lp->rd_ring = &lp->td_ring[KORINA_NUM_TDS];
-
spin_lock_init(&lp->lock);
/* just use the rx dma irq */
dev->irq = lp->rx_irq;
@@ -1026,8 +1020,6 @@ static int korina_probe(struct platform_device *pdev)
return rc;
probe_err_register:
- kfree(lp->td_ring);
-probe_err_td_ring:
iounmap(lp->tx_dma_regs);
probe_err_dma_tx:
iounmap(lp->rx_dma_regs);
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 07/10] net: korina: move tx to napi context
From: Roman Yeryomin @ 2017-10-15 16:23 UTC (permalink / raw)
To: netdev
Signed-off-by: Roman Yeryomin <roman@advem.lv>
---
drivers/net/ethernet/korina.c | 79 +++++++++++--------------------------------
1 file changed, 20 insertions(+), 59 deletions(-)
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index a076b0c49e6e..f606f1e01af1 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -185,10 +185,6 @@ static inline void korina_abort_dma(struct net_device *dev,
{
if (readl(&ch->dmac) & DMA_CHAN_RUN_BIT) {
writel(0x10, &ch->dmac);
-
- while (!(readl(&ch->dmas) & DMA_STAT_HALT))
- netif_trans_update(dev);
-
writel(0, &ch->dmas);
}
@@ -260,12 +256,9 @@ static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
{
struct korina_private *lp = netdev_priv(dev);
- unsigned long flags;
u32 chain_prev, chain_next, dmandptr;
struct dma_desc *td;
- spin_lock_irqsave(&lp->lock, flags);
-
td = &lp->td_ring[lp->tx_chain_tail];
/* stop queue when full, drop pkts if queue already full */
@@ -276,7 +269,6 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
if (lp->tx_count > (KORINA_NUM_TDS - 2)) {
dev->stats.tx_dropped++;
dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&lp->lock, flags);
return NETDEV_TX_BUSY;
}
@@ -319,9 +311,6 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
dma_cache_wback((u32) td, sizeof(*td));
- netif_trans_update(dev);
- spin_unlock_irqrestore(&lp->lock, flags);
-
return NETDEV_TX_OK;
}
@@ -332,8 +321,6 @@ static void korina_tx(struct net_device *dev)
u32 devcs;
u32 dmas;
- spin_lock(&lp->lock);
-
/* Process all desc that are done */
while (IS_DMA_FINISHED(td->control)) {
if (lp->tx_full == 1) {
@@ -389,10 +376,6 @@ static void korina_tx(struct net_device *dev)
/* Clear the DMA status register */
dmas = readl(&lp->tx_dma_regs->dmas);
writel(~dmas, &lp->tx_dma_regs->dmas);
-
- korina_int_enable_tx(lp);
-
- spin_unlock(&lp->lock);
}
static int korina_rx(struct net_device *dev, int limit)
@@ -513,67 +496,47 @@ static int korina_poll(struct napi_struct *napi, int budget)
struct net_device *dev = lp->dev;
int work_done;
+ korina_tx(dev);
+
work_done = korina_rx(dev, budget);
if (work_done < budget) {
napi_complete_done(napi, work_done);
+ spin_lock_bh(&lp->lock);
+ korina_int_enable_tx(lp);
korina_int_enable_rx(lp);
+ spin_unlock_bh(&lp->lock);
}
return work_done;
}
-static irqreturn_t
-korina_tx_dma_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct korina_private *lp = netdev_priv(dev);
- u32 dmas;
-
- dmas = readl(&lp->tx_dma_regs->dmas);
-
- if (likely(dmas & KORINA_INT_TX)) {
- korina_int_disable_tx(lp);
-
- korina_tx(dev);
-
- if (lp->tx_chain_status == desc_filled &&
- (readl(&(lp->tx_dma_regs->dmandptr)) == 0)) {
- writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]),
- &(lp->tx_dma_regs->dmandptr));
- lp->tx_chain_status = desc_empty;
- lp->tx_chain_head = lp->tx_chain_tail;
- netif_trans_update(dev);
- }
-
- if (unlikely(dmas & DMA_STAT_ERR))
- lp->dma_halt_cnt++;
-
- return IRQ_HANDLED;
- }
-
- return IRQ_NONE;
-}
-
/* Ethernet Rx DMA interrupt */
-static irqreturn_t korina_rx_dma_interrupt(int irq, void *dev_id)
+static irqreturn_t korina_dma_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
struct korina_private *lp = netdev_priv(dev);
u32 dmas;
+ unsigned long flags;
+ irqreturn_t ret = IRQ_NONE;
- dmas = readl(&lp->rx_dma_regs->dmas);
+ spin_lock_irqsave(&lp->lock, flags);
- if (likely(dmas & KORINA_INT_RX)) {
+ dmas = readl(&lp->tx_dma_regs->dmas);
+ dmas |= readl(&lp->rx_dma_regs->dmas);
+
+ if (likely(dmas & KORINA_INT_TXRX)) {
korina_int_disable_rx(lp);
+ korina_int_disable_tx(lp);
napi_schedule(&lp->napi);
if (unlikely(dmas & DMA_STAT_ERR))
lp->dma_halt_cnt++;
- return IRQ_HANDLED;
+ ret = IRQ_HANDLED;
}
- return IRQ_NONE;
+ spin_unlock_irqrestore(&lp->lock, flags);
+ return ret;
}
/*
@@ -792,8 +755,6 @@ static int korina_init(struct net_device *dev)
/* reset ethernet logic */
writel(0, &lp->eth_regs->ethintfc);
- while ((readl(&lp->eth_regs->ethintfc) & ETH_INT_FC_RIP))
- netif_trans_update(dev);
/* Enable Ethernet Interface */
writel(ETH_INT_FC_EN, &lp->eth_regs->ethintfc);
@@ -897,7 +858,7 @@ static void korina_tx_timeout(struct net_device *dev)
static void korina_poll_controller(struct net_device *dev)
{
disable_irq(dev->irq);
- korina_tx_dma_interrupt(dev->irq, dev);
+ korina_dma_interrupt(dev->irq, dev);
enable_irq(dev->irq);
}
#endif
@@ -916,14 +877,14 @@ static int korina_open(struct net_device *dev)
/* Install the interrupt handler
* that handles the Done Finished */
- ret = request_irq(lp->rx_irq, korina_rx_dma_interrupt,
+ ret = request_irq(lp->rx_irq, korina_dma_interrupt,
0, "Korina ethernet Rx", dev);
if (ret < 0) {
printk(KERN_ERR "%s: unable to get Rx DMA IRQ %d\n",
dev->name, lp->rx_irq);
goto err_release;
}
- ret = request_irq(lp->tx_irq, korina_tx_dma_interrupt,
+ ret = request_irq(lp->tx_irq, korina_dma_interrupt,
0, "Korina ethernet Tx", dev);
if (ret < 0) {
printk(KERN_ERR "%s: unable to get Tx DMA IRQ %d\n",
--
2.11.0
^ permalink raw reply related
* Re: [PATCH net-next 00/10] korina cleanups/optimizations
From: Florian Fainelli @ 2017-10-15 16:38 UTC (permalink / raw)
To: Roman Yeryomin, netdev
In-Reply-To: <20171015162226.606-1-roman@advem.lv>
On October 15, 2017 9:22:26 AM PDT, Roman Yeryomin <roman@advem.lv> wrote:
>TX optimizations have led to ~15% performance increase (35->40Mbps)
>in local tx usecase (tested with iperf v3.2).
Could you avoid empty commit messages and write a paragraph or two for each commit that explains what and why are you changing? The changes look fine but they lack any explanation.
>
>Roman Yeryomin (10):
> net: korina: optimize korina_send_packet logic
> net: korina: reorder functions
> net: korina: introduce and use interrupt disable/enable helpers
> net: korina: optimize tx/rx interrupt handlers
> net: korina: remove unused korina_private members
> net: korina: optimize tx descriptor flags processing
> net: korina: move tx to napi context
> net: korina: optimize tx_full condition
> net: korina: use dma api instead of dma_cache_* functions
> net: korina: bump version
>
>drivers/net/ethernet/korina.c | 503
>+++++++++++++++++-------------------------
> 1 file changed, 204 insertions(+), 299 deletions(-)
--
Florian
^ 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