Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 0/4] ulp: Generalize ULP infrastructure
From: Tom Herbert @ 2017-08-02  2:53 UTC (permalink / raw)
  To: netdev; +Cc: rohit, davejwatson, Tom Herbert

Generalize the ULP infrastructure that was recently introduced to
support kTLS. This adds a SO_ULP socket option and creates new fields in
sock structure for ULP ops and ULP data. Also, the interface allows
additional per ULP parameters to be set so that a ULP can be pushed
and operations started in one shot.

This patch sets:
  - Minor dependency fix in inet_common.h
  - Implement ULP infrastructure as a socket mechanism
  - Fixes TCP and TLS to use the new method (maintaining backwards
    API compatibility)
  - Adds a ulp.txt document

Tested: Ran simple ULP.

Tom Herbert (4):
  inet: include net/sock.h in inet_common.h
  sock: ULP infrastructure
  tcp: Adjust TCP ULP to defer to sockets ULP
  ulp: Documention for ULP infrastructure

 Documentation/networking/tls.txt       |   6 +-
 Documentation/networking/ulp.txt       |  82 ++++++++++++++
 arch/alpha/include/uapi/asm/socket.h   |   2 +
 arch/frv/include/uapi/asm/socket.h     |   2 +
 arch/ia64/include/uapi/asm/socket.h    |   2 +
 arch/m32r/include/uapi/asm/socket.h    |   2 +
 arch/mips/include/uapi/asm/socket.h    |   2 +
 arch/mn10300/include/uapi/asm/socket.h |   2 +
 arch/parisc/include/uapi/asm/socket.h  |   2 +
 arch/s390/include/uapi/asm/socket.h    |   2 +
 arch/sparc/include/uapi/asm/socket.h   |   2 +
 arch/xtensa/include/uapi/asm/socket.h  |   2 +
 include/linux/socket.h                 |   9 ++
 include/net/inet_common.h              |   2 +
 include/net/inet_connection_sock.h     |   4 -
 include/net/sock.h                     |   5 +
 include/net/tcp.h                      |  25 -----
 include/net/tls.h                      |   4 +-
 include/net/ulp_sock.h                 |  65 +++++++++++
 include/uapi/asm-generic/socket.h      |   2 +
 net/Kconfig                            |   4 +
 net/core/Makefile                      |   1 +
 net/core/sock.c                        |  14 +++
 net/core/sysctl_net_core.c             |  25 +++++
 net/core/ulp_sock.c                    | 194 +++++++++++++++++++++++++++++++++
 net/ipv4/sysctl_net_ipv4.c             |   9 +-
 net/ipv4/tcp.c                         |  40 ++++---
 net/ipv4/tcp_ipv4.c                    |   2 -
 net/ipv4/tcp_ulp.c                     | 135 -----------------------
 net/tls/Kconfig                        |   1 +
 net/tls/tls_main.c                     |  21 ++--
 31 files changed, 470 insertions(+), 200 deletions(-)
 create mode 100644 Documentation/networking/ulp.txt
 create mode 100644 include/net/ulp_sock.h
 create mode 100644 net/core/ulp_sock.c
 delete mode 100644 net/ipv4/tcp_ulp.c

-- 
2.11.0

^ permalink raw reply

* [RFC 1/1] constify tcp congestion
From: Stephen Hemminger @ 2017-08-02  2:49 UTC (permalink / raw)
  To: netdev; +Cc: Stephen Hemminger
In-Reply-To: <20170802024943.7517-1-sthemmin@microsoft.com>

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.

Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>

---
 include/net/tcp.h        |  10 ++-
 net/ipv4/tcp.c           |   2 -
 net/ipv4/tcp_bbr.c       |   2 +-
 net/ipv4/tcp_bic.c       |   2 +-
 net/ipv4/tcp_cdg.c       |   2 +-
 net/ipv4/tcp_cong.c      | 162 +++++++++++++++++++++++++++++------------------
 net/ipv4/tcp_cubic.c     |   2 +-
 net/ipv4/tcp_dctcp.c     |   6 +-
 net/ipv4/tcp_highspeed.c |   2 +-
 net/ipv4/tcp_htcp.c      |   2 +-
 net/ipv4/tcp_hybla.c     |   2 +-
 net/ipv4/tcp_illinois.c  |   2 +-
 net/ipv4/tcp_lp.c        |   2 +-
 net/ipv4/tcp_nv.c        |   2 +-
 net/ipv4/tcp_scalable.c  |   2 +-
 net/ipv4/tcp_vegas.c     |   2 +-
 net/ipv4/tcp_veno.c      |   2 +-
 net/ipv4/tcp_westwood.c  |   2 +-
 net/ipv4/tcp_yeah.c      |   2 +-
 19 files changed, 124 insertions(+), 86 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index bb1881b4ce48..725395a7c6d1 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -931,8 +931,6 @@ struct rate_sample {
 };
 
 struct tcp_congestion_ops {
-	struct list_head	list;
-	u32 key;
 	u32 flags;
 
 	/* initialize private data (optional) */
@@ -970,8 +968,8 @@ struct tcp_congestion_ops {
 	struct module 	*owner;
 };
 
-int tcp_register_congestion_control(struct tcp_congestion_ops *type);
-void tcp_unregister_congestion_control(struct tcp_congestion_ops *type);
+int tcp_register_congestion_control(const struct tcp_congestion_ops *type);
+void tcp_unregister_congestion_control(const struct tcp_congestion_ops *type);
 
 void tcp_assign_congestion_control(struct sock *sk);
 void tcp_init_congestion_control(struct sock *sk);
@@ -990,9 +988,9 @@ void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked);
 u32 tcp_reno_ssthresh(struct sock *sk);
 u32 tcp_reno_undo_cwnd(struct sock *sk);
 void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 acked);
-extern struct tcp_congestion_ops tcp_reno;
+extern const struct tcp_congestion_ops tcp_reno;
 
-struct tcp_congestion_ops *tcp_ca_find_key(u32 key);
+const struct tcp_congestion_ops *tcp_ca_find_key(u32 key);
 u32 tcp_ca_get_key_by_name(const char *name, bool *ecn_ca);
 #ifdef CONFIG_INET
 char *tcp_ca_get_name_by_key(u32 key, char *buffer);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 9dd6f4dba9b1..b26eeff90cff 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3344,8 +3344,6 @@ int tcp_abort(struct sock *sk, int err)
 }
 EXPORT_SYMBOL_GPL(tcp_abort);
 
-extern struct tcp_congestion_ops tcp_reno;
-
 static __initdata unsigned long thash_entries;
 static int __init set_thash_entries(char *str)
 {
diff --git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c
index 69ee877574d0..353574dd1eb8 100644
--- a/net/ipv4/tcp_bbr.c
+++ b/net/ipv4/tcp_bbr.c
@@ -917,7 +917,7 @@ static void bbr_set_state(struct sock *sk, u8 new_state)
 	}
 }
 
-static struct tcp_congestion_ops tcp_bbr_cong_ops __read_mostly = {
+static const struct tcp_congestion_ops tcp_bbr_cong_ops = {
 	.flags		= TCP_CONG_NON_RESTRICTED,
 	.name		= "bbr",
 	.owner		= THIS_MODULE,
diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c
index 609965f0e298..8a8a3a6bde1a 100644
--- a/net/ipv4/tcp_bic.c
+++ b/net/ipv4/tcp_bic.c
@@ -209,7 +209,7 @@ static void bictcp_acked(struct sock *sk, const struct ack_sample *sample)
 	}
 }
 
-static struct tcp_congestion_ops bictcp __read_mostly = {
+static const struct tcp_congestion_ops bictcp = {
 	.init		= bictcp_init,
 	.ssthresh	= bictcp_recalc_ssthresh,
 	.cong_avoid	= bictcp_cong_avoid,
diff --git a/net/ipv4/tcp_cdg.c b/net/ipv4/tcp_cdg.c
index 50a0f3e51d5b..32e8631dd128 100644
--- a/net/ipv4/tcp_cdg.c
+++ b/net/ipv4/tcp_cdg.c
@@ -399,7 +399,7 @@ static void tcp_cdg_release(struct sock *sk)
 	kfree(ca->gradients);
 }
 
-struct tcp_congestion_ops tcp_cdg __read_mostly = {
+static const struct tcp_congestion_ops tcp_cdg = {
 	.cong_avoid = tcp_cdg_cong_avoid,
 	.cwnd_event = tcp_cdg_cwnd_event,
 	.pkts_acked = tcp_cdg_acked,
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index fde983f6376b..0d43eef045f4 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -19,13 +19,21 @@
 static DEFINE_SPINLOCK(tcp_cong_list_lock);
 static LIST_HEAD(tcp_cong_list);
 
+struct tcp_congestion_entry {
+	struct list_head	list;
+	u32 key;
+	u32 flags;
+	const struct tcp_congestion_ops *ops;
+	struct rcu_head rcu;
+};
+
 /* Simple linear search, don't expect many entries! */
-static struct tcp_congestion_ops *tcp_ca_find(const char *name)
+static struct tcp_congestion_entry *tcp_ca_find(const char *name)
 {
-	struct tcp_congestion_ops *e;
+	struct tcp_congestion_entry *e;
 
 	list_for_each_entry_rcu(e, &tcp_cong_list, list) {
-		if (strcmp(e->name, name) == 0)
+		if (strcmp(e->ops->name, name) == 0)
 			return e;
 	}
 
@@ -33,28 +41,30 @@ static struct tcp_congestion_ops *tcp_ca_find(const char *name)
 }
 
 /* Must be called with rcu lock held */
-static const struct tcp_congestion_ops *__tcp_ca_find_autoload(const char *name)
+static const struct tcp_congestion_entry *tcp_ca_find_autoload(const char *name)
 {
-	const struct tcp_congestion_ops *ca = tcp_ca_find(name);
+	const struct tcp_congestion_entry *e;
+
+	e = tcp_ca_find(name);
 #ifdef CONFIG_MODULES
-	if (!ca && capable(CAP_NET_ADMIN)) {
+	if (!e && capable(CAP_NET_ADMIN)) {
 		rcu_read_unlock();
 		request_module("tcp_%s", name);
 		rcu_read_lock();
-		ca = tcp_ca_find(name);
+		e = tcp_ca_find(name);
 	}
 #endif
-	return ca;
+	return e;
 }
 
 /* Simple linear search, not much in here. */
-struct tcp_congestion_ops *tcp_ca_find_key(u32 key)
+const struct tcp_congestion_ops *tcp_ca_find_key(u32 key)
 {
-	struct tcp_congestion_ops *e;
+	struct tcp_congestion_entry *e;
 
 	list_for_each_entry_rcu(e, &tcp_cong_list, list) {
 		if (e->key == key)
-			return e;
+			return e->ops;
 	}
 
 	return NULL;
@@ -64,8 +74,9 @@ struct tcp_congestion_ops *tcp_ca_find_key(u32 key)
  * Attach new congestion control algorithm to the list
  * of available options.
  */
-int tcp_register_congestion_control(struct tcp_congestion_ops *ca)
+int tcp_register_congestion_control(const struct tcp_congestion_ops *ca)
 {
+	struct tcp_congestion_entry *e;
 	int ret = 0;
 
 	/* all algorithms must implement these */
@@ -75,15 +86,21 @@ int tcp_register_congestion_control(struct tcp_congestion_ops *ca)
 		return -EINVAL;
 	}
 
-	ca->key = jhash(ca->name, sizeof(ca->name), strlen(ca->name));
+	e = kmalloc(sizeof(*e), GFP_KERNEL);
+	if (!e)
+		return -ENOMEM;
+
+	e->key = jhash(ca->name, sizeof(ca->name), strlen(ca->name));
+	e->ops = ca;
+	e->flags = ca->flags;
 
 	spin_lock(&tcp_cong_list_lock);
-	if (ca->key == TCP_CA_UNSPEC || tcp_ca_find_key(ca->key)) {
+	if (e->key == TCP_CA_UNSPEC || tcp_ca_find_key(e->key)) {
 		pr_notice("%s already registered or non-unique key\n",
 			  ca->name);
 		ret = -EEXIST;
 	} else {
-		list_add_tail_rcu(&ca->list, &tcp_cong_list);
+		list_add_tail_rcu(&e->list, &tcp_cong_list);
 		pr_debug("%s registered\n", ca->name);
 	}
 	spin_unlock(&tcp_cong_list_lock);
@@ -98,10 +115,18 @@ EXPORT_SYMBOL_GPL(tcp_register_congestion_control);
  * to ensure that this can't be done till all sockets using
  * that method are closed.
  */
-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);
 
 	/* Wait for outstanding readers to complete before the
@@ -117,17 +142,19 @@ EXPORT_SYMBOL_GPL(tcp_unregister_congestion_control);
 
 u32 tcp_ca_get_key_by_name(const char *name, bool *ecn_ca)
 {
-	const struct tcp_congestion_ops *ca;
+	const struct tcp_congestion_entry *e;
 	u32 key = TCP_CA_UNSPEC;
 
 	might_sleep();
 
 	rcu_read_lock();
-	ca = __tcp_ca_find_autoload(name);
-	if (ca) {
-		key = ca->key;
-		*ecn_ca = ca->flags & TCP_CONG_NEEDS_ECN;
+
+	e = tcp_ca_find_autoload(name);
+	if (e) {
+		key = e->key;
+		*ecn_ca = e->flags & TCP_CONG_NEEDS_ECN;
 	}
+
 	rcu_read_unlock();
 
 	return key;
@@ -154,10 +181,12 @@ EXPORT_SYMBOL_GPL(tcp_ca_get_name_by_key);
 void tcp_assign_congestion_control(struct sock *sk)
 {
 	struct inet_connection_sock *icsk = inet_csk(sk);
-	struct tcp_congestion_ops *ca;
+	struct tcp_congestion_entry *e;
 
 	rcu_read_lock();
-	list_for_each_entry_rcu(ca, &tcp_cong_list, list) {
+	list_for_each_entry_rcu(e, &tcp_cong_list, list) {
+		const struct tcp_congestion_ops *ca = e->ops;
+
 		if (likely(try_module_get(ca->owner))) {
 			icsk->icsk_ca_ops = ca;
 			goto out;
@@ -166,14 +195,15 @@ void tcp_assign_congestion_control(struct sock *sk)
 		 * guaranteed fallback is Reno from this list.
 		 */
 	}
-out:
-	rcu_read_unlock();
-	memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv));
 
-	if (ca->flags & TCP_CONG_NEEDS_ECN)
+out:
+	if (e->flags & TCP_CONG_NEEDS_ECN)
 		INET_ECN_xmit(sk);
 	else
 		INET_ECN_dontxmit(sk);
+
+	rcu_read_unlock();
+	memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv));
 }
 
 void tcp_init_congestion_control(struct sock *sk)
@@ -216,24 +246,24 @@ void tcp_cleanup_congestion_control(struct sock *sk)
 /* Used by sysctl to change default congestion control */
 int tcp_set_default_congestion_control(const char *name)
 {
-	struct tcp_congestion_ops *ca;
+	struct tcp_congestion_entry *e;
 	int ret = -ENOENT;
 
 	spin_lock(&tcp_cong_list_lock);
-	ca = tcp_ca_find(name);
+	e = tcp_ca_find(name);
 #ifdef CONFIG_MODULES
-	if (!ca && capable(CAP_NET_ADMIN)) {
+	if (!e && capable(CAP_NET_ADMIN)) {
 		spin_unlock(&tcp_cong_list_lock);
 
 		request_module("tcp_%s", name);
 		spin_lock(&tcp_cong_list_lock);
-		ca = tcp_ca_find(name);
+		e = tcp_ca_find(name);
 	}
 #endif
 
-	if (ca) {
-		ca->flags |= TCP_CONG_NON_RESTRICTED;	/* default is always allowed */
-		list_move(&ca->list, &tcp_cong_list);
+	if (e) {
+		e->flags |= TCP_CONG_NON_RESTRICTED;	/* default is always allowed */
+		list_move(&e->list, &tcp_cong_list);
 		ret = 0;
 	}
 	spin_unlock(&tcp_cong_list_lock);
@@ -251,14 +281,16 @@ late_initcall(tcp_congestion_default);
 /* Build string with list of available congestion control values */
 void tcp_get_available_congestion_control(char *buf, size_t maxlen)
 {
-	struct tcp_congestion_ops *ca;
+	struct tcp_congestion_entry *e;
 	size_t offs = 0;
 
 	rcu_read_lock();
-	list_for_each_entry_rcu(ca, &tcp_cong_list, list) {
+	list_for_each_entry_rcu(e, &tcp_cong_list, list) {
+		const char *name = e->ops->name;
+
 		offs += snprintf(buf + offs, maxlen - offs,
 				 "%s%s",
-				 offs == 0 ? "" : " ", ca->name);
+				 offs == 0 ? "" : " ", name);
 	}
 	rcu_read_unlock();
 }
@@ -266,30 +298,33 @@ void tcp_get_available_congestion_control(char *buf, size_t maxlen)
 /* Get current default congestion control */
 void tcp_get_default_congestion_control(char *name)
 {
-	struct tcp_congestion_ops *ca;
+	struct tcp_congestion_entry *e;
 	/* We will always have reno... */
 	BUG_ON(list_empty(&tcp_cong_list));
 
 	rcu_read_lock();
-	ca = list_entry(tcp_cong_list.next, struct tcp_congestion_ops, list);
-	strncpy(name, ca->name, TCP_CA_NAME_MAX);
+	e = list_first_entry(&tcp_cong_list, struct tcp_congestion_entry, list);
+	strncpy(name, e->ops->name, TCP_CA_NAME_MAX);
 	rcu_read_unlock();
 }
 
 /* Built list of non-restricted congestion control values */
 void tcp_get_allowed_congestion_control(char *buf, size_t maxlen)
 {
-	struct tcp_congestion_ops *ca;
+	struct tcp_congestion_entry *e;
 	size_t offs = 0;
 
 	*buf = '\0';
 	rcu_read_lock();
-	list_for_each_entry_rcu(ca, &tcp_cong_list, list) {
-		if (!(ca->flags & TCP_CONG_NON_RESTRICTED))
+	list_for_each_entry_rcu(e, &tcp_cong_list, list) {
+		const char *name = e->ops->name;
+
+		if (!(e->flags & TCP_CONG_NON_RESTRICTED))
 			continue;
+
 		offs += snprintf(buf + offs, maxlen - offs,
 				 "%s%s",
-				 offs == 0 ? "" : " ", ca->name);
+				 offs == 0 ? "" : " ", name);
 	}
 	rcu_read_unlock();
 }
@@ -297,7 +332,7 @@ void tcp_get_allowed_congestion_control(char *buf, size_t maxlen)
 /* Change list of non-restricted congestion control */
 int tcp_set_allowed_congestion_control(char *val)
 {
-	struct tcp_congestion_ops *ca;
+	struct tcp_congestion_entry *e;
 	char *saved_clone, *clone, *name;
 	int ret = 0;
 
@@ -308,23 +343,23 @@ int tcp_set_allowed_congestion_control(char *val)
 	spin_lock(&tcp_cong_list_lock);
 	/* pass 1 check for bad entries */
 	while ((name = strsep(&clone, " ")) && *name) {
-		ca = tcp_ca_find(name);
-		if (!ca) {
+		e = tcp_ca_find(name);
+		if (!e) {
 			ret = -ENOENT;
 			goto out;
 		}
 	}
 
 	/* pass 2 clear old values */
-	list_for_each_entry_rcu(ca, &tcp_cong_list, list)
-		ca->flags &= ~TCP_CONG_NON_RESTRICTED;
+	list_for_each_entry_rcu(e, &tcp_cong_list, list)
+		e->flags &= ~TCP_CONG_NON_RESTRICTED;
 
 	/* pass 3 mark as allowed */
 	while ((name = strsep(&val, " ")) && *name) {
-		ca = tcp_ca_find(name);
-		WARN_ON(!ca);
-		if (ca)
-			ca->flags |= TCP_CONG_NON_RESTRICTED;
+		e = tcp_ca_find(name);
+		WARN_ON(!e);
+		if (e)
+			e->flags |= TCP_CONG_NON_RESTRICTED;
 	}
 out:
 	spin_unlock(&tcp_cong_list_lock);
@@ -341,6 +376,7 @@ int tcp_set_allowed_congestion_control(char *val)
 int tcp_set_congestion_control(struct sock *sk, const char *name, bool load)
 {
 	struct inet_connection_sock *icsk = inet_csk(sk);
+	const struct tcp_congestion_entry *e;
 	const struct tcp_congestion_ops *ca;
 	int err = 0;
 
@@ -349,17 +385,23 @@ int tcp_set_congestion_control(struct sock *sk, const char *name, bool load)
 
 	rcu_read_lock();
 	if (!load)
-		ca = tcp_ca_find(name);
+		e = tcp_ca_find(name);
 	else
-		ca = __tcp_ca_find_autoload(name);
+		e = tcp_ca_find_autoload(name);
+
+	if (!e) {
+		err = -ENOENT;
+		goto out;
+	}
+
 	/* No change asking for existing value */
+	ca = e->ops;
 	if (ca == icsk->icsk_ca_ops) {
 		icsk->icsk_ca_setsockopt = 1;
 		goto out;
 	}
-	if (!ca) {
-		err = -ENOENT;
-	} else if (!load) {
+
+	if (!load) {
 		icsk->icsk_ca_ops = ca;
 		if (!try_module_get(ca->owner))
 			err = -EBUSY;
@@ -460,7 +502,7 @@ u32 tcp_reno_undo_cwnd(struct sock *sk)
 }
 EXPORT_SYMBOL_GPL(tcp_reno_undo_cwnd);
 
-struct tcp_congestion_ops tcp_reno = {
+const struct tcp_congestion_ops tcp_reno = {
 	.flags		= TCP_CONG_NON_RESTRICTED,
 	.name		= "reno",
 	.owner		= THIS_MODULE,
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
index 57ae5b5ae643..6a358d8408c4 100644
--- a/net/ipv4/tcp_cubic.c
+++ b/net/ipv4/tcp_cubic.c
@@ -465,7 +465,7 @@ static void bictcp_acked(struct sock *sk, const struct ack_sample *sample)
 		hystart_update(sk, delay);
 }
 
-static struct tcp_congestion_ops cubictcp __read_mostly = {
+static const struct tcp_congestion_ops cubictcp = {
 	.init		= bictcp_init,
 	.ssthresh	= bictcp_recalc_ssthresh,
 	.cong_avoid	= bictcp_cong_avoid,
diff --git a/net/ipv4/tcp_dctcp.c b/net/ipv4/tcp_dctcp.c
index 5f5e5936760e..7c608527c581 100644
--- a/net/ipv4/tcp_dctcp.c
+++ b/net/ipv4/tcp_dctcp.c
@@ -72,7 +72,7 @@ module_param(dctcp_clamp_alpha_on_loss, uint, 0644);
 MODULE_PARM_DESC(dctcp_clamp_alpha_on_loss,
 		 "parameter for clamping alpha on loss");
 
-static struct tcp_congestion_ops dctcp_reno;
+static const struct tcp_congestion_ops dctcp_reno;
 
 static void dctcp_reset(const struct tcp_sock *tp, struct dctcp *ca)
 {
@@ -318,7 +318,7 @@ static u32 dctcp_cwnd_undo(struct sock *sk)
 	return max(tcp_sk(sk)->snd_cwnd, ca->loss_cwnd);
 }
 
-static struct tcp_congestion_ops dctcp __read_mostly = {
+static const struct tcp_congestion_ops dctcp = {
 	.init		= dctcp_init,
 	.in_ack_event   = dctcp_update_alpha,
 	.cwnd_event	= dctcp_cwnd_event,
@@ -332,7 +332,7 @@ static struct tcp_congestion_ops dctcp __read_mostly = {
 	.name		= "dctcp",
 };
 
-static struct tcp_congestion_ops dctcp_reno __read_mostly = {
+static const struct tcp_congestion_ops dctcp_reno = {
 	.ssthresh	= tcp_reno_ssthresh,
 	.cong_avoid	= tcp_reno_cong_avoid,
 	.undo_cwnd	= tcp_reno_undo_cwnd,
diff --git a/net/ipv4/tcp_highspeed.c b/net/ipv4/tcp_highspeed.c
index 6d9879e93648..0faf9f952cf4 100644
--- a/net/ipv4/tcp_highspeed.c
+++ b/net/ipv4/tcp_highspeed.c
@@ -165,7 +165,7 @@ static u32 hstcp_cwnd_undo(struct sock *sk)
 	return max(tcp_sk(sk)->snd_cwnd, ca->loss_cwnd);
 }
 
-static struct tcp_congestion_ops tcp_highspeed __read_mostly = {
+static const struct tcp_congestion_ops tcp_highspeed = {
 	.init		= hstcp_init,
 	.ssthresh	= hstcp_ssthresh,
 	.undo_cwnd	= hstcp_cwnd_undo,
diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c
index 3eb78cde6ff0..74a5992f0323 100644
--- a/net/ipv4/tcp_htcp.c
+++ b/net/ipv4/tcp_htcp.c
@@ -286,7 +286,7 @@ static void htcp_state(struct sock *sk, u8 new_state)
 	}
 }
 
-static struct tcp_congestion_ops htcp __read_mostly = {
+static const struct tcp_congestion_ops htcp = {
 	.init		= htcp_init,
 	.ssthresh	= htcp_recalc_ssthresh,
 	.cong_avoid	= htcp_cong_avoid,
diff --git a/net/ipv4/tcp_hybla.c b/net/ipv4/tcp_hybla.c
index 0f7175c3338e..4705a65cd23a 100644
--- a/net/ipv4/tcp_hybla.c
+++ b/net/ipv4/tcp_hybla.c
@@ -163,7 +163,7 @@ static void hybla_cong_avoid(struct sock *sk, u32 ack, u32 acked)
 	tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tp->snd_cwnd_clamp);
 }
 
-static struct tcp_congestion_ops tcp_hybla __read_mostly = {
+static const struct tcp_congestion_ops tcp_hybla = {
 	.init		= hybla_init,
 	.ssthresh	= tcp_reno_ssthresh,
 	.undo_cwnd	= tcp_reno_undo_cwnd,
diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c
index 60352ff4f5a8..f0ea215a66fd 100644
--- a/net/ipv4/tcp_illinois.c
+++ b/net/ipv4/tcp_illinois.c
@@ -333,7 +333,7 @@ static size_t tcp_illinois_info(struct sock *sk, u32 ext, int *attr,
 	return 0;
 }
 
-static struct tcp_congestion_ops tcp_illinois __read_mostly = {
+static const struct tcp_congestion_ops tcp_illinois = {
 	.init		= tcp_illinois_init,
 	.ssthresh	= tcp_illinois_ssthresh,
 	.undo_cwnd	= tcp_illinois_cwnd_undo,
diff --git a/net/ipv4/tcp_lp.c b/net/ipv4/tcp_lp.c
index ae10ed64fe13..9960add64363 100644
--- a/net/ipv4/tcp_lp.c
+++ b/net/ipv4/tcp_lp.c
@@ -316,7 +316,7 @@ static void tcp_lp_pkts_acked(struct sock *sk, const struct ack_sample *sample)
 	lp->last_drop = now;
 }
 
-static struct tcp_congestion_ops tcp_lp __read_mostly = {
+static const struct tcp_congestion_ops tcp_lp = {
 	.init = tcp_lp_init,
 	.ssthresh = tcp_reno_ssthresh,
 	.undo_cwnd = tcp_reno_undo_cwnd,
diff --git a/net/ipv4/tcp_nv.c b/net/ipv4/tcp_nv.c
index 6d650ed3cb59..fcfc2329953d 100644
--- a/net/ipv4/tcp_nv.c
+++ b/net/ipv4/tcp_nv.c
@@ -441,7 +441,7 @@ static size_t tcpnv_get_info(struct sock *sk, u32 ext, int *attr,
 	return 0;
 }
 
-static struct tcp_congestion_ops tcpnv __read_mostly = {
+static const struct tcp_congestion_ops tcpnv = {
 	.init		= tcpnv_init,
 	.ssthresh	= tcpnv_recalc_ssthresh,
 	.cong_avoid	= tcpnv_cong_avoid,
diff --git a/net/ipv4/tcp_scalable.c b/net/ipv4/tcp_scalable.c
index f2123075ce6e..18c98f8e5f6c 100644
--- a/net/ipv4/tcp_scalable.c
+++ b/net/ipv4/tcp_scalable.c
@@ -50,7 +50,7 @@ static u32 tcp_scalable_cwnd_undo(struct sock *sk)
 	return max(tcp_sk(sk)->snd_cwnd, ca->loss_cwnd);
 }
 
-static struct tcp_congestion_ops tcp_scalable __read_mostly = {
+static const struct tcp_congestion_ops tcp_scalable = {
 	.ssthresh	= tcp_scalable_ssthresh,
 	.undo_cwnd	= tcp_scalable_cwnd_undo,
 	.cong_avoid	= tcp_scalable_cong_avoid,
diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c
index 218cfcc77650..c9d7000f00b0 100644
--- a/net/ipv4/tcp_vegas.c
+++ b/net/ipv4/tcp_vegas.c
@@ -304,7 +304,7 @@ size_t tcp_vegas_get_info(struct sock *sk, u32 ext, int *attr,
 }
 EXPORT_SYMBOL_GPL(tcp_vegas_get_info);
 
-static struct tcp_congestion_ops tcp_vegas __read_mostly = {
+static const struct tcp_congestion_ops tcp_vegas = {
 	.init		= tcp_vegas_init,
 	.ssthresh	= tcp_reno_ssthresh,
 	.undo_cwnd	= tcp_reno_undo_cwnd,
diff --git a/net/ipv4/tcp_veno.c b/net/ipv4/tcp_veno.c
index 76005d4b8dfc..0d9e33d7d7c5 100644
--- a/net/ipv4/tcp_veno.c
+++ b/net/ipv4/tcp_veno.c
@@ -210,7 +210,7 @@ static u32 tcp_veno_cwnd_undo(struct sock *sk)
 	return max(tcp_sk(sk)->snd_cwnd, veno->loss_cwnd);
 }
 
-static struct tcp_congestion_ops tcp_veno __read_mostly = {
+static const struct tcp_congestion_ops tcp_veno = {
 	.init		= tcp_veno_init,
 	.ssthresh	= tcp_veno_ssthresh,
 	.undo_cwnd	= tcp_veno_cwnd_undo,
diff --git a/net/ipv4/tcp_westwood.c b/net/ipv4/tcp_westwood.c
index e5de84310949..4c9b8711f4fe 100644
--- a/net/ipv4/tcp_westwood.c
+++ b/net/ipv4/tcp_westwood.c
@@ -251,7 +251,7 @@ static size_t tcp_westwood_info(struct sock *sk, u32 ext, int *attr,
 	return 0;
 }
 
-static struct tcp_congestion_ops tcp_westwood __read_mostly = {
+static const struct tcp_congestion_ops tcp_westwood = {
 	.init		= tcp_westwood_init,
 	.ssthresh	= tcp_reno_ssthresh,
 	.cong_avoid	= tcp_reno_cong_avoid,
diff --git a/net/ipv4/tcp_yeah.c b/net/ipv4/tcp_yeah.c
index e6ff99c4bd3b..507e4b2cb55f 100644
--- a/net/ipv4/tcp_yeah.c
+++ b/net/ipv4/tcp_yeah.c
@@ -232,7 +232,7 @@ static u32 tcp_yeah_cwnd_undo(struct sock *sk)
 	return max(tcp_sk(sk)->snd_cwnd, yeah->loss_cwnd);
 }
 
-static struct tcp_congestion_ops tcp_yeah __read_mostly = {
+static const struct tcp_congestion_ops tcp_yeah = {
 	.init		= tcp_yeah_init,
 	.ssthresh	= tcp_yeah_ssthresh,
 	.undo_cwnd      = tcp_yeah_cwnd_undo,
-- 
2.11.0

^ permalink raw reply related

* [RFC 0/1] tcp: constify congestion_ops
From: Stephen Hemminger @ 2017-08-02  2:49 UTC (permalink / raw)
  To: netdev; +Cc: Stephen Hemminger

This is a proposed method of making TCP congestion_ops structure const.

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.

Stephen Hemminger (1):
  constify tcp congestion

 include/net/tcp.h        |  10 ++-
 net/ipv4/tcp.c           |   2 -
 net/ipv4/tcp_bbr.c       |   2 +-
 net/ipv4/tcp_bic.c       |   2 +-
 net/ipv4/tcp_cdg.c       |   2 +-
 net/ipv4/tcp_cong.c      | 162 +++++++++++++++++++++++++++++------------------
 net/ipv4/tcp_cubic.c     |   2 +-
 net/ipv4/tcp_dctcp.c     |   6 +-
 net/ipv4/tcp_highspeed.c |   2 +-
 net/ipv4/tcp_htcp.c      |   2 +-
 net/ipv4/tcp_hybla.c     |   2 +-
 net/ipv4/tcp_illinois.c  |   2 +-
 net/ipv4/tcp_lp.c        |   2 +-
 net/ipv4/tcp_nv.c        |   2 +-
 net/ipv4/tcp_scalable.c  |   2 +-
 net/ipv4/tcp_vegas.c     |   2 +-
 net/ipv4/tcp_veno.c      |   2 +-
 net/ipv4/tcp_westwood.c  |   2 +-
 net/ipv4/tcp_yeah.c      |   2 +-
 19 files changed, 124 insertions(+), 86 deletions(-)

-- 
2.11.0

^ permalink raw reply

* Re: [PATCH net 6/7] netvsc: Initialize 64-bit stats seqcount
From: Stephen Hemminger @ 2017-08-02  2:42 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: netdev, Stephen Hemminger, Haiyang Zhang, open list, edumazet,
	open list:Hyper-V CORE AND DRIVERS, davem
In-Reply-To: <20170801191113.8754-8-f.fainelli@gmail.com>

On Tue,  1 Aug 2017 12:11:12 -0700
Florian Fainelli <f.fainelli@gmail.com> wrote:

> On 32-bit hosts and with CONFIG_DEBUG_LOCK_ALLOC we should be seeing a
> lockdep splat indicating this seqcount is not correctly initialized, fix
> that. In commit 6c80f3fc2398 ("netvsc: report per-channel stats in
> ethtool statistics") netdev_alloc_pcpu_stats() was removed in favor of
> open-coding the 64-bits statistics, except that u64_stats_init() was
> missed.
> 
> Fixes: 6c80f3fc2398 ("netvsc: report per-channel stats in ethtool statistics")
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
>  drivers/net/hyperv/netvsc.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
> index 0a9167dd72fb..96f90c75d1b7 100644
> --- a/drivers/net/hyperv/netvsc.c
> +++ b/drivers/net/hyperv/netvsc.c
> @@ -1302,6 +1302,8 @@ int netvsc_device_add(struct hv_device *device,
>  		struct netvsc_channel *nvchan = &net_device->chan_table[i];
>  
>  		nvchan->channel = device->channel;
> +		u64_stats_init(&nvchan->tx_stats.syncp);
> +		u64_stats_init(&nvchan->rx_stats.syncp);
>  	}
>  
>  	/* Enable NAPI handler before init callbacks */


Looks good, thanks. 32 bit guests are still supported but rarely tested.

Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>

^ permalink raw reply

* Re: sysctl, argument parsing, possible bug
From: Stephen Hemminger @ 2017-08-02  2:40 UTC (permalink / raw)
  To: Cong Wang; +Cc: Massimo Sala, LKML, Linux Kernel Network Developers
In-Reply-To: <CAM_iQpXtHACnD8kmmHd4bcg+Khy5Y0K=HMmc08avTSHov4zN1A@mail.gmail.com>

On Tue, 1 Aug 2017 14:27:37 -0700
Cong Wang <xiyou.wangcong@gmail.com> wrote:

> On Tue, Aug 1, 2017 at 1:47 PM, Massimo Sala <massimo.sala.71@gmail.com> wrote:
> > cat /proc/sys/net/ipv4/conf/eth0.100/forwarding
> > 0
> >
> > sysctl net.ipv4.conf.eth0.100.forwarding
> > error: "net.ipv4.conf.eth0.100.forwarding" is an unknown key
> >  
> 
> Use echo instead, sysctl doesn't understand eth0.100
> is a netdev name, sigh.

sysctl happily accepts / as a separator see man sysctl(8)

PARAMETERS
       variable
              The  name  of  a  key to read from.  An example is kernel.ostype.  The '/' separator is also
              accepted in place of a '.'.

^ permalink raw reply

* Re: [PATCH 1/6] [net-next]net: sched: act_mirred: Extend redirect action to accept a traffic class
From: Nambiar, Amritha @ 2017-08-02  2:20 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: intel-wired-lan, jeffrey.t.kirsher, alexander.h.duyck,
	kiran.patil, netdev, mitch.a.williams, alexander.duyck,
	neerav.parikh, sridhar.samudrala, carolyn.wyborny
In-Reply-To: <20170801111203.GI1939@nanopsycho>


On 8/1/2017 4:12 AM, Jiri Pirko wrote:
> Tue, Aug 01, 2017 at 02:37:37AM CEST, amritha.nambiar@intel.com wrote:
>> The Mirred/redirect action is extended to forward to a traffic
>> class on the device. The traffic class index needs to be
>> provided in addition to the device's ifindex.
>>
>> Example:
>> # tc filter add dev eth0 protocol ip parent ffff: prio 1 flower\
>>  dst_ip 192.168.1.1/32 ip_proto udp dst_port 22\
>>  skip_sw indev eth0 action mirred ingress redirect dev eth0 tc 1
> 
> You need to make sure that the current offloaders fill forbid to add
> this rule, not just silently ignore the tc value.

I will fix this in the next version, probably using the 'flags' field
I've defined.

> 
> 
>>
>> Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
>> ---
>> include/net/tc_act/tc_mirred.h        |    7 +++++++
>> include/uapi/linux/tc_act/tc_mirred.h |    5 +++++
>> net/sched/act_mirred.c                |   17 +++++++++++++++++
>> 3 files changed, 29 insertions(+)
>>
>> diff --git a/include/net/tc_act/tc_mirred.h b/include/net/tc_act/tc_mirred.h
>> index 604bc31..60058c4 100644
>> --- a/include/net/tc_act/tc_mirred.h
>> +++ b/include/net/tc_act/tc_mirred.h
>> @@ -9,6 +9,8 @@ struct tcf_mirred {
>> 	int			tcfm_eaction;
>> 	int			tcfm_ifindex;
>> 	bool			tcfm_mac_header_xmit;
>> +	u8			tcfm_tc;
>> +	u32			flags;
>> 	struct net_device __rcu	*tcfm_dev;
>> 	struct list_head	tcfm_list;
>> };
>> @@ -37,4 +39,9 @@ static inline int tcf_mirred_ifindex(const struct tc_action *a)
>> 	return to_mirred(a)->tcfm_ifindex;
>> }
>>
>> +static inline int tcf_mirred_tc(const struct tc_action *a)
>> +{
>> +	return to_mirred(a)->tcfm_tc;
>> +}
>> +
>> #endif /* __NET_TC_MIR_H */
>> diff --git a/include/uapi/linux/tc_act/tc_mirred.h b/include/uapi/linux/tc_act/tc_mirred.h
>> index 3d7a2b3..8ff4d76 100644
>> --- a/include/uapi/linux/tc_act/tc_mirred.h
>> +++ b/include/uapi/linux/tc_act/tc_mirred.h
>> @@ -9,6 +9,10 @@
>> #define TCA_EGRESS_MIRROR 2 /* mirror packet to EGRESS */
>> #define TCA_INGRESS_REDIR 3  /* packet redirect to INGRESS*/
>> #define TCA_INGRESS_MIRROR 4 /* mirror packet to INGRESS */
>> +
>> +#define MIRRED_F_TC_MAP		0x1
>> +#define MIRRED_TC_MAP_MAX	0x10
>> +#define MIRRED_TC_MAP_MASK	0xF
> 
> I'm completely lost. Why do you have these values here? and in fact one
> twice?

I'll fix this to remove the defines for the TC max range and its bitmap
here and reuse the existing ones defined in linux/netdevice.h

> 
> 
>>                                                                                 
>> struct tc_mirred {
>> 	tc_gen;
>> @@ -21,6 +25,7 @@ enum {
>> 	TCA_MIRRED_TM,
>> 	TCA_MIRRED_PARMS,
>> 	TCA_MIRRED_PAD,
>> +	TCA_MIRRED_TC_MAP,
>> 	__TCA_MIRRED_MAX
>> };
>> #define TCA_MIRRED_MAX (__TCA_MIRRED_MAX - 1)
>> diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
>> index 1b5549a..f9801de 100644
>> --- a/net/sched/act_mirred.c
>> +++ b/net/sched/act_mirred.c
>> @@ -67,6 +67,7 @@ static void tcf_mirred_release(struct tc_action *a, int bind)
>>
>> static const struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = {
>> 	[TCA_MIRRED_PARMS]	= { .len = sizeof(struct tc_mirred) },
>> +	[TCA_MIRRED_TC_MAP]	= { .type = NLA_U8 },
>> };
>>
>> static unsigned int mirred_net_id;
>> @@ -83,6 +84,8 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
>> 	struct tcf_mirred *m;
>> 	struct net_device *dev;
>> 	bool exists = false;
>> +	u8 *tc_map = NULL;
>> +	u32 flags = 0;
>> 	int ret;
>>
>> 	if (nla == NULL)
>> @@ -92,6 +95,14 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
>> 		return ret;
>> 	if (tb[TCA_MIRRED_PARMS] == NULL)
>> 		return -EINVAL;
>> +
>> +	if (tb[TCA_MIRRED_TC_MAP]) {
>> +		tc_map = nla_data(tb[TCA_MIRRED_TC_MAP]);
>> +		if (*tc_map >= MIRRED_TC_MAP_MAX)
>> +			return -EINVAL;
>> +		flags |= MIRRED_F_TC_MAP;
>> +	}
>> +
>> 	parm = nla_data(tb[TCA_MIRRED_PARMS]);
>>
>> 	exists = tcf_hash_check(tn, parm->index, a, bind);
>> @@ -139,6 +150,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
>> 	ASSERT_RTNL();
>> 	m->tcf_action = parm->action;
>> 	m->tcfm_eaction = parm->eaction;
>> +	m->flags = flags;
>> 	if (dev != NULL) {
>> 		m->tcfm_ifindex = parm->ifindex;
>> 		if (ret != ACT_P_CREATED)
>> @@ -146,6 +158,8 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
>> 		dev_hold(dev);
>> 		rcu_assign_pointer(m->tcfm_dev, dev);
>> 		m->tcfm_mac_header_xmit = mac_header_xmit;
>> +		if (flags & MIRRED_F_TC_MAP)
>> +			m->tcfm_tc = *tc_map & MIRRED_TC_MAP_MASK;
>> 	}
>>
>> 	if (ret == ACT_P_CREATED) {
>> @@ -259,6 +273,9 @@ static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind,
>>
>> 	if (nla_put(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt))
>> 		goto nla_put_failure;
>> +	if ((m->flags & MIRRED_F_TC_MAP) &&
>> +	    nla_put_u8(skb, TCA_MIRRED_TC_MAP, m->tcfm_tc))
>> +		goto nla_put_failure;
>>
>> 	tcf_tm_dump(&t, &m->tcf_tm);
>> 	if (nla_put_64bit(skb, TCA_MIRRED_TM, sizeof(t), &t, TCA_MIRRED_PAD))
>>

^ permalink raw reply

* Re: [PATCH 6/6] [net-next]net: i40e: Enable cloud filters in i40e via tc/flower classifier
From: Nambiar, Amritha @ 2017-08-02  2:13 UTC (permalink / raw)
  To: Jamal Hadi Salim, intel-wired-lan, jeffrey.t.kirsher
  Cc: alexander.h.duyck, kiran.patil, netdev, mitch.a.williams,
	alexander.duyck, neerav.parikh, sridhar.samudrala,
	carolyn.wyborny, Or Gerlitz
In-Reply-To: <f93480af-9ae0-2e02-7b11-78f8ab53899c@mojatatu.com>


On 8/1/2017 3:56 AM, Jamal Hadi Salim wrote:
> On 17-07-31 08:38 PM, Amritha Nambiar wrote:
>> This patch enables tc-flower based hardware offloads. tc/flower
>> filter provided by the kernel is configured as driver specific
>> cloud filter. The patch implements functions and admin queue
>> commands needed to support cloud filters in the driver and
>> adds cloud filters to configure these tc-flower filters.
>>
>> The only action supported is to redirect packets to a traffic class
>> on the same device.
>>
>> # tc qdisc add dev eth0 ingress
>> # ethtool -K eth0 hw-tc-offload on
>>
>> # tc filter add dev eth0 protocol ip parent ffff:\
>>    prio 1 flower dst_mac 3c:fd:fe:a0:d6:70 skip_sw indev eth0\
>>    action mirred ingress redirect dev eth0 tc 0
>>
> 
> Out of curiosity - did you need to say "indev eth0" there?

It looks like I don't need to specify "indev eth0". I will need to look
up how this part is offloaded and probably validate in the driver when
this is specified.

> Also: Is it possible to add an skbmark? Example something like
> these that directs two flows to the same queue but different
> skb marks:
> 
> # tc filter add dev eth0 protocol ip parent ffff: \
>    prio 2 flower dst_ip 192.168.3.5/32 \
>    ip_proto udp dst_port 2a skip_sw \
>    action skbedit mark 11 \
>    action mirred ingress redirect dev eth0 tcqueue 1
> 
> # tc filter add dev eth0 protocol ip parent ffff: \
>      prio 1 flower dst_mac 3c:fd:fe:a0:d6:70 skip_sw \
>      action skbedit mark 12 \
>      action mirred ingress redirect dev eth0 tcqueue 1
> 

It is possible to support the skbedit mark action for the first rule
here (L3 and L4) which I can take up in a subsequent patch, but this
cannot be supported on our device for L2 based match in the second rule.

> cheers,
> jamal
> 

^ permalink raw reply

* Re: [PATCH 1/6] [net-next]net: sched: act_mirred: Extend redirect action to accept a traffic class
From: Nambiar, Amritha @ 2017-08-02  1:42 UTC (permalink / raw)
  To: Jamal Hadi Salim, intel-wired-lan, jeffrey.t.kirsher
  Cc: alexander.h.duyck, kiran.patil, netdev, mitch.a.williams,
	alexander.duyck, neerav.parikh, sridhar.samudrala,
	carolyn.wyborny
In-Reply-To: <7f2d3255-ecb1-0252-1066-4ac1ed7c79eb@mojatatu.com>


On 8/1/2017 3:44 AM, Jamal Hadi Salim wrote:
> On 17-07-31 08:37 PM, Amritha Nambiar wrote:
>> The Mirred/redirect action is extended to forward to a traffic
>> class on the device. The traffic class index needs to be
>> provided in addition to the device's ifindex.
>>
>> Example:
>> # tc filter add dev eth0 protocol ip parent ffff: prio 1 flower\
>>    dst_ip 192.168.1.1/32 ip_proto udp dst_port 22\
>>    skip_sw indev eth0 action mirred ingress redirect dev eth0 tc 1
>>
>> Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
>> ---
>>   include/net/tc_act/tc_mirred.h        |    7 +++++++
>>   include/uapi/linux/tc_act/tc_mirred.h |    5 +++++
>>   net/sched/act_mirred.c                |   17 +++++++++++++++++
>>   3 files changed, 29 insertions(+)
>>
>> diff --git a/include/net/tc_act/tc_mirred.h b/include/net/tc_act/tc_mirred.h
>> index 604bc31..60058c4 100644
>> --- a/include/net/tc_act/tc_mirred.h
>> +++ b/include/net/tc_act/tc_mirred.h
>> @@ -9,6 +9,8 @@ struct tcf_mirred {
>>   	int			tcfm_eaction;
>>   	int			tcfm_ifindex;
>>   	bool			tcfm_mac_header_xmit;
>> +	u8			tcfm_tc;
>> +	u32			flags;
>>   	struct net_device __rcu	*tcfm_dev;
>>   	struct list_head	tcfm_list;
>>   };
>> @@ -37,4 +39,9 @@ static inline int tcf_mirred_ifindex(const struct tc_action *a)
>>   	return to_mirred(a)->tcfm_ifindex;
>>   }
>>   
>> +static inline int tcf_mirred_tc(const struct tc_action *a)
>> +{
>> +	return to_mirred(a)->tcfm_tc;
>> +}
>> +
>>   #endif /* __NET_TC_MIR_H */
>> diff --git a/include/uapi/linux/tc_act/tc_mirred.h b/include/uapi/linux/tc_act/tc_mirred.h
>> index 3d7a2b3..8ff4d76 100644
>> --- a/include/uapi/linux/tc_act/tc_mirred.h
>> +++ b/include/uapi/linux/tc_act/tc_mirred.h
>> @@ -9,6 +9,10 @@
>>   #define TCA_EGRESS_MIRROR 2 /* mirror packet to EGRESS */
>>   #define TCA_INGRESS_REDIR 3  /* packet redirect to INGRESS*/
>>   #define TCA_INGRESS_MIRROR 4 /* mirror packet to INGRESS */
>> +
>> +#define MIRRED_F_TC_MAP		0x1
>> +#define MIRRED_TC_MAP_MAX	0x10
>> +#define MIRRED_TC_MAP_MASK	0xF
>>                                                                                   
>>   struct tc_mirred {
>>   	tc_gen;
>> @@ -21,6 +25,7 @@ enum {
>>   	TCA_MIRRED_TM,
>>   	TCA_MIRRED_PARMS,
>>   	TCA_MIRRED_PAD,
>> +	TCA_MIRRED_TC_MAP,
>>   	__TCA_MIRRED_MAX
>>   };
>>   #define TCA_MIRRED_MAX (__TCA_MIRRED_MAX - 1)
>> diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
>> index 1b5549a..f9801de 100644
>> --- a/net/sched/act_mirred.c
>> +++ b/net/sched/act_mirred.c
>> @@ -67,6 +67,7 @@ static void tcf_mirred_release(struct tc_action *a, int bind)
>>   
>>   static const struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = {
>>   	[TCA_MIRRED_PARMS]	= { .len = sizeof(struct tc_mirred) },
>> +	[TCA_MIRRED_TC_MAP]	= { .type = NLA_U8 },
>>   };
>>   
>>   static unsigned int mirred_net_id;
>> @@ -83,6 +84,8 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
>>   	struct tcf_mirred *m;
>>   	struct net_device *dev;
>>   	bool exists = false;
>> +	u8 *tc_map = NULL;
>> +	u32 flags = 0;
>>   	int ret;
>>   
>>   	if (nla == NULL)
>> @@ -92,6 +95,14 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
>>   		return ret;
>>   	if (tb[TCA_MIRRED_PARMS] == NULL)
>>   		return -EINVAL;
>> +
>> +	if (tb[TCA_MIRRED_TC_MAP]) {
>> +		tc_map = nla_data(tb[TCA_MIRRED_TC_MAP]);
>> +		if (*tc_map >= MIRRED_TC_MAP_MAX)
>> +			return -EINVAL;
>> +		flags |= MIRRED_F_TC_MAP;
> 
> 
>> +	}
>> +
>>   	parm = nla_data(tb[TCA_MIRRED_PARMS]);
>>   
>>   	exists = tcf_hash_check(tn, parm->index, a, bind);
>> @@ -139,6 +150,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
>>   	ASSERT_RTNL();
>>   	m->tcf_action = parm->action;
>>   	m->tcfm_eaction = parm->eaction;
>> +	m->flags = flags;
>>   	if (dev != NULL) {
>>   		m->tcfm_ifindex = parm->ifindex;
>>   		if (ret != ACT_P_CREATED)
>> @@ -146,6 +158,8 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
>>   		dev_hold(dev);
>>   		rcu_assign_pointer(m->tcfm_dev, dev);
>>   		m->tcfm_mac_header_xmit = mac_header_xmit;
>> +		if (flags & MIRRED_F_TC_MAP)
>> +			m->tcfm_tc = *tc_map & MIRRED_TC_MAP_MASK;
>>   	}
>>   
> Is the mask a hardware limit. I dont know how these queues are
> allocated - I am assuming each of these "tc queues" maps to a rx
> DMA ring?

This is the bitmask for TC max range again defined in linux/netdevice.h.
I'll fix this to remove the new definition I have (MIRRED_TC_MAP_MASK)
here and replace with the existing TC_BITMASK. These are just the
traffic class index that are offloaded to the device. I had submitted
another series that handles configuring queues for the traffic classes
and queue layout offloaded via the mqprio framework.

> 
>>   	if (ret == ACT_P_CREATED) {
>> @@ -259,6 +273,9 @@ static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind,
>>   
>>   	if (nla_put(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt))
>>   		goto nla_put_failure;
>> +	if ((m->flags & MIRRED_F_TC_MAP) &&
>> +	    nla_put_u8(skb, TCA_MIRRED_TC_MAP, m->tcfm_tc))
>> +		goto nla_put_failure;
>>
> 
> If you have m->tcfm_tc then I dont think you need the flags; so i would
> remove it from the struct altogether.

I think I would still need the flags as "tc" index is an optional
parameter and the value zero is also a valid TC index. I was also
planning to use this flag to address Jiri's comment to fail this rule in
devices not supporting this offload.

> 
> cheers,
> jamal
> 

^ permalink raw reply

* Re: [PATCH 1/6] [net-next]net: sched: act_mirred: Extend redirect action to accept a traffic class
From: Nambiar, Amritha @ 2017-08-02  1:12 UTC (permalink / raw)
  To: Jamal Hadi Salim, intel-wired-lan, jeffrey.t.kirsher
  Cc: alexander.h.duyck, kiran.patil, netdev, mitch.a.williams,
	alexander.duyck, neerav.parikh, sridhar.samudrala,
	carolyn.wyborny
In-Reply-To: <85d57ef2-1c9f-d0e6-a3e8-d65078485afb@mojatatu.com>


On 8/1/2017 3:22 AM, Jamal Hadi Salim wrote:
> On 17-07-31 08:37 PM, Amritha Nambiar wrote:
>> The Mirred/redirect action is extended to forward to a traffic
>> class on the device. The traffic class index needs to be
>> provided in addition to the device's ifindex.
>>
>> Example:
>> # tc filter add dev eth0 protocol ip parent ffff: prio 1 flower\
>>    dst_ip 192.168.1.1/32 ip_proto udp dst_port 22\
>>    skip_sw indev eth0 action mirred ingress redirect dev eth0 tc 1
>>
>> Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
>> ---
>>   include/net/tc_act/tc_mirred.h        |    7 +++++++
>>   include/uapi/linux/tc_act/tc_mirred.h |    5 +++++
>>   net/sched/act_mirred.c                |   17 +++++++++++++++++
>>   3 files changed, 29 insertions(+)
>>
>> diff --git a/include/net/tc_act/tc_mirred.h b/include/net/tc_act/tc_mirred.h
>> index 604bc31..60058c4 100644
>> --- a/include/net/tc_act/tc_mirred.h
>> +++ b/include/net/tc_act/tc_mirred.h
>> @@ -9,6 +9,8 @@ struct tcf_mirred {
>>   	int			tcfm_eaction;
>>   	int			tcfm_ifindex;
>>   	bool			tcfm_mac_header_xmit;
>> +	u8			tcfm_tc;
>> +	u32			flags;
>>   	struct net_device __rcu	*tcfm_dev;
>>   	struct list_head	tcfm_list;
>>   };
>> @@ -37,4 +39,9 @@ static inline int tcf_mirred_ifindex(const struct tc_action *a)
>>   	return to_mirred(a)->tcfm_ifindex;
>>   }
>>   
>> +static inline int tcf_mirred_tc(const struct tc_action *a)
>> +{
>> +	return to_mirred(a)->tcfm_tc;
>> +}
>> +
>>   #endif /* __NET_TC_MIR_H */
>> diff --git a/include/uapi/linux/tc_act/tc_mirred.h b/include/uapi/linux/tc_act/tc_mirred.h
>> index 3d7a2b3..8ff4d76 100644
>> --- a/include/uapi/linux/tc_act/tc_mirred.h
>> +++ b/include/uapi/linux/tc_act/tc_mirred.h
>> @@ -9,6 +9,10 @@
>>   #define TCA_EGRESS_MIRROR 2 /* mirror packet to EGRESS */
>>   #define TCA_INGRESS_REDIR 3  /* packet redirect to INGRESS*/
>>   #define TCA_INGRESS_MIRROR 4 /* mirror packet to INGRESS */
>> +
>> +#define MIRRED_F_TC_MAP		0x1
>> +#define MIRRED_TC_MAP_MAX	0x10
> 
> Assuming this is the max number of queues?
> Where does this upper bound come from? Is it a spec
> or an intel thing? If spec - mentioning which
> spec and section would be useful.

This is the max number of TCs. The Linux upper bound for this is defined
in linux/netdevice.h. I will fix this part to remove the definition here
and reuse the existing one.

> 
> cheers,
> jamal
> 

^ permalink raw reply

* Re: [PATCH net-next RFC 0/6] Configure cloud filters in i40e via tc/flower classifier
From: Nambiar, Amritha @ 2017-08-02  0:57 UTC (permalink / raw)
  To: Jamal Hadi Salim, intel-wired-lan, jeffrey.t.kirsher
  Cc: alexander.h.duyck, kiran.patil, netdev, mitch.a.williams,
	alexander.duyck, neerav.parikh, sridhar.samudrala,
	carolyn.wyborny, Or Gerlitz
In-Reply-To: <2d833571-a5f3-41a6-0e6c-9d2c27b0a8c5@mojatatu.com>


On 8/1/2017 3:15 AM, Jamal Hadi Salim wrote:
> On 17-07-31 08:36 PM, Amritha Nambiar wrote:
>> This patch series enables configuring cloud filters in i40e
>> using the tc/flower classifier. The only tc-filter action
>> supported is to redirect packets to a traffic class on the
>> same device. The tc/mirred:redirect action is extended to
>> accept a traffic class to achieve this.
>>
>> The cloud filters are added for a VSI and are cleaned up when
>> the VSI is deleted. The filters that match on L4 ports needs
>> enhanced admin queue functions with big buffer support for
>> extended general fields in Add/Remove Cloud filters command.
>>
>> Example:
>> # tc qdisc add dev eth0 ingress
>>
>> # ethtool -K eth0 hw-tc-offload on
>>
>> # tc filter add dev eth0 protocol ip parent ffff: prio 1 flower\
>>    dst_ip 192.168.1.1/32 ip_proto udp dst_port 22\
>>    skip_sw indev eth0 action mirred ingress redirect dev eth0 tc 1
>>
> 
> I think "queue 1" sounds better than "tc 1".
> "tc" is  already a keyword in a few places (even within that declaration
> above).

The idea is to redirect to a traffic class that has queues assigned to
it and not a single queue i.e. these are actually queue groups and not a
single queue. So may be "qgroup 1" or "tcqgroup 1" fits better.

> 
> cheers,
> jamal
> 

^ permalink raw reply

* Re: [PATCH 1/2] [for 4.13] net: qcom/emac: disable flow control autonegotiation by default
From: Timur Tabi @ 2017-08-02  0:56 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: David S. Miller, netdev
In-Reply-To: <20170801231554.GA8415@lunn.ch>

On 8/1/17 6:15 PM, Andrew Lunn wrote:
> Pause frames are something you can auto-negotiate at the PHY
> level. Should you also be clearing some bits in the phydev, so the
> peer knows pause frames are not supported?

When pause frame autonegotiation is enabled in the driver, that only 
means that the driver looks at what the PHY has autonegotiated, and then 
configures the MAC to match that.

The driver doesn't touch the PHY at all.  It leaves all that to phylib.

Now if autonegotiation is disabled in the driver, then it just 
hard-codes those TX/RX settings in the driver.  Are you saying I should 
program the PHY at the point to disable autonegotiation on the PHY 
level?  If so, then I don't know how to do that.  I just assumed that 
the MAC never tells the PHY what to do.

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, hosted by The Linux Foundation.

^ permalink raw reply

* Re: [PATCH v3 0/2] ravb: add wake-on-lan support via magic packet
From: David Miller @ 2017-08-02  0:54 UTC (permalink / raw)
  To: niklas.soderlund+renesas
  Cc: sergei.shtylyov, geert, netdev, linux-renesas-soc
In-Reply-To: <20170801101437.9020-1-niklas.soderlund+renesas@ragnatech.se>

From: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Date: Tue,  1 Aug 2017 12:14:35 +0200

> WoL is enabled in the suspend callback by setting MagicPacket detection
> and disabling all interrupts expect MagicPacket. In the resume path the
> driver needs to reset the hardware to rearm the WoL logic, this prevents
> the driver from simply restoring the registers and to take advantage of
> that ravb was not suspended to reduce resume time. To reset the
> hardware the driver closes the device, sets it in reset mode and reopens
> the device just like it would do in a normal suspend/resume scenario
> without WoL enabled, but it both closes and opens the device in the
> resume callback since the device needs to be reset for WoL to work.
> 
> One quirk needed for WoL is that the module clock needs to be prevented
> from being switched off by Runtime PM. To keep the clock alive the
> suspend callback need to call clk_enable() directly to increase the
> usage count of the clock. Then when Runtime PM decreases the clock usage
> count it won't reach 0 and be switched off.
> 
> Changes since v2
> - Only do the clock dance to workaround PSCI sleep when resuming if WoL 
>   is enabled. This was a bug in v2 which resulted in a WARN if resuming 
>   from PSCI sleep with WoL disabled, thanks Sergei for pointing this 
>   out!
> - Break out clock dance workaround in separate patch to make it easier 
>   to revert once a fix is upstream for the clock driver as suggested by 
>   Sergei.
> 
> Changes since v1
> - Fix issue where device would fail to resume from PSCI suspend if WoL
>   was enabled, reported by Geert. The fault was that the clock driver
>   thinks the clock is on, but PSCI have disabled it, added workaround
>   for this in ravb driver which can be removed once the clock driver is
>   aware of the PSCI behavior.
> - Only try to restore from wol wake up if netif is running, since this
>   is a condition to enable wol in the first place this was a bug in v1.

Series applied, thanks.

^ permalink raw reply

* Re: pull request: bluetooth-next 2017-08-01
From: David Miller @ 2017-08-02  0:43 UTC (permalink / raw)
  To: johan.hedberg; +Cc: linux-bluetooth, netdev
In-Reply-To: <20170801094156.GA22557@x1c.lan>

From: Johan Hedberg <johan.hedberg@gmail.com>
Date: Tue, 1 Aug 2017 12:41:56 +0300

> Here's our first batch of Bluetooth patches for the 4.14 kernel:
> 
>  - Several new USB IDs for the btusb driver
>  - Memory leak fix in btusb driver
>  - Cleanups & fixes to hci_nokia, hci_serdev and hci_bcm drivers
>  - Fixed cleanup path in mrf24j40 (802.15.4) driver probe function
>  - A few other smaller cleanups & fixes to drivers
> 
> Please let me know if there are any issues pulling. Thanks.

Pulled, thank you.

^ permalink raw reply

* Re: [PATCH net-next 00/10] net: l3mdev: Support for sockets bound to enslaved device
From: David Miller @ 2017-08-02  0:41 UTC (permalink / raw)
  To: dsahern; +Cc: netdev
In-Reply-To: <1501557206-27503-1-git-send-email-dsahern@gmail.com>

From: David Ahern <dsahern@gmail.com>
Date: Mon, 31 Jul 2017 20:13:16 -0700

> Existing code for socket lookups already pass in 6+ arguments. Rather
> than add another for the enslaved device index, the existing lookups
> are converted to use a new sk_lookup struct. From there, the enslaved
> device index becomes another element of the struct.

Sorry, not gonna happen :-)

I know it's difficult, but maybe we should think about why we're
passing so much crap into each lookup.

And perhaps, why it can't (for example) be constituted in the lookup
function itself given sufficient (relevant) context.

I think passing a big struct into the lookups, by reference, is a big
step backwards.

For one thing, if you pass it by pointer then the compiler can't
potentially pass parts in registers even if it could.  However
if you pass it by value, that's actually a possibility.

But I'd like to avoid this on-stack blob altogether if possible.

Thanks.

^ permalink raw reply

* Re: [PATCH] drivers/net/wan/z85230.c: Use designated initializers
From: Kees Cook @ 2017-08-02  0:33 UTC (permalink / raw)
  To: David Miller; +Cc: LKML, Network Development
In-Reply-To: <20170801.152943.804666349488319640.davem@davemloft.net>

On Tue, Aug 1, 2017 at 3:29 PM, David Miller <davem@davemloft.net> wrote:
> From: Kees Cook <keescook@chromium.org>
> Date: Sun, 30 Jul 2017 18:31:17 -0700
>
>> In preparation for the randstruct gcc plugin performing randomization of
>> structures that are entirely function pointers, use designated initializers
>> so the compiler doesn't get angry.
>>
>> Reported-by: kbuild test robot <fengguang.wu@intel.com>
>> Signed-off-by: Kees Cook <keescook@chromium.org>
>> ---
>> This is a prerequisite for the future randstruct fptr randomization. I'd
>> prefer to carry this in my gcc-plugin tree for v4.14 with an Ack from
>> someone on net-dev, or if possible, have it applied to v4.13 via net-dev.
>
> Please queue this up into the gcc-plugin tree then:
>
> Acked-by: David S. Miller <davem@davemloft.net>
>
> It isn't a bug fix so I would only have put it into 'net-next' rather
> than 'net'.

Okay, sounds good. I'll carry it. Thanks!

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply

* [PATCH 1/2] atm: adummy: constify attribute_group structure
From: Amitoj Kaur Chawla @ 2017-08-01 23:57 UTC (permalink / raw)
  To: 3chas3, linux-atm-general, netdev, linux-kernel

Functions working with attribute_groups provided by <linux/sysfs.h>
work with const attribute_group. These attribute_group structures do not
change at runtime so mark them as const.

File size before:
 text      data     bss     dec     hex filename
 2033      1448       0    3481     d99 drivers/atm/adummy.o

File size after:
 text      data     bss     dec     hex filename
 2129      1352       0    3481     d99 drivers/atm/adummy.o

This change was made with the help of Coccinelle.

Signed-off-by: Amitoj Kaur Chawla <amitoj1606@gmail.com>
---
 drivers/atm/adummy.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c
index 1fd25e8..da27ddf 100644
--- a/drivers/atm/adummy.c
+++ b/drivers/atm/adummy.c
@@ -71,7 +71,7 @@ static struct attribute *adummy_attrs[] = {
 	NULL
 };
 
-static struct attribute_group adummy_group_attrs = {
+static const struct attribute_group adummy_group_attrs = {
 	.name = NULL, /* We want them in dev's root folder */
 	.attrs = adummy_attrs
 };
-- 
2.7.4

^ permalink raw reply related

* [PATCH 2/2] atm: solos-pci: constify attribute_group structures
From: Amitoj Kaur Chawla @ 2017-08-01 23:57 UTC (permalink / raw)
  To: 3chas3, linux-atm-general, netdev, linux-kernel

Functions working with attribute_groups provided by <linux/sysfs.h>
work with const attribute_group. These attribute_group structures do not
change at runtime so mark them as const.

File size before:
 text      data     bss     dec     hex filename
 35740    28424     832   64996    fde4 drivers/atm/solos-pci.o

File size after:
 text      data     bss     dec     hex filename
 35932    28232     832   64996    fde4 drivers/atm/solos-pci.o

This change was made with the help of Coccinelle.

Signed-off-by: Amitoj Kaur Chawla <amitoj1606@gmail.com>
---
 drivers/atm/solos-pci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index c8f2ca6..3f9c37d 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -611,7 +611,7 @@ static struct attribute *solos_attrs[] = {
 	NULL
 };
 
-static struct attribute_group solos_attr_group = {
+static const struct attribute_group solos_attr_group = {
 	.attrs = solos_attrs,
 	.name = "parameters",
 };
@@ -628,7 +628,7 @@ static struct attribute *gpio_attrs[] = {
 	NULL
 };
 
-static struct attribute_group gpio_attr_group = {
+static const struct attribute_group gpio_attr_group = {
 	.attrs = gpio_attrs,
 	.name = "gpio",
 };
-- 
2.7.4

^ permalink raw reply related

* Re: [PATCH 1/2] [for 4.13] net: qcom/emac: disable flow control autonegotiation by default
From: Andrew Lunn @ 2017-08-01 23:15 UTC (permalink / raw)
  To: Timur Tabi; +Cc: David S. Miller, netdev
In-Reply-To: <1501623460-3575-2-git-send-email-timur@codeaurora.org>

On Tue, Aug 01, 2017 at 04:37:39PM -0500, Timur Tabi wrote:
> The EMAC has a curious qwirk when RX flow control is enabled and the
> kernel hangs.  With the kernel hung, the EMAC's RX queue soon fills.
> If RX flow control is enabled, the EMAC will then send a non-stop
> stream of pause frames until the system is reset.  The EMAC does not
> have a built-in watchdog.
> 
> In various tests, the pause frame stream sometimes overloads nearby
> switches, effectively disabling the network.  Since the RX queue is
> large and the host processor is more than capable of handling incoming
> packets quickly, the only time the EMAC will send any pause frames is
> when the kernel is hung and unrecoverable.
> 
> To avoid all these problems, we disable flow control autonegotiation
> by default, and only enable receiving pause frames.
> 
> Cc: stable@vger.kernel.org # 4.11.x
> Signed-off-by: Timur Tabi <timur@codeaurora.org>
> ---
>  drivers/net/ethernet/qualcomm/emac/emac.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/qualcomm/emac/emac.c b/drivers/net/ethernet/qualcomm/emac/emac.c
> index 60850bfa3d32..475c0ea29235 100644
> --- a/drivers/net/ethernet/qualcomm/emac/emac.c
> +++ b/drivers/net/ethernet/qualcomm/emac/emac.c
> @@ -441,8 +441,13 @@ static void emac_init_adapter(struct emac_adapter *adpt)
>  	/* others */
>  	adpt->preamble = EMAC_PREAMBLE_DEF;
>  
> -	/* default to automatic flow control */
> -	adpt->automatic = true;
> +	/* Disable transmission of pause frames by default, to avoid the
> +	 * risk of a pause frame flood that can occur if the kernel hangs.
> +	 * We still want to be able to respond to them, however.
> +	 */
> +	adpt->automatic = false;
> +	adpt->tx_flow_control = false;
> +	adpt->rx_flow_control = true;

Hi Timur

Pause frames are something you can auto-negotiate at the PHY
level. Should you also be clearing some bits in the phydev, so the
peer knows pause frames are not supported?

     Andrew

^ permalink raw reply

* Re: [PATCH net-next v2 0/3] netvsc: transparent SR-IOV VF support
From: David Miller @ 2017-08-01 23:13 UTC (permalink / raw)
  To: stephen; +Cc: kys, haiyangz, sthemmin, corbet, devel, linux-doc, netdev
In-Reply-To: <20170731234524.30326-1-sthemmin@microsoft.com>

From: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon, 31 Jul 2017 16:45:21 -0700

> This patch set changes how SR-IOV Virtual Function devices are managed
> in the Hyper-V network driver. It was part of earlier bundle, but
> is now updated.

I think you need to do a rebase.  I just merged net into net-next and
this created some conflicts.

^ permalink raw reply

* Re: [PATCH net 2/2] gue: fix remcsum when GRO on and CHECKSUM_PARTIAL boundary is outer UDP
From: David Miller @ 2017-08-01 23:09 UTC (permalink / raw)
  To: den; +Cc: netdev, tom
In-Reply-To: <20170731160539.6013-1-den@klaipeden.com>

From: Koichiro Den <den@klaipeden.com>
Date: Tue,  1 Aug 2017 01:05:39 +0900

> In the case that GRO is turned on and the original received packet is
> CHECKSUM_PARTIAL, if the outer UDP header is exactly at the last
> csum-unnecessary point, which for instance could occur if the packet
> comes from another Linux guest on the same Linux host, we have to do
> either remcsum_adjust or set up CHECKSUM_PARTIAL again with its
> csum_start properly reset considering RCO.
> 
> However, since b7fe10e5ebac ("gro: Fix remcsum offload to deal with frags
> in GRO") that barrier in such case could be skipped if GRO turned on,
> hence we pass over it and the inner L4 validation mistakenly reckons
> it as a bad csum.
> 
> This patch makes remcsum_offload being reset at the same time of GRO
> remcsum cleanup, so as to make it work in such case as before.
> 
> Fixes: b7fe10e5ebac ("gro: Fix remcsum offload to deal with frags in GRO")
> Signed-off-by: Koichiro Den <den@klaipeden.com>

Applied.

^ permalink raw reply

* Re: [PATCH net 1/2] vxlan: fix remcsum when GRO on and CHECKSUM_PARTIAL boundary is outer UDP
From: David Miller @ 2017-08-01 23:09 UTC (permalink / raw)
  To: den; +Cc: netdev, tom
In-Reply-To: <20170731160520.5957-1-den@klaipeden.com>

From: Koichiro Den <den@klaipeden.com>
Date: Tue,  1 Aug 2017 01:05:20 +0900

> In the case that GRO is turned on and the original received packet is
> CHECKSUM_PARTIAL, if the outer UDP header is exactly at the last
> csum-unnecessary point, which for instance could occur if the packet
> comes from another Linux guest on the same Linux host, we have to do
> either remcsum_adjust or set up CHECKSUM_PARTIAL again with its
> csum_start properly reset considering RCO.
> 
> However, since b7fe10e5ebac("gro: Fix remcsum offload to deal with frags
> in GRO") that barrier in such case could be skipped if GRO turned on,
> hence we pass over it and the inner L4 validation mistakenly reckons
> it as a bad csum.
> 
> This patch makes remcsum_offload being reset at the same time of GRO
> remcsum cleanup, so as to make it work in such case as before.
> 
> Fixes: b7fe10e5ebac ("gro: Fix remcsum offload to deal with frags in GRO")
> Signed-off-by: Koichiro Den <den@klaipeden.com>

Applied.

^ permalink raw reply

* Re: [PATCH-net-next] net: add skb_frag_foreach_page and use with kmap_atomic
From: David Miller @ 2017-08-01 23:07 UTC (permalink / raw)
  To: willemdebruijn.kernel; +Cc: netdev, willemb
In-Reply-To: <20170731121547.23736-1-willemdebruijn.kernel@gmail.com>

From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Date: Mon, 31 Jul 2017 08:15:47 -0400

> From: Willem de Bruijn <willemb@google.com>
> 
> Skb frags may contain compound pages. Various operations map frags
> temporarily using kmap_atomic, but this function works on single
> pages, not whole compound pages. The distinction is only relevant
> for high mem pages that require temporary mappings.
> 
> Introduce a looping mechanism that for compound highmem pages maps
> one page at a time, does not change behavior on other pages.
> Use the loop in the kmap_atomic callers in net/core/skbuff.c.
> 
> Verified by triggering skb_copy_bits with
> 
>     tcpdump -n -c 100 -i ${DEV} -w /dev/null &
>     netperf -t TCP_STREAM -H ${HOST}
> 
>   and by triggering __skb_checksum with
> 
>     ethtool -K ${DEV} tx off
> 
>   repeated the tests with looping on a non-highmem platform
>   (x86_64) by making skb_frag_must_loop always return true.
> 
> Signed-off-by: Willem de Bruijn <willemb@google.com>

Ok, this looks good.

Thanks for following up on this.

Applied.

^ permalink raw reply

* Re: [PATCH] iwlwifi: Demote messages about fw flags size to info
From: João Paulo Rechi Vita @ 2017-08-01 22:58 UTC (permalink / raw)
  To: Coelho, Luciano
  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: <1500894086.20057.12.camel@intel.com>

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.

> 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.

Cheers,

......................................................................................
João Paulo Rechi Vita  |  +1.415.851.5778  |  Endless

^ permalink raw reply

* Re: [PATCH net-next v3 0/4] net-next: mediatek: add support for ethernet on MT7622 SoC
From: David Miller @ 2017-08-01 22:52 UTC (permalink / raw)
  To: sean.wang; +Cc: john, nbd, netdev, linux-kernel, linux-mediatek, keyhaede
In-Reply-To: <cover.1501494522.git.sean.wang@mediatek.com>

From: <sean.wang@mediatek.com>
Date: Mon, 31 Jul 2017 18:05:07 +0800

> From: Sean Wang <sean.wang@mediatek.com>
> 
> Changes since v2:
> - update John's mail
> 
> Changes since v1:
> - add refinement for ethernet clock management
> - take out the code block for ESW, add it until ESW driver is actually introduced
> 
> The series adds the driver for ethernet controller found on MT7622 SoC.
> There are additions against with previous MT7623 SoC such as shared SGMII
> given for the dual GMACs and built-in 5-ports 10/100 embedded switch support
> (ESW). Thus more clocks consumers and SGMII hardware setup for the extra
> features are all introduced here and as for the support for ESW that would be
> planned to add in the separate patch integrating with DSA infrastructure
> in the future.
> 
> Currently testing successfully is done with those patches for the conditions
> such as GMAC2 with IP1001 PHY via RGMII and GMAC1/2 with RTL8211F PHY via SGMII.

Series applied, thank you.

^ permalink raw reply

* Re: [PATCH net-next] net: dsa: Add support for 64-bit statistics
From: Florian Fainelli @ 2017-08-01 22:42 UTC (permalink / raw)
  To: netdev; +Cc: davem, Andrew Lunn, Vivien Didelot, open list
In-Reply-To: <20170801220036.11355-1-f.fainelli@gmail.com>

On 08/01/2017 03:00 PM, Florian Fainelli wrote:
> DSA slave network devices maintain a pair of bytes and packets counters
> for each directions, but these are not 64-bit capable. Re-use
> pcpu_sw_netstats which contains exactly what we need for that purpose
> and update the code path to report 64-bit capable statistics.

Humm, I do see a long time for ifconfig/ethtool -S to complete after
having transfered over 250GiB of data, the locking looks correct to me
in that statistics for the RX path are updated from softIRQ context
(napi_gro_receive/netif_receive_skb) but maybe I did misunderstand
whether the softirq/IRQ context applies to the producer and not the
reader...

> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
>  net/dsa/dsa.c      |  8 ++++++--
>  net/dsa/dsa_priv.h |  2 ++
>  net/dsa/slave.c    | 38 +++++++++++++++++++++++++++++++-------
>  3 files changed, 39 insertions(+), 9 deletions(-)
> 
> diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
> index a55e2e4087a4..0ba842c08dd3 100644
> --- a/net/dsa/dsa.c
> +++ b/net/dsa/dsa.c
> @@ -190,6 +190,7 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
>  {
>  	struct dsa_switch_tree *dst = dev->dsa_ptr;
>  	struct sk_buff *nskb = NULL;
> +	struct dsa_slave_priv *p;
>  
>  	if (unlikely(dst == NULL)) {
>  		kfree_skb(skb);
> @@ -207,12 +208,15 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
>  	}
>  
>  	skb = nskb;
> +	p = netdev_priv(skb->dev);
>  	skb_push(skb, ETH_HLEN);
>  	skb->pkt_type = PACKET_HOST;
>  	skb->protocol = eth_type_trans(skb, skb->dev);
>  
> -	skb->dev->stats.rx_packets++;
> -	skb->dev->stats.rx_bytes += skb->len;
> +	u64_stats_update_begin(&p->stats64.syncp);
> +	p->stats64.rx_packets++;
> +	p->stats64.rx_bytes += skb->len;
> +	u64_stats_update_end(&p->stats64.syncp);
>  
>  	netif_receive_skb(skb);
>  
> diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
> index 55982cc39b24..7aa0656296c2 100644
> --- a/net/dsa/dsa_priv.h
> +++ b/net/dsa/dsa_priv.h
> @@ -77,6 +77,8 @@ struct dsa_slave_priv {
>  	struct sk_buff *	(*xmit)(struct sk_buff *skb,
>  					struct net_device *dev);
>  
> +	struct pcpu_sw_netstats	stats64;
> +
>  	/* DSA port data, such as switch, port index, etc. */
>  	struct dsa_port		*dp;
>  
> diff --git a/net/dsa/slave.c b/net/dsa/slave.c
> index 9507bd38cf04..65f3cef85976 100644
> --- a/net/dsa/slave.c
> +++ b/net/dsa/slave.c
> @@ -354,8 +354,10 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
>  	struct dsa_slave_priv *p = netdev_priv(dev);
>  	struct sk_buff *nskb;
>  
> -	dev->stats.tx_packets++;
> -	dev->stats.tx_bytes += skb->len;
> +	u64_stats_update_begin(&p->stats64.syncp);
> +	p->stats64.tx_packets++;
> +	p->stats64.tx_bytes += skb->len;
> +	u64_stats_update_end(&p->stats64.syncp);
>  
>  	/* Transmit function may have to reallocate the original SKB,
>  	 * in which case it must have freed it. Only free it here on error.
> @@ -594,11 +596,15 @@ static void dsa_slave_get_ethtool_stats(struct net_device *dev,
>  {
>  	struct dsa_slave_priv *p = netdev_priv(dev);
>  	struct dsa_switch *ds = p->dp->ds;
> -
> -	data[0] = dev->stats.tx_packets;
> -	data[1] = dev->stats.tx_bytes;
> -	data[2] = dev->stats.rx_packets;
> -	data[3] = dev->stats.rx_bytes;
> +	unsigned int start;
> +
> +	do {
> +		start = u64_stats_fetch_begin_irq(&p->stats64.syncp);
> +		data[0] = p->stats64.tx_packets;
> +		data[1] = p->stats64.tx_bytes;
> +		data[2] = p->stats64.rx_packets;
> +		data[3] = p->stats64.rx_bytes;
> +	} while (u64_stats_fetch_retry_irq(&p->stats64.syncp, start));
>  	if (ds->ops->get_ethtool_stats)
>  		ds->ops->get_ethtool_stats(ds, p->dp->index, data + 4);
>  }
> @@ -861,6 +867,22 @@ static int dsa_slave_setup_tc(struct net_device *dev, u32 handle,
>  	}
>  }
>  
> +static void dsa_slave_get_stats64(struct net_device *dev,
> +				  struct rtnl_link_stats64 *stats)
> +{
> +	struct dsa_slave_priv *p = netdev_priv(dev);
> +	unsigned int start;
> +
> +	netdev_stats_to_stats64(stats, &dev->stats);
> +	do {
> +		start = u64_stats_fetch_begin_irq(&p->stats64.syncp);
> +		stats->tx_packets = p->stats64.tx_packets;
> +		stats->tx_bytes = p->stats64.tx_bytes;
> +		stats->rx_packets = p->stats64.rx_packets;
> +		stats->rx_bytes = p->stats64.rx_bytes;
> +	} while (u64_stats_fetch_retry_irq(&p->stats64.syncp, start));
> +}
> +
>  void dsa_cpu_port_ethtool_init(struct ethtool_ops *ops)
>  {
>  	ops->get_sset_count = dsa_cpu_port_get_sset_count;
> @@ -936,6 +958,7 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
>  	.ndo_bridge_dellink	= switchdev_port_bridge_dellink,
>  	.ndo_get_phys_port_name	= dsa_slave_get_phys_port_name,
>  	.ndo_setup_tc		= dsa_slave_setup_tc,
> +	.ndo_get_stats64	= dsa_slave_get_stats64,
>  };
>  
>  static const struct switchdev_ops dsa_slave_switchdev_ops = {
> @@ -1171,6 +1194,7 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
>  	slave_dev->vlan_features = master->vlan_features;
>  
>  	p = netdev_priv(slave_dev);
> +	u64_stats_init(&p->stats64.syncp);
>  	p->dp = &ds->ports[port];
>  	INIT_LIST_HEAD(&p->mall_tc_list);
>  	p->xmit = dst->tag_ops->xmit;
> 


-- 
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