* [PATCH] Adding Agile-SD TCP module and modifying Kconfig and Makefile
From: mohamedalrshah @ 2017-08-02 4:43 UTC (permalink / raw)
To: davem; +Cc: netdev, torvalds, linux-kernel, mohamed.a.alrshah, mohamed.asnd
In-Reply-To: <stephen@networkplumber.org>
Published:
Alrshah, M.A., Othman, M., Ali, B. and Hanapi, Z.M., 2015. Agile-SD: a Linux-based
TCP congestion control algorithm for supporting high-speed and short-distance networks.
Journal of Network and Computer Applications, 55, pp.181-190.
Agile-SD is a new loss-based and RTT-independent TCP congestion
control algorithm designed to support high-speed and Short-Distance (SD)
networks. It mainly contributes the agility factor mechanism, which allows
Agile-SD to deal with small buffer sizes while reducing its sensitivity to
packet loss. Due to the use of this mechanism, Agile-SD improves the
throughput of TCP up to 50% compared to Cubic-TCP and Compound-TCP. Its
performance was evaluated using the well-known NS2 simulator to measure
the average throughput, loss ratio and fairness.
Agile-SD is designed and implemented by Mohamed A. Alrshah et al. (2015) as
a Linux kernel module in the real Linux operating system (openSUSE 42.1 Leap),
which is implemented at the Network, Parallel and Distributed Computing Laboratory,
A2.10, second floor, Block A, Faculty of Computer Science and Information Technology,
Universiti Putra Malaysia, over real PCs connected to the Internet for daily uses and
evaluation purposes.
The main motivation behind Agile-SD is to support the short-distance networks such
as local area networks and data center networks in order to increase the bandwidth
utilization over high-speed networks. Moreover, Agile-SD is introduced in support
of the open source community, where it can be used under the OpenGL agreement.
---
net/ipv4/Kconfig | 15 ++++
net/ipv4/Makefile | 1 +
net/ipv4/tcp_agilesd.c | 221 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 237 insertions(+)
create mode 100755 net/ipv4/tcp_agilesd.c
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 91a25579..22d824b1 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -677,6 +677,17 @@ config TCP_CONG_BBR
bufferbloat, policers, or AQM schemes that do not provide a delay
signal. It requires the fq ("Fair Queue") pacing packet scheduler.
+config TCP_CONG_AGILESD
+ tristate "Agile-SD Congestion control"
+ default n
+ ---help---
+
+ This is version 1.0 of Agile-SD TCP. It is a sender-side only.
+ It contributes the Agility Factor (AF) to shorten the epoch time
+ and to make TCP independent from RTT. AF reduces the sensitivity
+ to packet losses, which in turn Agile-SD to achieve better throughput
+ over high-speed networks.
+
choice
prompt "Default TCP congestion control"
default DEFAULT_CUBIC
@@ -713,6 +724,9 @@ choice
config DEFAULT_BBR
bool "BBR" if TCP_CONG_BBR=y
+
+ config DEFAULT_AGILESD
+ bool "AGILESD" if TCP_CONG_AGILESD=y
config DEFAULT_RENO
bool "Reno"
@@ -738,6 +752,7 @@ config DEFAULT_TCP_CONG
default "dctcp" if DEFAULT_DCTCP
default "cdg" if DEFAULT_CDG
default "bbr" if DEFAULT_BBR
+ default "agilesd" if DEFAULT_AGILESD
default "cubic"
config TCP_MD5SIG
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index f83de23a..33d398b5 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_INET_UDP_DIAG) += udp_diag.o
obj-$(CONFIG_INET_RAW_DIAG) += raw_diag.o
obj-$(CONFIG_NET_TCPPROBE) += tcp_probe.o
obj-$(CONFIG_TCP_CONG_BBR) += tcp_bbr.o
+obj-$(CONFIG_TCP_CONG_AGILESD) += tcp_agilesd.o
obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o
obj-$(CONFIG_TCP_CONG_CDG) += tcp_cdg.o
obj-$(CONFIG_TCP_CONG_CUBIC) += tcp_cubic.o
diff --git a/net/ipv4/tcp_agilesd.c b/net/ipv4/tcp_agilesd.c
new file mode 100755
index 00000000..fd040ff2
--- /dev/null
+++ b/net/ipv4/tcp_agilesd.c
@@ -0,0 +1,221 @@
+/* agilesd is a Loss-Based Congestion Control Algorithm for TCP v1.0.
+ * agilesd has been created by Mohamed A. Alrshah,
+ * at Faculty of Computer Science and Information Technology,
+ * Universiti Putra Malaysia.
+ * agilesd is based on the article, which is published in 2015 as below:
+ *
+ * Alrshah, M.A., Othman, M., Ali, B. and Hanapi, Z.M., 2015.
+ * Agile-SD: a Linux-based TCP congestion control algorithm for supporting high-speed and short-distance networks.
+ * Journal of Network and Computer Applications, 55, pp.181-190.
+ */
+
+/* These includes are very important to operate the algorithm under NS2. */
+//#define NS_PROTOCOL "tcp_agilesd.c"
+//#include "../ns-linux-c.h"
+//#include "../ns-linux-util.h"
+//#include <math.h>
+/* These includes are very important to operate the algorithm under NS2. */
+
+/* These includes are very important to operate the algorithm under Linux OS. */
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/math64.h>
+#include <net/tcp.h>
+//#include <linux/skbuff.h> // optional
+//#include <linux/inet_diag.h> // optional
+/* These includes are very important to operate the algorithm under Linux OS. */
+
+#define SCALE 1000 /* Scale factor to avoid fractions */
+#define Double_SCALE 1000000 /* Double_SCALE must be equal to SCALE^2 */
+#define beta 900 /* beta for multiplicative decrease */
+
+static int initial_ssthresh __read_mostly;
+//static int beta __read_mostly = 900; /*the initial value of beta is equal to 90%*/
+
+module_param(initial_ssthresh, int, 0644);
+MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold");
+//module_param(beta, int, 0444);
+//MODULE_PARM_DESC(beta, "beta for multiplicative decrease");
+
+/* agilesd Parameters */
+struct agilesdtcp {
+ u32 loss_cwnd; // congestion window at last loss.
+ u32 frac_tracer; // This is to trace the fractions of the increment.
+ u32 degraded_loss_cwnd; // loss_cwnd after degradation.
+ enum dystate{SS=0, CA=1} agilesd_tcp_status;
+};
+
+static inline void agilesdtcp_reset(struct sock *sk)
+{
+ /*After timeout loss cntRTT and baseRTT must be reset to the initial values as below */
+}
+
+/* This function is called after the first acknowledgment is received and before the congestion
+ * control algorithm will be called for the first time. If the congestion control algorithm has
+ * private data, it should initialize its private date here. */
+static void agilesdtcp_init(struct sock *sk)
+{
+ struct agilesdtcp *ca = inet_csk_ca(sk);
+
+ // If the value of initial_ssthresh is not set, snd_ssthresh will be initialized by a large value.
+ if (initial_ssthresh)
+ tcp_sk(sk)->snd_ssthresh = initial_ssthresh;
+ else
+ tcp_sk(sk)->snd_ssthresh = 0x7fffffff;
+
+ ca->loss_cwnd = 0;
+ ca->frac_tracer = 0;
+ ca->agilesd_tcp_status = SS;
+}
+
+/* This function is called whenever an ack is received and the congestion window can be increased.
+ * This is equivalent to opencwnd in tcp.cc.
+ * ack is the number of bytes that are acknowledged in the latest acknowledgment;
+ * rtt is the the rtt measured by the latest acknowledgment;
+ * in_flight is the packet in flight before the latest acknowledgment;
+ * good_ack is an indicator whether the current situation is normal (no duplicate ack, no loss and no SACK). */
+static void agilesdtcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight) //For Linux Kernel Use.
+//static void agilesdtcp_cong_avoid(struct sock *sk, u32 ack, u32 seq_rtt, u32 in_flight, int data_acked) //For NS2 Use.
+{
+ struct tcp_sock *tp = tcp_sk(sk);
+ struct agilesdtcp *ca = inet_csk_ca(sk);
+ u32 inc_factor;
+ u32 ca_inc;
+ u32 current_gap, total_gap;
+ /* The value of inc_factor is limited by lower_fl and upper_fl.
+ * The lower_fl must be always = 1. The greater the upper_fl the higher the aggressiveness.
+ * But, if upper_fl set to 1, agilesd will work exactly as newreno.
+ * We have already designed an equation to calculate the optimum upper_fl based on the given beta.
+ * This equation will be revealed once its article is published*/
+ u32 lower_fl = 1 * SCALE;
+ u32 upper_fl = 3 * SCALE;
+
+ //if (!tcp_is_cwnd_limited(sk, in_flight)) return; //For NS-2 Use, if the in flight packets not >= cwnd do nothing//
+ if (!tcp_is_cwnd_limited(sk)) return; // For Linux Kernel Use.
+
+ if (tp->snd_cwnd < tp->snd_ssthresh){
+ ca->agilesd_tcp_status = SS;
+ //tcp_slow_start(tp); //For NS-2 Use
+ tcp_slow_start(tp, in_flight); // For Linux Kernel Use.
+ }
+ else {
+ ca->agilesd_tcp_status = CA;
+
+ if (ca->loss_cwnd > ca->degraded_loss_cwnd)
+ total_gap = ca->loss_cwnd - ca->degraded_loss_cwnd;
+ else
+ total_gap = 1;
+
+ if (ca->loss_cwnd > tp->snd_cwnd)
+ current_gap = ca->loss_cwnd - tp->snd_cwnd;
+ else
+ current_gap = 0;
+
+ inc_factor = min(max(((upper_fl * current_gap) / total_gap), lower_fl), upper_fl);
+
+ ca_inc = ((inc_factor * SCALE) / tp->snd_cwnd); /* SCALE is used to avoid fractions*/
+
+ ca->frac_tracer += ca_inc; /* This in order to take the fraction increase into account */
+ if (ca->frac_tracer >= Double_SCALE) /* To take factor scale into account */
+ {
+ tp->snd_cwnd += 1;
+ ca->frac_tracer -= Double_SCALE;
+ }
+ }
+}
+
+/* This function is called when the TCP flow detects a loss.
+ * It returns the slow start threshold of a flow, after a packet loss is detected. */
+static u32 agilesdtcp_recalc_ssthresh(struct sock *sk)
+{
+ const struct tcp_sock *tp = tcp_sk(sk);
+ struct agilesdtcp *ca = inet_csk_ca(sk);
+
+ ca->loss_cwnd = tp->snd_cwnd;
+
+ if (ca->agilesd_tcp_status == CA)
+ ca->degraded_loss_cwnd = max((tp->snd_cwnd * beta) / SCALE, 2U);
+ else
+ ca->degraded_loss_cwnd = max((tp->snd_cwnd * beta) / SCALE, 2U);
+
+ ca->frac_tracer = 0;
+
+ return ca->degraded_loss_cwnd;
+}
+
+/* This function is called when the TCP flow detects a loss.
+ * It returns the congestion window of a flow, after a packet loss is detected;
+ * (for many algorithms, this will be equal to ssthresh). When a loss is detected,
+ * min_cwnd is called after ssthresh. But some others algorithms might set min_cwnd
+ * to be smaller than ssthresh. If this is the case, there will be a slow start after loss recovery. */
+//static u32 agilesdtcp_min_cwnd(const struct sock *sk)
+//{
+// return tcp_sk(sk)->snd_ssthresh;
+//}
+
+static u32 agilesdtcp_undo_cwnd(struct sock *sk)
+{
+ const struct tcp_sock *tp = tcp_sk(sk);
+ const struct agilesdtcp *ca = inet_csk_ca(sk);
+ return max(tp->snd_cwnd, ca->loss_cwnd);
+}
+
+/* This function is called when the congestion state of the TCP is changed.
+ * newstate is the state code for the state that TCP is going to be in.
+ * The possible states are listed below:
+ * The current congestion control state, which can be one of the followings:
+ * TCP_CA_Open: normal state
+ * TCP_CA_Recovery: Loss Recovery after a Fast Transmission
+ * TCP_CA_Loss: Loss Recovery after a Timeout
+ * (The following two states are not effective in TCP-Linux but is effective in Linux)
+ * TCP_CA_Disorder: duplicate packets detected, but haven't reach the threshold. So TCP shall assume that packet reordering is happening.
+ * TCP_CA_CWR: the state that congestion window is decreasing (after local congestion in NIC, or ECN and etc).
+ * It is to notify the congestion control algorithm and is used by some
+ * algorithms which turn off their special control during loss recovery. */
+static void agilesdtcp_state(struct sock *sk, u8 new_state)
+{
+ if (new_state == TCP_CA_Loss)
+ agilesdtcp_reset(inet_csk_ca(sk));
+}
+
+/* This function is called when there is an acknowledgment that acknowledges some new packets.
+ * num_acked is the number of packets that are acknowledged by this acknowledgments. */
+//static void agilesdtcp_acked(struct sock *sk, u32 num_acked, ktime_t rtt_us) //For NS2 Use.
+static void agilesdtcp_acked(struct sock *sk, u32 num_acked, s32 rtt_us) //For Linux Kernel Use.
+{
+
+}
+
+static struct tcp_congestion_ops agilesdtcp __read_mostly = {
+ .init = agilesdtcp_init,
+ .ssthresh = agilesdtcp_recalc_ssthresh, //REQUIRED
+ .cong_avoid = agilesdtcp_cong_avoid, //REQUIRED
+ .set_state = agilesdtcp_state,
+ .undo_cwnd = agilesdtcp_undo_cwnd,
+ .pkts_acked = agilesdtcp_acked,
+ .owner = THIS_MODULE,
+ .name = "agilesd", //REQUIRED
+ //.min_cwnd = agilesdtcp_min_cwnd, //NOT REQUIRED
+};
+
+static int __init agilesdtcp_register(void)
+{
+ BUILD_BUG_ON(sizeof(struct agilesdtcp) > ICSK_CA_PRIV_SIZE);
+ return tcp_register_congestion_control(&agilesdtcp);
+}
+
+static void __exit agilesdtcp_unregister(void)
+{
+ tcp_unregister_congestion_control(&agilesdtcp);
+}
+
+module_init(agilesdtcp_register);
+module_exit(agilesdtcp_unregister);
+
+MODULE_AUTHOR("Mohamed A. Alrshah <mohamed.a.alrshah@ieee.org>");
+MODULE_AUTHOR("Mohamed Othman");
+MODULE_AUTHOR("Borhanuddin Ali");
+MODULE_AUTHOR("Zurina Hanapi");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("agilesd is a Loss-Based Congestion Control Algorithm for TCP v1.0. By Mohamed A. Alrshah");
+MODULE_VERSION("1.0");
--
2.12.3
^ permalink raw reply related
* Re: [PATCH] iwlwifi: Demote messages about fw flags size to info
From: Luca Coelho @ 2017-08-02 4:46 UTC (permalink / raw)
To: João Paulo Rechi Vita
Cc: linuxwifi, kvalo@codeaurora.org, jprvita@gmail.com,
Berg, Johannes, Grumbach, Emmanuel,
linux-wireless@vger.kernel.org, linux@endlessm.com,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <CAOcMMifW4mVPj1TVkzQPdvT0YO6p1DUObNinzWv2_ZtCbfk9Mg@mail.gmail.com>
Hi João Paulo,
On Tue, 2017-08-01 at 15:58 -0700, João Paulo Rechi Vita wrote:
> Hello Luca,
>
> On Mon, Jul 24, 2017 at 4:01 AM, Coelho, Luciano
> <luciano.coelho@intel.com> wrote:
> > On Fri, 2017-07-21 at 07:51 -0700, João Paulo Rechi Vita wrote:
>
> (...)
>
> > > Currently these messages are presented to the user during boot if there
> > > is no bootsplash covering the console, sometimes even if the boot splash
> > > is enabled but has not started yet by the time this message is shown.
> > >
>
> I should have provided another piece of information here: all of this
> happens even when booting with the 'quiet' kernel parameter.
Oh, okay, that's annoying.
> > This specific case is harmless, but I'd rather keep this message as an
> > error, because in other situations it could lead to unexpected
> > behavioir, so I prefer to keep it very visible.
> >
> >
>
> I see your point, and I understand the purpose of these messages. I'm
> wondering if perhaps having them at the warning level would give them
> enough visibility, while still keeping a clean boot process to the end
> user. If so, I can send an updated patch.
>
> Thanks for your reply and for pointing to the fix for the root cause
> of that message.
Sure, I agree it's better to make it use IWL_WARN(), which will generate
a dev_warn() instead of a dev_err().
--
Cheers,
Luca.
^ permalink raw reply
* Re: [PATCH] Adding Agile-SD TCP module and modifying Kconfig and Makefile
From: David Miller @ 2017-08-02 5:47 UTC (permalink / raw)
To: mohamed.asnd; +Cc: netdev, torvalds, linux-kernel, mohamed.a.alrshah
In-Reply-To: <20170802043701.13507-1-mohamed.asnd@gmail.com>
From: mohamedalrshah <mohamed.asnd@gmail.com>
Date: Wed, 2 Aug 2017 12:37:01 +0800
> +//#define NS_PROTOCOL "tcp_agilesd.c"
> +//#include "../ns-linux-c.h"
> +//#include "../ns-linux-util.h"
> +//#include <math.h>
There is no way this submission will be considered seriously with all of
this cruft in it.
Your new module needs significant cleanups.
^ permalink raw reply
* Re: [RFC 0/1] tcp: constify congestion_ops
From: Florian Westphal @ 2017-08-02 6:00 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Stephen Hemminger
In-Reply-To: <20170802024943.7517-1-sthemmin@microsoft.com>
Stephen Hemminger <stephen@networkplumber.org> wrote:
> I wonder if restricting congestion control choices is still necessary?
> It seems like being overly paranoid, and better enforced by having a more
> limited kernel config, seccomp or other mechanism.
Agree, I think it can be removed.
^ permalink raw reply
* [PATCH v3 00/11] Add the internal phy support
From: David Wu @ 2017-08-02 6:15 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, heiko-4mtYJXux2i+zQB+pC5nmwQ,
andrew-g2DYL2Zd6BY, f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
olof-nZhT3qVonbNeoWH0uzbU5w, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
arnd-r2nGTMty4D4
Cc: peppe.cavallaro-qxv4g6HH51o, alexandre.torgue-qxv4g6HH51o,
huangtao-TNX95d0MmH7DzftRWevZcw, hwg-TNX95d0MmH7DzftRWevZcw,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Wu
The rk3228 and rk3328 support internal phy inside, let's enable
it to work. And the internal phy need to do some special setting, so
register the rockchip internal phy driver.
David Wu (11):
net: phy: Add rockchip phy driver support
multi_v7_defconfig: Make rockchip phy built-in
arm64: defconfig: Enable CONFIG_ROCKCHIP_PHY
net: stmmac: dwmac-rk: Remove unwanted code for rk3328_set_to_rmii()
net: stmmac: dwmac-rk: Add internal phy support
net: stmmac: dwmac-rk: Add internal phy support for rk3228
net: stmmac: dwmac-rk: Add internal phy supprot for rk3328
ARM: dts: rk322x: Add support internal phy for gmac
ARM: dts: rk3228-evb: Enable the internal phy for gmac
ARM64: dts: rockchip: Add gmac2phy node support for rk3328
ARM64: dts: rockchip: Enable gmac2phy for rk3328-evb
.../devicetree/bindings/net/rockchip-dwmac.txt | 6 +-
arch/arm/boot/dts/rk3228-evb.dts | 20 ++
arch/arm/boot/dts/rk322x.dtsi | 8 +-
arch/arm/configs/multi_v7_defconfig | 1 +
arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 17 ++
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 25 +++
arch/arm64/configs/defconfig | 1 +
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 122 ++++++++++-
drivers/net/phy/Kconfig | 5 +
drivers/net/phy/Makefile | 1 +
drivers/net/phy/rockchip.c | 229 +++++++++++++++++++++
11 files changed, 424 insertions(+), 11 deletions(-)
create mode 100644 drivers/net/phy/rockchip.c
--
1.9.1
--
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
* [PATCH v3 01/11] net: phy: Add rockchip phy driver support
From: David Wu @ 2017-08-02 6:15 UTC (permalink / raw)
To: davem, heiko, andrew, f.fainelli, robh+dt, mark.rutland,
catalin.marinas, will.deacon, olof, linux, arnd
Cc: peppe.cavallaro, alexandre.torgue, huangtao, hwg, netdev,
linux-arm-kernel, linux-rockchip, devicetree, linux-kernel,
David Wu
In-Reply-To: <1501654546-17292-1-git-send-email-david.wu@rock-chips.com>
Support internal ethernet phy currently.
Signed-off-by: David Wu <david.wu@rock-chips.com>
---
drivers/net/phy/Kconfig | 5 +
drivers/net/phy/Makefile | 1 +
drivers/net/phy/rockchip.c | 229 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 235 insertions(+)
create mode 100644 drivers/net/phy/rockchip.c
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 2dda720..22cc702 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -334,6 +334,11 @@ config REALTEK_PHY
---help---
Supports the Realtek 821x PHY.
+config ROCKCHIP_PHY
+ tristate "Driver for Rockchip Ethernet PHYs"
+ ---help---
+ Currently supports the internal Ethernet PHY.
+
config SMSC_PHY
tristate "SMSC PHYs"
---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 8e9b9f3..350520e 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_MICROSEMI_PHY) += mscc.o
obj-$(CONFIG_NATIONAL_PHY) += national.o
obj-$(CONFIG_QSEMI_PHY) += qsemi.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
+obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
obj-$(CONFIG_SMSC_PHY) += smsc.o
obj-$(CONFIG_STE10XP) += ste10Xp.o
obj-$(CONFIG_TERANETICS_PHY) += teranetics.o
diff --git a/drivers/net/phy/rockchip.c b/drivers/net/phy/rockchip.c
new file mode 100644
index 0000000..c1f07d6
--- /dev/null
+++ b/drivers/net/phy/rockchip.c
@@ -0,0 +1,229 @@
+/**
+ * drivers/net/phy/rockchip.c
+ *
+ * Driver for ROCKCHIP Ethernet PHYs
+ *
+ * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * David Wu <david.wu@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/phy.h>
+#include <linux/netdevice.h>
+
+#define MII_INTERNAL_CTRL_STATUS 17
+#define SMI_ADDR_TSTCNTL 20
+#define SMI_ADDR_TSTREAD1 21
+#define SMI_ADDR_TSTREAD2 22
+#define SMI_ADDR_TSTWRITE 23
+#define MII_SPECIAL_CONTROL_STATUS 31
+
+#define MII_AUTO_MDIX_EN BIT(7)
+#define MII_MDIX_EN BIT(6)
+
+#define MII_SPEED_10 BIT(2)
+#define MII_SPEED_100 BIT(3)
+
+#define TSTCNTL_RD (BIT(15) | BIT(10))
+#define TSTCNTL_WR (BIT(14) | BIT(10))
+
+#define WR_ADDR_A7CFG 0x18
+
+static int rockchip_init_tstmode(struct phy_device *phydev)
+{
+ int ret;
+
+ /* Enable access to Analog and DSP register banks */
+ ret = phy_write(phydev, SMI_ADDR_TSTCNTL, 0x0400);
+ if (ret)
+ return ret;
+
+ ret = phy_write(phydev, SMI_ADDR_TSTCNTL, 0x0000);
+ if (ret)
+ return ret;
+
+ return phy_write(phydev, SMI_ADDR_TSTCNTL, 0x0400);
+}
+
+static int rockchip_close_tstmode(struct phy_device *phydev)
+{
+ /* Back to basic register bank */
+ return phy_write(phydev, SMI_ADDR_TSTCNTL, 0x0000);
+}
+
+static int rockchip_internal_phy_analog_init(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = rockchip_init_tstmode(phydev);
+ if (ret)
+ return ret;
+
+ /*
+ * Adjust tx amplitude to make sginal better,
+ * the default value is 0x8.
+ */
+ ret = phy_write(phydev, SMI_ADDR_TSTWRITE, 0xB);
+ if (ret)
+ return ret;
+ ret = phy_write(phydev, SMI_ADDR_TSTCNTL, TSTCNTL_WR | WR_ADDR_A7CFG);
+ if (ret)
+ return ret;
+
+ return rockchip_close_tstmode(phydev);
+}
+
+static int rockchip_internal_phy_config_init(struct phy_device *phydev)
+{
+ int val, ret;
+
+ /*
+ * The auto MIDX has linked problem on some board,
+ * workround to disable auto MDIX.
+ */
+ val = phy_read(phydev, MII_INTERNAL_CTRL_STATUS);
+ if (val < 0)
+ return val;
+ val &= ~MII_AUTO_MDIX_EN;
+ ret = phy_write(phydev, MII_INTERNAL_CTRL_STATUS, val);
+ if (ret)
+ return ret;
+
+ return rockchip_internal_phy_analog_init(phydev);
+}
+
+static void rockchip_link_change_notify(struct phy_device *phydev)
+{
+ int speed = SPEED_10;
+
+ if (phydev->autoneg == AUTONEG_ENABLE) {
+ int reg = phy_read(phydev, MII_SPECIAL_CONTROL_STATUS);
+
+ if (reg < 0) {
+ phydev_err(phydev, "phy_read err: %d.\n", reg);
+ return;
+ }
+
+ if (reg & MII_SPEED_100)
+ speed = SPEED_100;
+ else if (reg & MII_SPEED_10)
+ speed = SPEED_10;
+ } else {
+ int bmcr = phy_read(phydev, MII_BMCR);
+
+ if (bmcr < 0) {
+ phydev_err(phydev, "phy_read err: %d.\n", bmcr);
+ return;
+ }
+
+ if (bmcr & BMCR_SPEED100)
+ speed = SPEED_100;
+ else
+ speed = SPEED_10;
+ }
+
+ /*
+ * If mode switch happens from 10BT to 100BT, all DSP/AFE
+ * registers are set to default values. So any AFE/DSP
+ * registers have to be re-initialized in this case.
+ */
+ if ((phydev->speed == SPEED_10) && (speed == SPEED_100)) {
+ int ret = rockchip_internal_phy_analog_init(phydev);
+ if (ret)
+ phydev_err(phydev, "rockchip_internal_phy_analog_init err: %d.\n",
+ ret);
+ }
+}
+
+static int rockchip_set_polarity(struct phy_device *phydev, int polarity)
+{
+ int reg, err, val;
+
+ /* get the current settings */
+ reg = phy_read(phydev, MII_INTERNAL_CTRL_STATUS);
+ if (reg < 0)
+ return reg;
+
+ reg &= ~MII_AUTO_MDIX_EN;
+ val = reg;
+ switch (polarity) {
+ case ETH_TP_MDI:
+ val &= ~MII_MDIX_EN;
+ break;
+ case ETH_TP_MDI_X:
+ val |= MII_MDIX_EN;
+ break;
+ case ETH_TP_MDI_AUTO:
+ case ETH_TP_MDI_INVALID:
+ default:
+ return 0;
+ }
+
+ if (val != reg) {
+ /* Set the new polarity value in the register */
+ err = phy_write(phydev, MII_INTERNAL_CTRL_STATUS, val);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int rockchip_config_aneg(struct phy_device *phydev)
+{
+ int err;
+
+ err = rockchip_set_polarity(phydev, phydev->mdix);
+ if (err < 0)
+ return err;
+
+ return genphy_config_aneg(phydev);
+}
+
+static int rockchip_phy_resume(struct phy_device *phydev)
+{
+ genphy_resume(phydev);
+
+ return rockchip_internal_phy_config_init(phydev);
+}
+
+static struct phy_driver rockchip_phy_driver[] = {
+{
+ .phy_id = 0x1234d400,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Rockchip internal EPHY",
+ .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause
+ | SUPPORTED_Asym_Pause),
+ .flags = PHY_IS_INTERNAL,
+ .link_change_notify = rockchip_link_change_notify,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rockchip_internal_phy_config_init,
+ .config_aneg = rockchip_config_aneg,
+ .read_status = genphy_read_status,
+ .suspend = genphy_suspend,
+ .resume = rockchip_phy_resume,
+},
+};
+
+module_phy_driver(rockchip_phy_driver);
+
+static struct mdio_device_id __maybe_unused rockchip_phy_tbl[] = {
+ { 0x1234d400, 0xfffffff0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(mdio, rockchip_phy_tbl);
+
+MODULE_AUTHOR("David Wu <david.wu@rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip Ethernet PHY driver");
+MODULE_LICENSE("GPL v2");
--
1.9.1
^ permalink raw reply related
* [PATCH v3 02/11] multi_v7_defconfig: Make rockchip phy built-in
From: David Wu @ 2017-08-02 6:15 UTC (permalink / raw)
To: davem, heiko, andrew, f.fainelli, robh+dt, mark.rutland,
catalin.marinas, will.deacon, olof, linux, arnd
Cc: peppe.cavallaro, alexandre.torgue, huangtao, hwg, netdev,
linux-arm-kernel, linux-rockchip, devicetree, linux-kernel,
David Wu
In-Reply-To: <1501654546-17292-1-git-send-email-david.wu@rock-chips.com>
Enable the rockchip phy for multi_v7_defconfig builds.
Signed-off-by: David Wu <david.wu@rock-chips.com>
---
arch/arm/configs/multi_v7_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 4d19c1b..94d7e71 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -270,6 +270,7 @@ CONFIG_ICPLUS_PHY=y
CONFIG_REALTEK_PHY=y
CONFIG_MICREL_PHY=y
CONFIG_FIXED_PHY=y
+CONFIG_ROCKCHIP_PHY=y
CONFIG_USB_PEGASUS=y
CONFIG_USB_RTL8152=m
CONFIG_USB_USBNET=y
--
1.9.1
^ permalink raw reply related
* [PATCH v3 03/11] arm64: defconfig: Enable CONFIG_ROCKCHIP_PHY
From: David Wu @ 2017-08-02 6:15 UTC (permalink / raw)
To: davem, heiko, andrew, f.fainelli, robh+dt, mark.rutland,
catalin.marinas, will.deacon, olof, linux, arnd
Cc: peppe.cavallaro, alexandre.torgue, huangtao, hwg, netdev,
linux-arm-kernel, linux-rockchip, devicetree, linux-kernel,
David Wu
In-Reply-To: <1501654546-17292-1-git-send-email-david.wu@rock-chips.com>
Make the rockchip phy driver built into the kernel.
Signed-off-by: David Wu <david.wu@rock-chips.com>
---
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 6c7d147..925bd478 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -203,6 +203,7 @@ CONFIG_MARVELL_PHY=m
CONFIG_MESON_GXL_PHY=m
CONFIG_MICREL_PHY=y
CONFIG_REALTEK_PHY=m
+CONFIG_ROCKCHIP_PHY=y
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_RTL8152=m
--
1.9.1
^ permalink raw reply related
* [PATCH v3 04/11] net: stmmac: dwmac-rk: Remove unwanted code for rk3328_set_to_rmii()
From: David Wu @ 2017-08-02 6:15 UTC (permalink / raw)
To: davem, heiko, andrew, f.fainelli, robh+dt, mark.rutland,
catalin.marinas, will.deacon, olof, linux, arnd
Cc: peppe.cavallaro, alexandre.torgue, huangtao, hwg, netdev,
linux-arm-kernel, linux-rockchip, devicetree, linux-kernel,
David Wu
In-Reply-To: <1501654546-17292-1-git-send-email-david.wu@rock-chips.com>
This is wrong setting for rk3328_set_to_rmii(), so remove it.
Signed-off-by: David Wu <david.wu@rock-chips.com>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index f0df519..a8e8fd5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -365,9 +365,6 @@ static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
RK3328_GMAC_PHY_INTF_SEL_RMII |
RK3328_GMAC_RMII_MODE);
-
- /* set MAC to RMII mode */
- regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, GRF_BIT(11));
}
static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v3 01/11] net: phy: Add rockchip phy driver support
From: Corentin Labbe @ 2017-08-02 6:20 UTC (permalink / raw)
To: David Wu
Cc: davem, heiko, andrew, f.fainelli, robh+dt, mark.rutland,
catalin.marinas, will.deacon, olof, linux, arnd, huangtao, hwg,
alexandre.torgue, devicetree, netdev, linux-kernel,
linux-rockchip, peppe.cavallaro, linux-arm-kernel
In-Reply-To: <1501654546-17292-2-git-send-email-david.wu@rock-chips.com>
Hello I have some minor comment below
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mii.h>
> +#include <linux/ethtool.h>
> +#include <linux/phy.h>
> +#include <linux/netdevice.h>
in alphabetic order please
[...]
> +static int rockchip_init_tstmode(struct phy_device *phydev)
> +{
> + int ret;
> +
> + /* Enable access to Analog and DSP register banks */
> + ret = phy_write(phydev, SMI_ADDR_TSTCNTL, 0x0400);
> + if (ret)
> + return ret;
> +
> + ret = phy_write(phydev, SMI_ADDR_TSTCNTL, 0x0000);
> + if (ret)
> + return ret;
> +
> + return phy_write(phydev, SMI_ADDR_TSTCNTL, 0x0400);
> +}
> +
> +static int rockchip_close_tstmode(struct phy_device *phydev)
> +{
> + /* Back to basic register bank */
> + return phy_write(phydev, SMI_ADDR_TSTCNTL, 0x0000);
The reuse of 0x0000 and 0x0400 seems to promote a define use
[...]
> +static struct phy_driver rockchip_phy_driver[] = {
> +{
> + .phy_id = 0x1234d400,
> + .phy_id_mask = 0xfffffff0,
> + .name = "Rockchip internal EPHY",
> + .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause
> + | SUPPORTED_Asym_Pause),
> + .flags = PHY_IS_INTERNAL,
> + .link_change_notify = rockchip_link_change_notify,
> + .soft_reset = genphy_soft_reset,
> + .config_init = rockchip_internal_phy_config_init,
> + .config_aneg = rockchip_config_aneg,
> + .read_status = genphy_read_status,
> + .suspend = genphy_suspend,
> + .resume = rockchip_phy_resume,
> +},
> +};
> +
> +module_phy_driver(rockchip_phy_driver);
> +
> +static struct mdio_device_id __maybe_unused rockchip_phy_tbl[] = {
> + { 0x1234d400, 0xfffffff0 },
Same comment for phy_id, use a define
Regards
Corentin Labbe
^ permalink raw reply
* [PATCH v3 05/11] net: stmmac: dwmac-rk: Add internal phy support
From: David Wu @ 2017-08-02 6:21 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, heiko-4mtYJXux2i+zQB+pC5nmwQ,
andrew-g2DYL2Zd6BY, f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
olof-nZhT3qVonbNeoWH0uzbU5w, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
arnd-r2nGTMty4D4
Cc: peppe.cavallaro-qxv4g6HH51o, alexandre.torgue-qxv4g6HH51o,
huangtao-TNX95d0MmH7DzftRWevZcw, hwg-TNX95d0MmH7DzftRWevZcw,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Wu
In-Reply-To: <1501654546-17292-1-git-send-email-david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
To make internal phy work, need to configure the phy_clock,
phy cru_reset and related registers.
Signed-off-by: David Wu <david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
---
.../devicetree/bindings/net/rockchip-dwmac.txt | 6 +-
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 81 ++++++++++++++++++++++
2 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
index 8f42755..ec39b31 100644
--- a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
@@ -25,7 +25,8 @@ Required properties:
- clock-names: One name for each entry in the clocks property.
- phy-mode: See ethernet.txt file in the same directory.
- pinctrl-names: Names corresponding to the numbered pinctrl states.
- - pinctrl-0: pin-control mode. can be <&rgmii_pins> or <&rmii_pins>.
+ - pinctrl-0: pin-control mode. can be <&rgmii_pins>, <&rmii_pins> or led pins
+ for internal phy mode.
- clock_in_out: For RGMII, it must be "input", means main clock(125MHz)
is not sourced from SoC's PLL, but input from PHY; For RMII, "input" means
PHY provides the reference clock(50MHz), "output" means GMAC provides the
@@ -40,6 +41,9 @@ Optional properties:
- tx_delay: Delay value for TXD timing. Range value is 0~0x7F, 0x30 as default.
- rx_delay: Delay value for RXD timing. Range value is 0~0x7F, 0x10 as default.
- phy-supply: phandle to a regulator if the PHY needs one
+ - clocks: <&cru MAC_PHY>: Clock selector for internal macphy
+ - phy-is-internal: A boolean property allows us to know that MAC will connect to
+ internal phy.
Example:
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index a8e8fd5..7b80ab9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -41,6 +41,7 @@ struct rk_gmac_ops {
void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
+ void (*internal_phy_powerup)(struct rk_priv_data *bsp_priv);
};
struct rk_priv_data {
@@ -52,6 +53,7 @@ struct rk_priv_data {
bool clk_enabled;
bool clock_input;
+ bool internal_phy;
struct clk *clk_mac;
struct clk *gmac_clkin;
@@ -61,6 +63,9 @@ struct rk_priv_data {
struct clk *clk_mac_refout;
struct clk *aclk_mac;
struct clk *pclk_mac;
+ struct clk *clk_macphy;
+
+ struct reset_control *macphy_reset;
int tx_delay;
int rx_delay;
@@ -750,6 +755,50 @@ static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
.set_rmii_speed = rk3399_set_rmii_speed,
};
+#define RK_GRF_MACPHY_CON0 0xb00
+#define RK_GRF_MACPHY_CON1 0xb04
+#define RK_GRF_MACPHY_CON2 0xb08
+#define RK_GRF_MACPHY_CON3 0xb0c
+
+#define RK_MACPHY_ENABLE GRF_BIT(0)
+#define RK_MACPHY_DISABLE GRF_CLR_BIT(0)
+#define RK_MACPHY_CFG_CLK_50M GRF_BIT(14)
+#define RK_GMAC2PHY_RMII_MODE (GRF_BIT(6) | GRF_CLR_BIT(7))
+#define RK_GRF_CON2_MACPHY_ID HIWORD_UPDATE(0x1234, 0xffff, 0)
+#define RK_GRF_CON3_MACPHY_ID HIWORD_UPDATE(0x35, 0x3f, 0)
+
+static void rk_gmac_internal_phy_powerup(struct rk_priv_data *priv)
+{
+ if (priv->ops->internal_phy_powerup)
+ priv->ops->internal_phy_powerup(priv);
+
+ regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
+ regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
+
+ regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
+ regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
+
+ if (priv->macphy_reset) {
+ /* macphy needs to be disabled before trying to reset it */
+ regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
+ if (priv->macphy_reset)
+ reset_control_assert(priv->macphy_reset);
+ usleep_range(10, 20);
+ if (priv->macphy_reset)
+ reset_control_deassert(priv->macphy_reset);
+ usleep_range(10, 20);
+ regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
+ msleep(30);
+ }
+}
+
+static void rk_gmac_internal_phy_powerdown(struct rk_priv_data *priv)
+{
+ regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
+ if (priv->macphy_reset)
+ reset_control_assert(priv->macphy_reset);
+}
+
static int gmac_clk_init(struct rk_priv_data *bsp_priv)
{
struct device *dev = &bsp_priv->pdev->dev;
@@ -803,6 +852,14 @@ static int gmac_clk_init(struct rk_priv_data *bsp_priv)
clk_set_rate(bsp_priv->clk_mac, 50000000);
}
+ if (bsp_priv->internal_phy) {
+ bsp_priv->clk_macphy = devm_clk_get(dev, "clk_macphy");
+ if (IS_ERR(bsp_priv->clk_macphy))
+ dev_err(dev, "cannot get %s clock\n", "clk_macphy");
+ else
+ clk_set_rate(bsp_priv->clk_macphy, 50000000);
+ }
+
return 0;
}
@@ -826,6 +883,9 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
bsp_priv->clk_mac_refout);
}
+ if (!IS_ERR(bsp_priv->clk_macphy))
+ clk_prepare_enable(bsp_priv->clk_macphy);
+
if (!IS_ERR(bsp_priv->aclk_mac))
clk_prepare_enable(bsp_priv->aclk_mac);
@@ -858,6 +918,9 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
bsp_priv->clk_mac_refout);
}
+ if (!IS_ERR(bsp_priv->clk_macphy))
+ clk_disable_unprepare(bsp_priv->clk_macphy);
+
if (!IS_ERR(bsp_priv->aclk_mac))
clk_disable_unprepare(bsp_priv->aclk_mac);
@@ -940,6 +1003,18 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
bsp_priv->clock_input = false;
}
+ bsp_priv->internal_phy = device_property_read_bool(dev,
+ "phy-is-internal");
+ if (bsp_priv->internal_phy) {
+ bsp_priv->macphy_reset = devm_reset_control_get(dev, "mac-phy");
+ if (IS_ERR(bsp_priv->macphy_reset)) {
+ dev_info(dev, "no macphy_reset control found\n");
+ bsp_priv->macphy_reset = NULL;
+ }
+ }
+ dev_info(dev, "internal PHY? (%s).\n",
+ bsp_priv->internal_phy ? "yes" : "no");
+
ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
if (ret) {
bsp_priv->tx_delay = 0x30;
@@ -1014,6 +1089,9 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
+ if (bsp_priv->internal_phy)
+ rk_gmac_internal_phy_powerup(bsp_priv);
+
return 0;
}
@@ -1021,6 +1099,9 @@ static void rk_gmac_powerdown(struct rk_priv_data *gmac)
{
struct device *dev = &gmac->pdev->dev;
+ if (gmac->internal_phy)
+ rk_gmac_internal_phy_powerdown(gmac);
+
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
--
1.9.1
--
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 related
* [PATCH v3 06/11] net: stmmac: dwmac-rk: Add internal phy support for rk3228
From: David Wu @ 2017-08-02 6:22 UTC (permalink / raw)
To: davem, heiko, andrew, f.fainelli, robh+dt, mark.rutland,
catalin.marinas, will.deacon, olof, linux, arnd
Cc: peppe.cavallaro, alexandre.torgue, huangtao, hwg, netdev,
linux-arm-kernel, linux-rockchip, devicetree, linux-kernel,
David Wu
In-Reply-To: <1501654546-17292-1-git-send-email-david.wu@rock-chips.com>
There is only one mac controller in rk3228, which could connect to
external phy or internal phy, use the grf_com_mux bit15 to route
external/internal phy.
Signed-off-by: David Wu <david.wu@rock-chips.com>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 7b80ab9..74cf0bb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -86,6 +86,8 @@ struct rk_priv_data {
#define RK3228_GRF_MAC_CON0 0x0900
#define RK3228_GRF_MAC_CON1 0x0904
+#define RK3228_GRF_CON_MUX 0x50
+
/* RK3228_GRF_MAC_CON0 */
#define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
#define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
@@ -111,6 +113,9 @@ struct rk_priv_data {
#define RK3228_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1)
#define RK3228_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1)
+/* RK3228_GRF_COM_MUX */
+#define RK3228_GRF_CON_MUX_GMAC_INTERNAL_PHY GRF_BIT(15)
+
static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
int tx_delay, int rx_delay)
{
@@ -191,11 +196,18 @@ static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
}
+static void rk3228_internal_phy_powerup(struct rk_priv_data *priv)
+{
+ regmap_write(priv->grf, RK3228_GRF_CON_MUX,
+ RK3228_GRF_CON_MUX_GMAC_INTERNAL_PHY);
+}
+
static const struct rk_gmac_ops rk3228_ops = {
.set_to_rgmii = rk3228_set_to_rgmii,
.set_to_rmii = rk3228_set_to_rmii,
.set_rgmii_speed = rk3228_set_rgmii_speed,
.set_rmii_speed = rk3228_set_rmii_speed,
+ .internal_phy_powerup = rk3228_internal_phy_powerup,
};
#define RK3288_GRF_SOC_CON1 0x0248
--
1.9.1
^ permalink raw reply related
* [PATCH v3 07/11] net: stmmac: dwmac-rk: Add internal phy supprot for rk3328
From: David Wu @ 2017-08-02 6:23 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, heiko-4mtYJXux2i+zQB+pC5nmwQ,
andrew-g2DYL2Zd6BY, f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
olof-nZhT3qVonbNeoWH0uzbU5w, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
arnd-r2nGTMty4D4
Cc: peppe.cavallaro-qxv4g6HH51o, alexandre.torgue-qxv4g6HH51o,
huangtao-TNX95d0MmH7DzftRWevZcw, hwg-TNX95d0MmH7DzftRWevZcw,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Wu
In-Reply-To: <1501654546-17292-1-git-send-email-david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
There are two mac controllers in the rk3328, the one connects
to external phy, and the other one connects to internal phy.
Like the mac of external phy, the internal phy's mac also needs to
configure the related mac registers at GRF.
Signed-off-by: David Wu <david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 74cf0bb..83471f3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -323,6 +323,8 @@ static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
#define RK3328_GRF_MAC_CON0 0x0900
#define RK3328_GRF_MAC_CON1 0x0904
+#define RK3328_GRF_MAC_CON2 0x0908
+#define RK3328_GRF_MACPHY_CON1 0xb04
/* RK3328_GRF_MAC_CON0 */
#define RK3328_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
@@ -349,6 +351,9 @@ static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
#define RK3328_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1)
#define RK3328_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(0)
+/* RK3328_GRF_MACPHY_CON1 */
+#define RK3328_MACPHY_RMII_MODE GRF_BIT(9)
+
static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
int tx_delay, int rx_delay)
{
@@ -373,13 +378,17 @@ static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
{
struct device *dev = &bsp_priv->pdev->dev;
+ unsigned int reg;
if (IS_ERR(bsp_priv->grf)) {
dev_err(dev, "Missing rockchip,grf property\n");
return;
}
- regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+ reg = bsp_priv->internal_phy ? RK3328_GRF_MAC_CON2 :
+ RK3328_GRF_MAC_CON1;
+
+ regmap_write(bsp_priv->grf, reg,
RK3328_GMAC_PHY_INTF_SEL_RMII |
RK3328_GMAC_RMII_MODE);
}
@@ -409,29 +418,40 @@ static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
{
struct device *dev = &bsp_priv->pdev->dev;
+ unsigned int reg;
if (IS_ERR(bsp_priv->grf)) {
dev_err(dev, "Missing rockchip,grf property\n");
return;
}
+ reg = bsp_priv->internal_phy ? RK3328_GRF_MAC_CON2 :
+ RK3328_GRF_MAC_CON1;
+
if (speed == 10)
- regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+ regmap_write(bsp_priv->grf, reg,
RK3328_GMAC_RMII_CLK_2_5M |
RK3328_GMAC_SPEED_10M);
else if (speed == 100)
- regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+ regmap_write(bsp_priv->grf, reg,
RK3328_GMAC_RMII_CLK_25M |
RK3328_GMAC_SPEED_100M);
else
dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
}
+static void rk3328_internal_phy_powerup(struct rk_priv_data *priv)
+{
+ regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
+ RK3328_MACPHY_RMII_MODE);
+}
+
static const struct rk_gmac_ops rk3328_ops = {
.set_to_rgmii = rk3328_set_to_rgmii,
.set_to_rmii = rk3328_set_to_rmii,
.set_rgmii_speed = rk3328_set_rgmii_speed,
.set_rmii_speed = rk3328_set_rmii_speed,
+ .internal_phy_powerup = rk3328_internal_phy_powerup,
};
#define RK3366_GRF_SOC_CON6 0x0418
--
1.9.1
--
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 related
* [PATCH v3 08/11] ARM: dts: rk322x: Add support internal phy for gmac
From: David Wu @ 2017-08-02 6:23 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, heiko-4mtYJXux2i+zQB+pC5nmwQ,
andrew-g2DYL2Zd6BY, f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
olof-nZhT3qVonbNeoWH0uzbU5w, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
arnd-r2nGTMty4D4
Cc: peppe.cavallaro-qxv4g6HH51o, alexandre.torgue-qxv4g6HH51o,
huangtao-TNX95d0MmH7DzftRWevZcw, hwg-TNX95d0MmH7DzftRWevZcw,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Wu
In-Reply-To: <1501654546-17292-1-git-send-email-david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
This patch adds internal mac phy clock and internal mac phy reset
for rk gmac using.
Signed-off-by: David Wu <david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
---
arch/arm/boot/dts/rk322x.dtsi | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index f3e4ffd..3778f7d 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -611,13 +611,13 @@
clocks = <&cru SCLK_MAC>, <&cru SCLK_MAC_RX>,
<&cru SCLK_MAC_TX>, <&cru SCLK_MAC_REF>,
<&cru SCLK_MAC_REFOUT>, <&cru ACLK_GMAC>,
- <&cru PCLK_GMAC>;
+ <&cru PCLK_GMAC>, <&cru SCLK_MAC_PHY>;
clock-names = "stmmaceth", "mac_clk_rx",
"mac_clk_tx", "clk_mac_ref",
"clk_mac_refout", "aclk_mac",
- "pclk_mac";
- resets = <&cru SRST_GMAC>;
- reset-names = "stmmaceth";
+ "pclk_mac", "clk_macphy";
+ resets = <&cru SRST_GMAC>, <&cru SRST_MACPHY>;
+ reset-names = "stmmaceth", "mac-phy";
rockchip,grf = <&grf>;
status = "disabled";
};
--
1.9.1
--
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 related
* [PATCH v3 09/11] ARM: dts: rk3228-evb: Enable the internal phy for gmac
From: David Wu @ 2017-08-02 6:24 UTC (permalink / raw)
To: davem, heiko, andrew, f.fainelli, robh+dt, mark.rutland,
catalin.marinas, will.deacon, olof, linux, arnd
Cc: peppe.cavallaro, alexandre.torgue, huangtao, hwg, netdev,
linux-arm-kernel, linux-rockchip, devicetree, linux-kernel,
David Wu
In-Reply-To: <1501654546-17292-1-git-send-email-david.wu@rock-chips.com>
This patch enables the internal phy for rk3228 evb board
by default.
To use the external 1000M phy on evb board, need to make
some switch of evb board to be on.
Signed-off-by: David Wu <david.wu@rock-chips.com>
---
arch/arm/boot/dts/rk3228-evb.dts | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/arch/arm/boot/dts/rk3228-evb.dts b/arch/arm/boot/dts/rk3228-evb.dts
index 5883433..48b3adb 100644
--- a/arch/arm/boot/dts/rk3228-evb.dts
+++ b/arch/arm/boot/dts/rk3228-evb.dts
@@ -50,6 +50,16 @@
device_type = "memory";
reg = <0x60000000 0x40000000>;
};
+
+ vcc_phy: vcc-phy-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ regulator-name = "vcc_phy";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
};
&emmc {
@@ -60,6 +70,16 @@
status = "okay";
};
+&gmac {
+ assigned-clocks = <&cru SCLK_MAC_SRC>;
+ assigned-clock-rates = <50000000>;
+ clock_in_out = "output";
+ phy-supply = <&vcc_phy>;
+ phy-mode = "rmii";
+ phy-is-internal;
+ status = "okay";
+};
+
&tsadc {
status = "okay";
--
1.9.1
^ permalink raw reply related
* [PATCH v3 10/11] ARM64: dts: rockchip: Add gmac2phy node support for rk3328
From: David Wu @ 2017-08-02 6:24 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, heiko-4mtYJXux2i+zQB+pC5nmwQ,
andrew-g2DYL2Zd6BY, f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
olof-nZhT3qVonbNeoWH0uzbU5w, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
arnd-r2nGTMty4D4
Cc: peppe.cavallaro-qxv4g6HH51o, alexandre.torgue-qxv4g6HH51o,
huangtao-TNX95d0MmH7DzftRWevZcw, hwg-TNX95d0MmH7DzftRWevZcw,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Wu
In-Reply-To: <1501654546-17292-1-git-send-email-david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
The gmac2phy controller of rk3328 is connected to internal phy
directly inside, add the node for the internal phy support.
Signed-off-by: David Wu <david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
---
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 0be96ce..51c8c66 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -63,6 +63,8 @@
i2c1 = &i2c1;
i2c2 = &i2c2;
i2c3 = &i2c3;
+ ethernet0 = &gmac2io;
+ ethernet1 = &gmac2phy;
};
cpus {
@@ -424,6 +426,29 @@
status = "disabled";
};
+ gmac2phy: eth@ff550000 {
+ compatible = "rockchip,rk3328-gmac";
+ reg = <0x0 0xff550000 0x0 0x10000>;
+ rockchip,grf = <&grf>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ clocks = <&cru SCLK_MAC2PHY_SRC>, <&cru SCLK_MAC2PHY_RXTX>,
+ <&cru SCLK_MAC2PHY_RXTX>, <&cru SCLK_MAC2PHY_REF>,
+ <&cru ACLK_MAC2PHY>, <&cru PCLK_MAC2PHY>,
+ <&cru SCLK_MAC2PHY_OUT>;
+ clock-names = "stmmaceth", "mac_clk_rx",
+ "mac_clk_tx", "clk_mac_ref",
+ "aclk_mac", "pclk_mac",
+ "clk_macphy";
+ resets = <&cru SRST_GMAC2PHY_A>, <&cru SRST_MACPHY>;
+ reset-names = "stmmaceth", "mac-phy";
+ phy-mode = "rmii";
+ phy-is-internal;
+ pinctrl-names = "default";
+ pinctrl-0 = <&fephyled_rxm1 &fephyled_linkm1>;
+ status = "disabled";
+ };
+
gic: interrupt-controller@ff811000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
--
1.9.1
--
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 related
* [PATCH v3 11/11] ARM64: dts: rockchip: Enable gmac2phy for rk3328-evb
From: David Wu @ 2017-08-02 6:26 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, heiko-4mtYJXux2i+zQB+pC5nmwQ,
andrew-g2DYL2Zd6BY, f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
olof-nZhT3qVonbNeoWH0uzbU5w, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
arnd-r2nGTMty4D4
Cc: peppe.cavallaro-qxv4g6HH51o, alexandre.torgue-qxv4g6HH51o,
huangtao-TNX95d0MmH7DzftRWevZcw, hwg-TNX95d0MmH7DzftRWevZcw,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Wu
In-Reply-To: <1501654546-17292-1-git-send-email-david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
Enable the gmac2phy, make the gmac2phy work on
the rk3328-evb board.
Signed-off-by: David Wu <david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
---
arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
index cf27239..b9f36da 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
@@ -50,6 +50,23 @@
chosen {
stdout-path = "serial2:1500000n8";
};
+
+ vcc_phy: vcc-phy-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_phy";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&gmac2phy {
+ phy-supply = <&vcc_phy>;
+ clock_in_out = "output";
+ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>;
+ assigned-clock-rate = <50000000>;
+ assigned-clocks = <&cru SCLK_MAC2PHY>;
+ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>;
+ status = "okay";
};
&uart2 {
--
1.9.1
--
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 related
* [PATCH net-next 0/2] bpf: add support for sys_{enter|exit}_* tracepoints
From: Yonghong Song @ 2017-08-02 6:30 UTC (permalink / raw)
To: peterz, ast, daniel, netdev; +Cc: kernel-team
Currently, bpf programs cannot be attached to sys_enter_* and sys_exit_*
style tracepoints. The main reason is that syscalls/sys_enter_* and syscalls/sys_exit_*
tracepoints are treated differently from other tracepoints and there
is no bpf hook to it.
This patch set adds bpf support for these syscalls tracepoints and also
adds a test case for it.
Yonghong Song (2):
bpf: add support for sys_enter_* and sys_exit_* tracepoints
bpf: add a test case for syscalls/sys_{enter|exit}_* tracepoints
kernel/events/core.c | 9 ++++--
kernel/trace/trace_syscalls.c | 53 ++++++++++++++++++++++++++++++--
samples/bpf/Makefile | 4 +++
samples/bpf/syscall_tp_kern.c | 62 +++++++++++++++++++++++++++++++++++++
samples/bpf/syscall_tp_user.c | 71 +++++++++++++++++++++++++++++++++++++++++++
5 files changed, 194 insertions(+), 5 deletions(-)
create mode 100644 samples/bpf/syscall_tp_kern.c
create mode 100644 samples/bpf/syscall_tp_user.c
--
2.9.4
^ permalink raw reply
* [PATCH net-next 1/2] bpf: add support for sys_{enter|exit}_* tracepoints
From: Yonghong Song @ 2017-08-02 6:30 UTC (permalink / raw)
To: peterz, ast, daniel, netdev; +Cc: kernel-team
In-Reply-To: <20170802063005.3220186-1-yhs@fb.com>
Currently, bpf programs cannot be attached to sys_enter_* and sys_exit_*
style tracepoints. The iovisor/bcc issue #748
(https://github.com/iovisor/bcc/issues/748) documents this issue.
For example, if you try to attach a bpf program to tracepoints
syscalls/sys_enter_newfstat, you will get the following error:
# ./tools/trace.py t:syscalls:sys_enter_newfstat
Ioctl(PERF_EVENT_IOC_SET_BPF): Invalid argument
Failed to attach BPF to tracepoint
The main reason is that syscalls/sys_enter_* and syscalls/sys_exit_*
tracepoints are treated differently from other tracepoints and there
is no bpf hook to it.
This patch adds bpf support for these syscalls tracepoints by
. permitting bpf attachment in ioctl PERF_EVENT_IOC_SET_BPF
. calling bpf programs in perf_syscall_enter and perf_syscall_exit
Signed-off-by: Yonghong Song <yhs@fb.com>
---
kernel/events/core.c | 9 +++++---
kernel/trace/trace_syscalls.c | 53 +++++++++++++++++++++++++++++++++++++++++--
2 files changed, 57 insertions(+), 5 deletions(-)
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 426c2ff..623c977 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -8050,7 +8050,7 @@ static void perf_event_free_bpf_handler(struct perf_event *event)
static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd)
{
- bool is_kprobe, is_tracepoint;
+ bool is_cap_any, is_kprobe, is_tracepoint;
struct bpf_prog *prog;
if (event->attr.type != PERF_TYPE_TRACEPOINT)
@@ -8059,9 +8059,11 @@ static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd)
if (event->tp_event->prog)
return -EEXIST;
+ /* currently, CAP_ANY only for sys_enter_* and sys_exit_* tracepoints */
+ is_cap_any = event->tp_event->flags & TRACE_EVENT_FL_CAP_ANY;
is_kprobe = event->tp_event->flags & TRACE_EVENT_FL_UKPROBE;
is_tracepoint = event->tp_event->flags & TRACE_EVENT_FL_TRACEPOINT;
- if (!is_kprobe && !is_tracepoint)
+ if (!is_cap_any && !is_kprobe && !is_tracepoint)
/* bpf programs can only be attached to u/kprobe or tracepoint */
return -EINVAL;
@@ -8070,7 +8072,8 @@ static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd)
return PTR_ERR(prog);
if ((is_kprobe && prog->type != BPF_PROG_TYPE_KPROBE) ||
- (is_tracepoint && prog->type != BPF_PROG_TYPE_TRACEPOINT)) {
+ (is_tracepoint && prog->type != BPF_PROG_TYPE_TRACEPOINT) ||
+ (is_cap_any && prog->type != BPF_PROG_TYPE_TRACEPOINT)) {
/* valid fd, but invalid bpf program type */
bpf_prog_put(prog);
return -EINVAL;
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index 5e10395..3bd9e1c 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -559,11 +559,29 @@ static DECLARE_BITMAP(enabled_perf_exit_syscalls, NR_syscalls);
static int sys_perf_refcount_enter;
static int sys_perf_refcount_exit;
+static int perf_call_bpf_enter(struct bpf_prog *prog, struct pt_regs *regs,
+ struct syscall_metadata *sys_data,
+ struct syscall_trace_enter *rec) {
+ struct syscall_tp_t {
+ unsigned long long regs;
+ unsigned long syscall_nr;
+ unsigned long args[6]; /* maximum 6 arguments */
+ } param;
+ int i;
+
+ *(struct pt_regs **)¶m = regs;
+ param.syscall_nr = rec->nr;
+ for (i = 0; i < sys_data->nb_args && i < 6; i++)
+ param.args[i] = rec->args[i];
+ return trace_call_bpf(prog, ¶m);
+}
+
static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
{
struct syscall_metadata *sys_data;
struct syscall_trace_enter *rec;
struct hlist_head *head;
+ struct bpf_prog *prog;
int syscall_nr;
int rctx;
int size;
@@ -578,8 +596,9 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
if (!sys_data)
return;
+ prog = READ_ONCE(sys_data->enter_event->prog);
head = this_cpu_ptr(sys_data->enter_event->perf_events);
- if (hlist_empty(head))
+ if (!prog && hlist_empty(head))
return;
/* get the size after alignment with the u32 buffer size field */
@@ -594,6 +613,13 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
rec->nr = syscall_nr;
syscall_get_arguments(current, regs, 0, sys_data->nb_args,
(unsigned long *)&rec->args);
+
+ if ((prog && !perf_call_bpf_enter(prog, regs, sys_data, rec)) ||
+ hlist_empty(head)) {
+ perf_swevent_put_recursion_context(rctx);
+ return;
+ }
+
perf_trace_buf_submit(rec, size, rctx,
sys_data->enter_event->event.type, 1, regs,
head, NULL);
@@ -633,11 +659,26 @@ static void perf_sysenter_disable(struct trace_event_call *call)
mutex_unlock(&syscall_trace_lock);
}
+static int perf_call_bpf_exit(struct bpf_prog *prog, struct pt_regs *regs,
+ struct syscall_trace_exit *rec) {
+ struct syscall_tp_t {
+ unsigned long long regs;
+ unsigned long syscall_nr;
+ unsigned long ret;
+ } param;
+
+ *(struct pt_regs **)¶m = regs;
+ param.syscall_nr = rec->nr;
+ param.ret = rec->ret;
+ return trace_call_bpf(prog, ¶m);
+}
+
static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
{
struct syscall_metadata *sys_data;
struct syscall_trace_exit *rec;
struct hlist_head *head;
+ struct bpf_prog *prog;
int syscall_nr;
int rctx;
int size;
@@ -652,8 +693,9 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
if (!sys_data)
return;
+ prog = READ_ONCE(sys_data->exit_event->prog);
head = this_cpu_ptr(sys_data->exit_event->perf_events);
- if (hlist_empty(head))
+ if (!prog && hlist_empty(head))
return;
/* We can probably do that at build time */
@@ -666,6 +708,13 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
rec->nr = syscall_nr;
rec->ret = syscall_get_return_value(current, regs);
+
+ if ((prog && !perf_call_bpf_exit(prog, regs, rec)) ||
+ hlist_empty(head)) {
+ perf_swevent_put_recursion_context(rctx);
+ return;
+ }
+
perf_trace_buf_submit(rec, size, rctx, sys_data->exit_event->event.type,
1, regs, head, NULL);
}
--
2.9.4
^ permalink raw reply related
* [PATCH net-next 2/2] bpf: add a test case for syscalls/sys_{enter|exit}_* tracepoints
From: Yonghong Song @ 2017-08-02 6:30 UTC (permalink / raw)
To: peterz, ast, daniel, netdev; +Cc: kernel-team
In-Reply-To: <20170802063005.3220186-1-yhs@fb.com>
Signed-off-by: Yonghong Song <yhs@fb.com>
---
samples/bpf/Makefile | 4 +++
samples/bpf/syscall_tp_kern.c | 62 +++++++++++++++++++++++++++++++++++++
samples/bpf/syscall_tp_user.c | 71 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 137 insertions(+)
create mode 100644 samples/bpf/syscall_tp_kern.c
create mode 100644 samples/bpf/syscall_tp_user.c
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 770d46c..f1010fe 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -39,6 +39,7 @@ hostprogs-y += per_socket_stats_example
hostprogs-y += load_sock_ops
hostprogs-y += xdp_redirect
hostprogs-y += xdp_redirect_map
+hostprogs-y += syscall_tp
# Libbpf dependencies
LIBBPF := ../../tools/lib/bpf/bpf.o
@@ -82,6 +83,7 @@ test_map_in_map-objs := bpf_load.o $(LIBBPF) test_map_in_map_user.o
per_socket_stats_example-objs := $(LIBBPF) cookie_uid_helper_example.o
xdp_redirect-objs := bpf_load.o $(LIBBPF) xdp_redirect_user.o
xdp_redirect_map-objs := bpf_load.o $(LIBBPF) xdp_redirect_map_user.o
+syscall_tp-objs := bpf_load.o $(LIBBPF) syscall_tp_user.o
# Tell kbuild to always build the programs
always := $(hostprogs-y)
@@ -125,6 +127,7 @@ always += tcp_iw_kern.o
always += tcp_clamp_kern.o
always += xdp_redirect_kern.o
always += xdp_redirect_map_kern.o
+always += syscall_tp_kern.o
HOSTCFLAGS += -I$(objtree)/usr/include
HOSTCFLAGS += -I$(srctree)/tools/lib/
@@ -163,6 +166,7 @@ HOSTLOADLIBES_xdp_tx_iptunnel += -lelf
HOSTLOADLIBES_test_map_in_map += -lelf
HOSTLOADLIBES_xdp_redirect += -lelf
HOSTLOADLIBES_xdp_redirect_map += -lelf
+HOSTLOADLIBES_syscall_tp += -lelf
# Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline:
# make samples/bpf/ LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang
diff --git a/samples/bpf/syscall_tp_kern.c b/samples/bpf/syscall_tp_kern.c
new file mode 100644
index 0000000..9149c52
--- /dev/null
+++ b/samples/bpf/syscall_tp_kern.c
@@ -0,0 +1,62 @@
+/* Copyright (c) 2017 Facebook
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+#include <uapi/linux/bpf.h>
+#include "bpf_helpers.h"
+
+struct syscalls_enter_open_args {
+ unsigned long long unused;
+ long syscall_nr;
+ long filename_ptr;
+ long flags;
+ long mode;
+};
+
+struct syscalls_exit_open_args {
+ unsigned long long unused;
+ long syscall_nr;
+ long ret;
+};
+
+struct bpf_map_def SEC("maps") enter_open_map = {
+ .type = BPF_MAP_TYPE_ARRAY,
+ .key_size = sizeof(u32),
+ .value_size = sizeof(u32),
+ .max_entries = 1,
+};
+
+struct bpf_map_def SEC("maps") exit_open_map = {
+ .type = BPF_MAP_TYPE_ARRAY,
+ .key_size = sizeof(u32),
+ .value_size = sizeof(u32),
+ .max_entries = 1,
+};
+
+static __always_inline void count(void *map)
+{
+ u32 key = 0;
+ u32 *value, init_val = 1;
+
+ value = bpf_map_lookup_elem(map, &key);
+ if (value)
+ *value += 1;
+ else
+ bpf_map_update_elem(map, &key, &init_val, BPF_NOEXIST);
+}
+
+SEC("tracepoint/syscalls/sys_enter_open")
+int trace_enter_open(struct syscalls_enter_open_args *ctx)
+{
+ count((void *)&enter_open_map);
+ return 0;
+}
+
+SEC("tracepoint/syscalls/sys_exit_open")
+int trace_enter_exit(struct syscalls_exit_open_args *ctx)
+{
+ count((void *)&exit_open_map);
+ return 0;
+}
diff --git a/samples/bpf/syscall_tp_user.c b/samples/bpf/syscall_tp_user.c
new file mode 100644
index 0000000..a3cb91e
--- /dev/null
+++ b/samples/bpf/syscall_tp_user.c
@@ -0,0 +1,71 @@
+/* Copyright (c) 2017 Facebook
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <linux/bpf.h>
+#include <string.h>
+#include <linux/perf_event.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdbool.h>
+#include <sys/resource.h>
+#include "libbpf.h"
+#include "bpf_load.h"
+
+/* This program verifies bpf attachment to tracepoint sys_enter_* and sys_exit_*.
+ * This requires kernel CONFIG_FTRACE_SYSCALLS to be set.
+ */
+
+static void verify_map(int map_id)
+{
+ __u32 key = 0;
+ __u32 val;
+
+ if (bpf_map_lookup_elem(map_id, &key, &val) != 0) {
+ fprintf(stderr, "map_lookup failed: %s\n", strerror(errno));
+ return;
+ }
+ if (val == 0)
+ fprintf(stderr, "failed: map #%d returns value 0\n", map_id);
+}
+
+int main(int argc, char **argv)
+{
+ struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
+ char filename[256];
+ int fd;
+
+ setrlimit(RLIMIT_MEMLOCK, &r);
+ snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+
+ if (load_bpf_file(filename)) {
+ fprintf(stderr, "%s", bpf_log_buf);
+ return 1;
+ }
+
+ /* current load_bpf_file has perf_event_open default pid = -1
+ * and cpu = 0, which permits attached bpf execution on
+ * all cpus for all pid's. bpf program execution ignores
+ * cpu affinity.
+ */
+ /* trigger some "open" operations */
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "open failed: %s\n", strerror(errno));
+ return 1;
+ }
+ close(fd);
+
+ /* verify the map */
+ verify_map(map_fd[0]);
+ verify_map(map_fd[1]);
+
+ return 0;
+}
--
2.9.4
^ permalink raw reply related
* Re: [PATCH v2 net-next 3/4] tcp: Adjust TCP ULP to defer to sockets ULP
From: kbuild test robot @ 2017-08-02 7:12 UTC (permalink / raw)
To: Tom Herbert; +Cc: kbuild-all, netdev, rohit, davejwatson, Tom Herbert
In-Reply-To: <20170802031846.21993-4-tom@quantonium.net>
[-- Attachment #1: Type: text/plain, Size: 712 bytes --]
Hi Tom,
[auto build test ERROR on net-next/master]
url: https://github.com/0day-ci/linux/commits/Tom-Herbert/inet-include-net-sock-h-in-inet_common-h/20170802-141113
config: x86_64-rhel-7.2 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
>> make[3]: *** No rule to make target 'net/ipv4/tcp_ulp.o', needed by 'net/ipv4/built-in.o'.
make[3]: Target '__build' not remade because of errors.
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 39621 bytes --]
^ permalink raw reply
* Re: [PATCH net-next 2/4] sock: ULP infrastructure
From: kbuild test robot @ 2017-08-02 7:32 UTC (permalink / raw)
To: Tom Herbert; +Cc: kbuild-all, netdev, rohit, davejwatson, Tom Herbert
In-Reply-To: <20170802025304.1862-3-tom@quantonium.net>
[-- Attachment #1: Type: text/plain, Size: 3165 bytes --]
Hi Tom,
[auto build test ERROR on net-next/master]
url: https://github.com/0day-ci/linux/commits/Tom-Herbert/ulp-Generalize-ULP-infrastructure/20170802-142035
config: x86_64-randconfig-x019-201731 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
Note: the linux-review/Tom-Herbert/ulp-Generalize-ULP-infrastructure/20170802-142035 HEAD 5b02ebca112742fa510bc8731781090320dc34f0 builds fine.
It only hurts bisectibility.
All errors (new ones prefixed by >>):
In file included from include/net/sock.h:75:0,
from include/linux/tcp.h:23,
from include/linux/ipv6.h:85,
from include/net/ipv6.h:16,
from include/net/6lowpan.h:58,
from net//6lowpan/core.c:16:
>> include/net/ulp_sock.h:51:1: error: expected identifier or '(' before '{' token
{
^
include/net/ulp_sock.h:56:1: error: expected identifier or '(' before '{' token
{
^
include/net/ulp_sock.h:60:1: error: expected identifier or '(' before '{' token
{
^
--
In file included from include/net/sock.h:75:0,
from include/net/inet_sock.h:27,
from include/net/ip.h:30,
from include/linux/errqueue.h:5,
from net//core/sock.c:96:
>> include/net/ulp_sock.h:51:1: error: expected identifier or '(' before '{' token
{
^
include/net/ulp_sock.h:56:1: error: expected identifier or '(' before '{' token
{
^
include/net/ulp_sock.h:60:1: error: expected identifier or '(' before '{' token
{
^
net//core/sock.c: In function 'sock_getsockopt':
net//core/sock.c:1392:10: error: implicit declaration of function 'ulp_get_config' [-Werror=implicit-function-declaration]
return ulp_get_config(sk, optval, optlen);
^~~~~~~~~~~~~~
cc1: some warnings being treated as errors
--
In file included from include/net/sock.h:75:0,
from include/net/inet_sock.h:27,
from include/net/ip.h:30,
from include/linux/errqueue.h:5,
from net/core/sock.c:96:
>> include/net/ulp_sock.h:51:1: error: expected identifier or '(' before '{' token
{
^
include/net/ulp_sock.h:56:1: error: expected identifier or '(' before '{' token
{
^
include/net/ulp_sock.h:60:1: error: expected identifier or '(' before '{' token
{
^
net/core/sock.c: In function 'sock_getsockopt':
net/core/sock.c:1392:10: error: implicit declaration of function 'ulp_get_config' [-Werror=implicit-function-declaration]
return ulp_get_config(sk, optval, optlen);
^~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +51 include/net/ulp_sock.h
49
50 int ulp_get(struct sock *sk, char __user *optval, int *optlen);
> 51 {
52 return -EOPNOTSUPP;
53 }
54
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 26674 bytes --]
^ permalink raw reply
* [patch net-next] mlxsw: core: Use correct EMAD transaction ID in debug message
From: Jiri Pirko @ 2017-08-02 7:52 UTC (permalink / raw)
To: netdev; +Cc: davem, idosch, mlxsw
From: Ido Schimmel <idosch@mellanox.com>
'trans->tid' is only assigned later in the function, resulting in a zero
transaction ID. Use 'tid' instead.
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index affe84e..9d5e7cf 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -667,7 +667,7 @@ static int mlxsw_emad_reg_access(struct mlxsw_core *mlxsw_core,
int err;
dev_dbg(mlxsw_core->bus_info->dev, "EMAD reg access (tid=%llx,reg_id=%x(%s),type=%s)\n",
- trans->tid, reg->id, mlxsw_reg_id_str(reg->id),
+ tid, reg->id, mlxsw_reg_id_str(reg->id),
mlxsw_core_reg_access_type_str(type));
skb = mlxsw_emad_alloc(mlxsw_core, reg->len);
--
2.9.3
^ permalink raw reply related
* Re: [PATCH net-next 2/4] sock: ULP infrastructure
From: kbuild test robot @ 2017-08-02 7:52 UTC (permalink / raw)
To: Tom Herbert; +Cc: kbuild-all, netdev, rohit, davejwatson, Tom Herbert
In-Reply-To: <20170802025304.1862-3-tom@quantonium.net>
[-- Attachment #1: Type: text/plain, Size: 2351 bytes --]
Hi Tom,
[auto build test ERROR on net-next/master]
url: https://github.com/0day-ci/linux/commits/Tom-Herbert/ulp-Generalize-ULP-infrastructure/20170802-142035
config: x86_64-rhel (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
In file included from include/net/sock.h:75:0,
from include/net/inet_sock.h:27,
from include/net/ip.h:30,
from drivers/net/ethernet/broadcom/cnic.c:37:
include/net/ulp_sock.h:51:1: error: expected identifier or '(' before '{' token
{
^
include/net/ulp_sock.h:56:1: error: expected identifier or '(' before '{' token
{
^
include/net/ulp_sock.h:60:1: error: expected identifier or '(' before '{' token
{
^
>> drivers/net/ethernet/broadcom/cnic.c:178:20: error: conflicting types for 'ulp_get'
static inline void ulp_get(struct cnic_ulp_ops *ulp_ops)
^~~~~~~
In file included from include/net/sock.h:75:0,
from include/net/inet_sock.h:27,
from include/net/ip.h:30,
from drivers/net/ethernet/broadcom/cnic.c:37:
include/net/ulp_sock.h:50:5: note: previous declaration of 'ulp_get' was here
int ulp_get(struct sock *sk, char __user *optval, int *optlen);
^~~~~~~
vim +/ulp_get +178 drivers/net/ethernet/broadcom/cnic.c
a4636960 drivers/net/cnic.c Michael Chan 2009-06-08 177
7fc1ece4 drivers/net/cnic.c Michael Chan 2009-08-14 @178 static inline void ulp_get(struct cnic_ulp_ops *ulp_ops)
7fc1ece4 drivers/net/cnic.c Michael Chan 2009-08-14 179 {
7fc1ece4 drivers/net/cnic.c Michael Chan 2009-08-14 180 atomic_inc(&ulp_ops->ref_count);
7fc1ece4 drivers/net/cnic.c Michael Chan 2009-08-14 181 }
7fc1ece4 drivers/net/cnic.c Michael Chan 2009-08-14 182
:::::: The code at line 178 was first introduced by commit
:::::: 7fc1ece40704b150477e548a7a98d285cc418790 cnic: Fix locking in init/exit calls.
:::::: TO: Michael Chan <mchan@broadcom.com>
:::::: CC: David S. Miller <davem@davemloft.net>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 39621 bytes --]
^ permalink raw reply
* Re: [RFC 1/1] constify tcp congestion
From: Eric Dumazet @ 2017-08-02 7:56 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Stephen Hemminger
In-Reply-To: <20170802024943.7517-2-sthemmin@microsoft.com>
On Tue, 2017-08-01 at 19:49 -0700, Stephen Hemminger wrote:
> Split the TCP congestion ops structure into const and mutable portions.
> Put the list pointers, key and a copy of the flags in new tcp_congestion_entry
> structure.
...
> -void tcp_unregister_congestion_control(struct tcp_congestion_ops *ca)
> +void tcp_unregister_congestion_control(const struct tcp_congestion_ops *ca)
> {
> + struct tcp_congestion_entry *e;
> +
> spin_lock(&tcp_cong_list_lock);
> - list_del_rcu(&ca->list);
> + list_for_each_entry_rcu(e, &tcp_cong_list, list) {
> + if (e->ops == ca) {
> + list_del_rcu(&e->list);
> + kfree_rcu(e, rcu);
> + break;
> + }
> + }
> spin_unlock(&tcp_cong_list_lock);
>
Since you switched to kfree_rcu(), you could remove the
synchronize_rcu() from tcp_unregister_congestion_control()
Otherwise, no need for kfree_rcu() and the rcu head added in struct
tcp_congestion_entry :
- You could do a kfree() after the synchronize_rcu().
Also, I am not convinced this would be a good move, since you added an
extra structure which is not const anyway.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox