Netdev List
 help / color / mirror / Atom feed
* [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 = <&ethphy>;
> +               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


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox