* [PATCH net-next 2/2] bindings: net: stmmac: Add documentation for TSN parameters
From: Jose Abreu @ 2017-10-25 14:04 UTC (permalink / raw)
To: netdev, linux-kernel, devicetree
Cc: Jose Abreu, David S. Miller, Joao Pinto, Giuseppe Cavallaro,
Alexandre Torgue, Rob Herring
In-Reply-To: <cover.1508938927.git.joabreu@synopsys.com>
This adds the documentation for TSN feature EST and FP.
Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Joao Pinto <jpinto@synopsys.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: Rob Herring <robh+dt@kernel.org>
---
Documentation/devicetree/bindings/net/stmmac.txt | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt
index c3a7be6..6359df6 100644
--- a/Documentation/devicetree/bindings/net/stmmac.txt
+++ b/Documentation/devicetree/bindings/net/stmmac.txt
@@ -114,6 +114,16 @@ Optional properties:
- snps,high_credit: max write outstanding req. limit
- snps,low_credit: max read outstanding req. limit
- snps,priority: TX queue priority (Range: 0x0 to 0xF)
+- TSN parameters: below the list of all the parameters to configure TSN
+ features (only applicable for IP version >= 5.00)
+ - snps,est: Enable EST algorithm
+ - If EST enabled provide these parameters:
+ - snps,btr: Array size of 2 with BTR value for EST algorithm
+ - snps,ctr: Array size of 2 with CTR value for EST algorithm
+ - snps,ter: TER value for EST algorithm
+ - snps,gcl: Variable size array with GCL table entries.
+ - snps,fp: Enable FP feature. This needs EST enabled.
+
Examples:
stmmac_axi_setup: stmmac-axi-config {
@@ -151,6 +161,15 @@ Examples:
};
};
+ tsn_setup: tsn-config {
+ snps,est;
+ snps,btr = <0x00000000 0x00000001>;
+ snps,ctr = <0x00000000 0x10000000>;
+ snps,ter = <0x00000000>;
+ snps,gcl = <0x00000001 0x00000002 0x00000003>;
+ snps,fp;
+ };
+
gmac0: ethernet@e0800000 {
compatible = "st,spear600-gmac";
reg = <0xe0800000 0x8000>;
@@ -176,4 +195,5 @@ Examples:
};
snps,mtl-rx-config = <&mtl_rx_setup>;
snps,mtl-tx-config = <&mtl_tx_setup>;
+ snps,tsn-config = <&tsn_setup>;
};
--
1.9.1
^ permalink raw reply related
* [RFC PATCH 07/12] xfrm: Move child route linkage into xfrm_dst.
From: David Miller @ 2017-10-25 14:03 UTC (permalink / raw)
To: netdev
XFRM bundle child chains look like this:
xdst1 --> xdst2 --> xdst3 --> path_dst
All of xdstN are xfrm_dst objects and xdst->u.dst.xfrm is non-NULL.
The final child pointer in the chain, here called 'path_dst', is some
other kind of route such as an ipv4 or ipv6 one.
The xfrm output path pops routes, one at a time, via the child
pointer, until we hit one which has a dst->xfrm pointer which
is NULL.
We can easily preserve the above mechanisms with child sitting
only in the xfrm_dst structure. All children in the chain
before we break out of the xfrm_output() loop have dst->xfrm
non-NULL and are therefore xfrm_dst objects.
Since we break out of the loop when we find dst->xfrm NULL, we
will not try to dereference 'dst' as if it were an xfrm_dst.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/dst.h | 12 +-----------
include/net/xfrm.h | 14 ++++++++++++--
net/core/dst.c | 2 +-
net/core/pktgen.c | 12 ++++++------
4 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 360d214..1e96e5e 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -34,7 +34,6 @@ struct sk_buff;
struct dst_entry {
struct net_device *dev;
struct rcu_head rcu_head;
- struct dst_entry *child;
struct dst_ops *ops;
unsigned long _metrics;
unsigned long expires;
@@ -88,7 +87,7 @@ struct dst_entry {
* Align __refcnt to a 64 bytes alignment
* (L1_CACHE_SIZE would be too much)
*/
- long __pad_to_align_refcnt[2];
+ long __pad_to_align_refcnt[3];
#endif
/*
* __refcnt wants to be on a different cache line from
@@ -242,15 +241,6 @@ dst_metric_locked(const struct dst_entry *dst, int metric)
return dst_metric(dst, RTAX_LOCK) & (1<<metric);
}
-static inline struct dst_entry *dst_child(const struct dst_entry *dst)
-{
-#ifdef CONFIG_XFRM
- if (dst->xfrm)
- return dst->child;
-#endif
- return NULL;
-}
-
static inline void dst_hold(struct dst_entry *dst)
{
/*
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 572a9cc..f805eb6 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -983,6 +983,7 @@ struct xfrm_dst {
struct rt6_info rt6;
} u;
struct dst_entry *route;
+ struct dst_entry *child;
struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
int num_pols, num_xfrms;
u32 xfrm_genid;
@@ -993,6 +994,15 @@ struct xfrm_dst {
u32 path_cookie;
};
+static inline struct dst_entry *dst_child(const struct dst_entry *dst)
+{
+#ifdef CONFIG_XFRM
+ if (dst->xfrm)
+ return ((struct xfrm_dst *)dst)->child;
+#endif
+ return NULL;
+}
+
#ifdef CONFIG_XFRM
static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
{
@@ -1004,14 +1014,14 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
static inline struct xfrm_dst *xfrm_dst_child(const struct xfrm_dst *xdst)
{
- struct dst_entry *child = dst_child(&xdst->u.dst);
+ struct dst_entry *child = xdst->child;
return (struct xfrm_dst *) child;
}
static inline void xfrm_dst_set_child(struct xfrm_dst *xdst, struct dst_entry *child)
{
- xdst->u.dst.child = child;
+ xdst->child = child;
}
#endif
diff --git a/net/core/dst.c b/net/core/dst.c
index 3f83669..fb12e34 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -21,6 +21,7 @@
#include <linux/sched.h>
#include <linux/prefetch.h>
#include <net/lwtunnel.h>
+#include <net/xfrm.h>
#include <net/dst.h>
#include <net/dst_metadata.h>
@@ -62,7 +63,6 @@ void dst_init(struct dst_entry *dst, struct dst_ops *ops,
struct net_device *dev, int initial_ref, int initial_obsolete,
unsigned short flags)
{
- dst->child = NULL;
dst->dev = dev;
if (dev)
dev_hold(dev);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 6e1e10f..099b0a2 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -399,7 +399,7 @@ struct pktgen_dev {
__u8 ipsmode; /* IPSEC mode (config) */
__u8 ipsproto; /* IPSEC type (config) */
__u32 spi;
- struct dst_entry dst;
+ struct xfrm_dst xdst;
struct dst_ops dstops;
#endif
char result[512];
@@ -2609,7 +2609,7 @@ static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev)
* supports both transport/tunnel mode + ESP/AH type.
*/
if ((x->props.mode == XFRM_MODE_TUNNEL) && (pkt_dev->spi != 0))
- skb->_skb_refdst = (unsigned long)&pkt_dev->dst | SKB_DST_NOREF;
+ skb->_skb_refdst = (unsigned long)&pkt_dev->xdst.u.dst | SKB_DST_NOREF;
rcu_read_lock_bh();
err = x->outer_mode->output(x, skb);
@@ -3734,10 +3734,10 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
* performance under such circumstance.
*/
pkt_dev->dstops.family = AF_INET;
- pkt_dev->dst.dev = pkt_dev->odev;
- dst_init_metrics(&pkt_dev->dst, pktgen_dst_metrics, false);
- pkt_dev->dst.child = &pkt_dev->dst;
- pkt_dev->dst.ops = &pkt_dev->dstops;
+ pkt_dev->xdst.u.dst.dev = pkt_dev->odev;
+ dst_init_metrics(&pkt_dev->xdst.u.dst, pktgen_dst_metrics, false);
+ pkt_dev->xdst.child = &pkt_dev->xdst.u.dst;
+ pkt_dev->xdst.u.dst.ops = &pkt_dev->dstops;
#endif
return add_dev_to_thread(t, pkt_dev);
--
2.1.2.532.g19b5d50
---
include/net/dst.h | 3 +--
include/net/xfrm.h | 13 +++++++++----
net/core/dst.c | 9 ++++++---
net/core/pktgen.c | 12 ++++++------
net/netfilter/xt_policy.c | 3 ++-
net/xfrm/xfrm_device.c | 2 +-
6 files changed, 25 insertions(+), 17 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 2409e7795ad5..6c6f0140759d 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -34,7 +34,6 @@ struct sk_buff;
struct dst_entry {
struct net_device *dev;
struct rcu_head rcu_head;
- struct dst_entry *child;
struct dst_ops *ops;
unsigned long _metrics;
unsigned long expires;
@@ -88,7 +87,7 @@ struct dst_entry {
* Align __refcnt to a 64 bytes alignment
* (L1_CACHE_SIZE would be too much)
*/
- long __pad_to_align_refcnt[2];
+ long __pad_to_align_refcnt[3];
#endif
/*
* __refcnt wants to be on a different cache line from
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 5a4cc05ff9e8..6509ba4316c7 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -983,6 +983,7 @@ struct xfrm_dst {
struct rt6_info rt6;
} u;
struct dst_entry *route;
+ struct dst_entry *child;
struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
int num_pols, num_xfrms;
u32 xfrm_genid;
@@ -997,15 +998,17 @@ struct xfrm_dst {
static inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst)
{
#ifdef CONFIG_XFRM
- if (dst->xfrm)
- return dst->child;
+ if (dst->xfrm) {
+ struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
+ return xdst->child;
+ }
#endif
return NULL;
}
static inline void xfrm_dst_set_child(struct xfrm_dst *xdst, struct dst_entry *child)
{
- xdst->u.dst.child = child;
+ xdst->child = child;
}
static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
@@ -1879,12 +1882,14 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
{
struct xfrm_state *x = dst->xfrm;
+ struct xfrm_dst *xdst;
if (!x || !x->type_offload)
return false;
+ xdst = (struct xfrm_dst *) dst;
if (x->xso.offload_handle && (x->xso.dev == dst->path->dev) &&
- !dst->child->xfrm)
+ !xdst->child->xfrm)
return true;
return false;
diff --git a/net/core/dst.c b/net/core/dst.c
index 6a3c21b8fc8d..5cf96179e8e0 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -21,6 +21,7 @@
#include <linux/sched.h>
#include <linux/prefetch.h>
#include <net/lwtunnel.h>
+#include <net/xfrm.h>
#include <net/dst.h>
#include <net/dst_metadata.h>
@@ -62,7 +63,6 @@ void dst_init(struct dst_entry *dst, struct dst_ops *ops,
struct net_device *dev, int initial_ref, int initial_obsolete,
unsigned short flags)
{
- dst->child = NULL;
dst->dev = dev;
if (dev)
dev_hold(dev);
@@ -121,8 +121,11 @@ struct dst_entry *dst_destroy(struct dst_entry * dst)
smp_rmb();
#ifdef CONFIG_XFRM
- if (dst->xfrm)
- child = dst->child;
+ if (dst->xfrm) {
+ struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
+
+ child = xdst->child;
+ }
#endif
if (!(dst->flags & DST_NOCOUNT))
dst_entries_add(dst->ops, -1);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 6e1e10ff433a..099b0a2f6bb2 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -399,7 +399,7 @@ struct pktgen_dev {
__u8 ipsmode; /* IPSEC mode (config) */
__u8 ipsproto; /* IPSEC type (config) */
__u32 spi;
- struct dst_entry dst;
+ struct xfrm_dst xdst;
struct dst_ops dstops;
#endif
char result[512];
@@ -2609,7 +2609,7 @@ static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev)
* supports both transport/tunnel mode + ESP/AH type.
*/
if ((x->props.mode == XFRM_MODE_TUNNEL) && (pkt_dev->spi != 0))
- skb->_skb_refdst = (unsigned long)&pkt_dev->dst | SKB_DST_NOREF;
+ skb->_skb_refdst = (unsigned long)&pkt_dev->xdst.u.dst | SKB_DST_NOREF;
rcu_read_lock_bh();
err = x->outer_mode->output(x, skb);
@@ -3734,10 +3734,10 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
* performance under such circumstance.
*/
pkt_dev->dstops.family = AF_INET;
- pkt_dev->dst.dev = pkt_dev->odev;
- dst_init_metrics(&pkt_dev->dst, pktgen_dst_metrics, false);
- pkt_dev->dst.child = &pkt_dev->dst;
- pkt_dev->dst.ops = &pkt_dev->dstops;
+ pkt_dev->xdst.u.dst.dev = pkt_dev->odev;
+ dst_init_metrics(&pkt_dev->xdst.u.dst, pktgen_dst_metrics, false);
+ pkt_dev->xdst.child = &pkt_dev->xdst.u.dst;
+ pkt_dev->xdst.u.dst.ops = &pkt_dev->dstops;
#endif
return add_dev_to_thread(t, pkt_dev);
diff --git a/net/netfilter/xt_policy.c b/net/netfilter/xt_policy.c
index 2b4ab189bba7..5639fb03bdd9 100644
--- a/net/netfilter/xt_policy.c
+++ b/net/netfilter/xt_policy.c
@@ -93,7 +93,8 @@ match_policy_out(const struct sk_buff *skb, const struct xt_policy_info *info,
if (dst->xfrm == NULL)
return -1;
- for (i = 0; dst && dst->xfrm; dst = dst->child, i++) {
+ for (i = 0; dst && dst->xfrm;
+ dst = ((struct xfrm_dst *)dst)->child, i++) {
pos = strict ? i : 0;
if (pos >= info->len)
return 0;
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index 30e5746085b8..c5851ddddd2a 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -121,7 +121,7 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
return false;
if ((x->xso.offload_handle && (dev == dst->path->dev)) &&
- !dst->child->xfrm && x->type->get_mtu) {
+ !xdst->child->xfrm && x->type->get_mtu) {
mtu = x->type->get_mtu(x, xdst->child_mtu_cached);
if (skb->len <= mtu)
--
2.13.6
^ permalink raw reply related
* [RFC PATCH 08/12] ipv6: Move dst->from into struct rt6_info.
From: David Miller @ 2017-10-25 14:04 UTC (permalink / raw)
To: netdev
The dst->from value is only used by ipv6 routes to track where
a route "came from".
Any time we clone or copy a core ipv6 route in the ipv6 routing
tables, we have the copy/clone's ->from point to the base route.
This is used to handle route expiration properly.
Only ipv6 uses this mechanism, and only ipv6 code references
it. So it is safe to move it into rt6_info.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/dst.h | 3 +--
include/net/ip6_fib.h | 9 ++++-----
net/core/dst.c | 1 -
net/ipv6/route.c | 34 +++++++++++++++++-----------------
4 files changed, 22 insertions(+), 25 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 6c6f0140759d..9ec3fd59c3e7 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -38,7 +38,6 @@ struct dst_entry {
unsigned long _metrics;
unsigned long expires;
struct dst_entry *path;
- struct dst_entry *from;
#ifdef CONFIG_XFRM
struct xfrm_state *xfrm;
#else
@@ -87,7 +86,7 @@ struct dst_entry {
* Align __refcnt to a 64 bytes alignment
* (L1_CACHE_SIZE would be too much)
*/
- long __pad_to_align_refcnt[3];
+ long __pad_to_align_refcnt[4];
#endif
/*
* __refcnt wants to be on a different cache line from
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 281a922f0c62..44d96a91e745 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -130,6 +130,7 @@ struct rt6_exception {
struct rt6_info {
struct dst_entry dst;
struct rt6_info __rcu *rt6_next;
+ struct rt6_info *from;
/*
* Tail elements of dst_entry (__refcnt etc.)
@@ -204,11 +205,9 @@ static inline void rt6_update_expires(struct rt6_info *rt0, int timeout)
{
struct rt6_info *rt;
- for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES);
- rt = (struct rt6_info *)rt->dst.from);
+ for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES); rt = rt->from);
if (rt && rt != rt0)
rt0->dst.expires = rt->dst.expires;
-
dst_set_expires(&rt0->dst, timeout);
rt0->rt6i_flags |= RTF_EXPIRES;
}
@@ -243,8 +242,8 @@ static inline u32 rt6_get_cookie(const struct rt6_info *rt)
u32 cookie = 0;
if (rt->rt6i_flags & RTF_PCPU ||
- (unlikely(!list_empty(&rt->rt6i_uncached)) && rt->dst.from))
- rt = (struct rt6_info *)(rt->dst.from);
+ (unlikely(!list_empty(&rt->rt6i_uncached)) && rt->from))
+ rt = rt->from;
rt6_get_cookie_safe(rt, &cookie);
diff --git a/net/core/dst.c b/net/core/dst.c
index 5cf96179e8e0..cf2076c0eb22 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -70,7 +70,6 @@ void dst_init(struct dst_entry *dst, struct dst_ops *ops,
dst_init_metrics(dst, dst_default_metrics.metrics, true);
dst->expires = 0UL;
dst->path = dst;
- dst->from = NULL;
#ifdef CONFIG_XFRM
dst->xfrm = NULL;
#endif
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 3c943d252a33..475c57e8fa90 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -186,7 +186,7 @@ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev)
static u32 *rt6_pcpu_cow_metrics(struct rt6_info *rt)
{
- return dst_metrics_write_ptr(rt->dst.from);
+ return dst_metrics_write_ptr(&rt->from->dst);
}
static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
@@ -391,7 +391,7 @@ static void ip6_dst_destroy(struct dst_entry *dst)
{
struct rt6_info *rt = (struct rt6_info *)dst;
struct rt6_exception_bucket *bucket;
- struct dst_entry *from = dst->from;
+ struct rt6_info *from = rt->from;
struct inet6_dev *idev;
dst_destroy_metrics_generic(dst);
@@ -409,8 +409,8 @@ static void ip6_dst_destroy(struct dst_entry *dst)
kfree(bucket);
}
- dst->from = NULL;
- dst_release(from);
+ rt->from = NULL;
+ dst_release(&from->dst);
}
static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
@@ -443,9 +443,9 @@ static bool rt6_check_expired(const struct rt6_info *rt)
if (rt->rt6i_flags & RTF_EXPIRES) {
if (time_after(jiffies, rt->dst.expires))
return true;
- } else if (rt->dst.from) {
+ } else if (rt->from) {
return rt->dst.obsolete != DST_OBSOLETE_FORCE_CHK ||
- rt6_check_expired((struct rt6_info *)rt->dst.from);
+ rt6_check_expired(rt->from);
}
return false;
}
@@ -1049,7 +1049,7 @@ static struct rt6_info *ip6_rt_cache_alloc(struct rt6_info *ort,
*/
if (ort->rt6i_flags & (RTF_CACHE | RTF_PCPU))
- ort = (struct rt6_info *)ort->dst.from;
+ ort = ort->from;
rcu_read_lock();
dev = ip6_rt_get_dev_rcu(ort);
@@ -1269,7 +1269,7 @@ static int rt6_insert_exception(struct rt6_info *nrt,
/* ort can't be a cache or pcpu route */
if (ort->rt6i_flags & (RTF_CACHE | RTF_PCPU))
- ort = (struct rt6_info *)ort->dst.from;
+ ort = ort->from;
WARN_ON_ONCE(ort->rt6i_flags & (RTF_CACHE | RTF_PCPU));
spin_lock_bh(&rt6_exception_lock);
@@ -1410,8 +1410,8 @@ static struct rt6_info *rt6_find_cached_rt(struct rt6_info *rt,
/* Remove the passed in cached rt from the hash table that contains it */
int rt6_remove_exception_rt(struct rt6_info *rt)
{
- struct rt6_info *from = (struct rt6_info *)rt->dst.from;
struct rt6_exception_bucket *bucket;
+ struct rt6_info *from = rt->from;
struct in6_addr *src_key = NULL;
struct rt6_exception *rt6_ex;
int err;
@@ -1455,8 +1455,8 @@ int rt6_remove_exception_rt(struct rt6_info *rt)
*/
static void rt6_update_exception_stamp_rt(struct rt6_info *rt)
{
- struct rt6_info *from = (struct rt6_info *)rt->dst.from;
struct rt6_exception_bucket *bucket;
+ struct rt6_info *from = rt->from;
struct in6_addr *src_key = NULL;
struct rt6_exception *rt6_ex;
@@ -1924,9 +1924,9 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
static void rt6_dst_from_metrics_check(struct rt6_info *rt)
{
- if (rt->dst.from &&
- dst_metrics_ptr(&rt->dst) != dst_metrics_ptr(rt->dst.from))
- dst_init_metrics(&rt->dst, dst_metrics_ptr(rt->dst.from), true);
+ if (rt->from &&
+ dst_metrics_ptr(&rt->dst) != dst_metrics_ptr(&rt->from->dst))
+ dst_init_metrics(&rt->dst, dst_metrics_ptr(&rt->from->dst), true);
}
static struct dst_entry *rt6_check(struct rt6_info *rt, u32 cookie)
@@ -1946,7 +1946,7 @@ static struct dst_entry *rt6_dst_from_check(struct rt6_info *rt, u32 cookie)
{
if (!__rt6_check_expired(rt) &&
rt->dst.obsolete == DST_OBSOLETE_FORCE_CHK &&
- rt6_check((struct rt6_info *)(rt->dst.from), cookie))
+ rt6_check(rt->from, cookie))
return &rt->dst;
else
return NULL;
@@ -1966,7 +1966,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
rt6_dst_from_metrics_check(rt);
if (rt->rt6i_flags & RTF_PCPU ||
- (unlikely(!list_empty(&rt->rt6i_uncached)) && rt->dst.from))
+ (unlikely(!list_empty(&rt->rt6i_uncached)) && rt->from))
return rt6_dst_from_check(rt, cookie);
else
return rt6_check(rt, cookie);
@@ -3043,11 +3043,11 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
static void rt6_set_from(struct rt6_info *rt, struct rt6_info *from)
{
- BUG_ON(from->dst.from);
+ BUG_ON(from->from);
rt->rt6i_flags &= ~RTF_EXPIRES;
dst_hold(&from->dst);
- rt->dst.from = &from->dst;
+ rt->from = from;
dst_init_metrics(&rt->dst, dst_metrics_ptr(&from->dst), true);
}
--
2.13.6
^ permalink raw reply related
* [RFC PATCH 09/12] xfrm: Move dst->path into struct xfrm_dst
From: David Miller @ 2017-10-25 14:04 UTC (permalink / raw)
To: netdev
The first member of an IPSEC route bundle chain sets it's dst->path to
the underlying ipv4/ipv6 route that carries the bundle.
Stated another way, if one were to follow the xfrm_dst->child chain of
the bundle, the final non-NULL pointer would be the path and point to
either an ipv4 or an ipv6 route.
This is largely used to make sure that PMTU events propagate down to
the correct ipv4 or ipv6 route.
When we don't have the top of an IPSEC bundle 'dst->path == dst'.
Move it down into xfrm_dst and key off of dst->xfrm.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/dst.h | 3 +--
include/net/xfrm.h | 15 ++++++++++++++-
net/bridge/br_nf_core.c | 1 -
net/core/dst.c | 1 -
net/ipv4/route.c | 2 +-
net/ipv6/ip6_output.c | 4 ++--
net/ipv6/route.c | 6 ------
net/xfrm/xfrm_device.c | 2 +-
net/xfrm/xfrm_policy.c | 28 ++++++++++++++--------------
9 files changed, 33 insertions(+), 29 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 9ec3fd59c3e7..ca6495f237d5 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -37,7 +37,6 @@ struct dst_entry {
struct dst_ops *ops;
unsigned long _metrics;
unsigned long expires;
- struct dst_entry *path;
#ifdef CONFIG_XFRM
struct xfrm_state *xfrm;
#else
@@ -86,7 +85,7 @@ struct dst_entry {
* Align __refcnt to a 64 bytes alignment
* (L1_CACHE_SIZE would be too much)
*/
- long __pad_to_align_refcnt[4];
+ long __pad_to_align_refcnt[5];
#endif
/*
* __refcnt wants to be on a different cache line from
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 6509ba4316c7..1fc54c96e266 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -984,6 +984,7 @@ struct xfrm_dst {
} u;
struct dst_entry *route;
struct dst_entry *child;
+ struct dst_entry *path;
struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
int num_pols, num_xfrms;
u32 xfrm_genid;
@@ -994,7 +995,18 @@ struct xfrm_dst {
u32 path_cookie;
};
+static struct dst_entry *xfrm_dst_path(const struct dst_entry *dst)
+{
#ifdef CONFIG_XFRM
+ if (dst->xfrm) {
+ const struct xfrm_dst *xdst = (const struct xfrm_dst *) dst;
+
+ return xdst->path;
+ }
+#endif
+ return (struct dst_entry *) dst;
+}
+
static inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst)
{
#ifdef CONFIG_XFRM
@@ -1006,6 +1018,7 @@ static inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst)
return NULL;
}
+#ifdef CONFIG_XFRM
static inline void xfrm_dst_set_child(struct xfrm_dst *xdst, struct dst_entry *child)
{
xdst->child = child;
@@ -1888,7 +1901,7 @@ static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
return false;
xdst = (struct xfrm_dst *) dst;
- if (x->xso.offload_handle && (x->xso.dev == dst->path->dev) &&
+ if (x->xso.offload_handle && (x->xso.dev == xfrm_dst_path(dst)->dev) &&
!xdst->child->xfrm)
return true;
diff --git a/net/bridge/br_nf_core.c b/net/bridge/br_nf_core.c
index 20cbb727df4d..8e2d7cfa4e16 100644
--- a/net/bridge/br_nf_core.c
+++ b/net/bridge/br_nf_core.c
@@ -78,7 +78,6 @@ void br_netfilter_rtable_init(struct net_bridge *br)
atomic_set(&rt->dst.__refcnt, 1);
rt->dst.dev = br->dev;
- rt->dst.path = &rt->dst;
dst_init_metrics(&rt->dst, br_dst_default_metrics, true);
rt->dst.flags = DST_NOXFRM | DST_FAKE_RTABLE;
rt->dst.ops = &fake_dst_ops;
diff --git a/net/core/dst.c b/net/core/dst.c
index cf2076c0eb22..9bc3bb6e94ef 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -69,7 +69,6 @@ void dst_init(struct dst_entry *dst, struct dst_ops *ops,
dst->ops = ops;
dst_init_metrics(dst, dst_default_metrics.metrics, true);
dst->expires = 0UL;
- dst->path = dst;
#ifdef CONFIG_XFRM
dst->xfrm = NULL;
#endif
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index bc40bd411196..5ff6e3edcd3e 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1102,7 +1102,7 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
new = true;
}
- __ip_rt_update_pmtu((struct rtable *) rt->dst.path, &fl4, mtu);
+ __ip_rt_update_pmtu((struct rtable *) xfrm_dst_path(&rt->dst), &fl4, mtu);
if (!dst_check(&rt->dst, 0)) {
if (new)
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 5110a418cc4d..176d74fb3b4d 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1201,13 +1201,13 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
rt->dst.dev->mtu : dst_mtu(&rt->dst);
else
mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
- rt->dst.dev->mtu : dst_mtu(rt->dst.path);
+ rt->dst.dev->mtu : dst_mtu(xfrm_dst_path(&rt->dst));
if (np->frag_size < mtu) {
if (np->frag_size)
mtu = np->frag_size;
}
cork->base.fragsize = mtu;
- if (dst_allfrag(rt->dst.path))
+ if (dst_allfrag(xfrm_dst_path(&rt->dst)))
cork->base.flags |= IPCORK_ALLFRAG;
cork->base.length = 0;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 475c57e8fa90..1eb0bfed015f 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -4584,8 +4584,6 @@ static int __net_init ip6_route_net_init(struct net *net)
GFP_KERNEL);
if (!net->ipv6.ip6_null_entry)
goto out_ip6_dst_entries;
- net->ipv6.ip6_null_entry->dst.path =
- (struct dst_entry *)net->ipv6.ip6_null_entry;
net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops;
dst_init_metrics(&net->ipv6.ip6_null_entry->dst,
ip6_template_metrics, true);
@@ -4597,8 +4595,6 @@ static int __net_init ip6_route_net_init(struct net *net)
GFP_KERNEL);
if (!net->ipv6.ip6_prohibit_entry)
goto out_ip6_null_entry;
- net->ipv6.ip6_prohibit_entry->dst.path =
- (struct dst_entry *)net->ipv6.ip6_prohibit_entry;
net->ipv6.ip6_prohibit_entry->dst.ops = &net->ipv6.ip6_dst_ops;
dst_init_metrics(&net->ipv6.ip6_prohibit_entry->dst,
ip6_template_metrics, true);
@@ -4608,8 +4604,6 @@ static int __net_init ip6_route_net_init(struct net *net)
GFP_KERNEL);
if (!net->ipv6.ip6_blk_hole_entry)
goto out_ip6_prohibit_entry;
- net->ipv6.ip6_blk_hole_entry->dst.path =
- (struct dst_entry *)net->ipv6.ip6_blk_hole_entry;
net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
ip6_template_metrics, true);
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index c5851ddddd2a..c61a7d46b412 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -120,7 +120,7 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
if (!x->type_offload || x->encap)
return false;
- if ((x->xso.offload_handle && (dev == dst->path->dev)) &&
+ if ((x->xso.offload_handle && (dev == xfrm_dst_path(dst)->dev)) &&
!xdst->child->xfrm && x->type->get_mtu) {
mtu = x->type->get_mtu(x, xdst->child_mtu_cached);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 206ac90ff4f0..7b80ee7486db 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1625,7 +1625,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
}
xfrm_dst_set_child(xdst_prev, dst);
- xdst0->u.dst.path = dst;
+ xdst0->path = dst;
err = -ENODEV;
dev = dst->dev;
@@ -1872,8 +1872,8 @@ static void xfrm_policy_queue_process(struct timer_list *t)
xfrm_decode_session(skb, &fl, dst->ops->family);
spin_unlock(&pq->hold_queue.lock);
- dst_hold(dst->path);
- dst = xfrm_lookup(net, dst->path, &fl, sk, 0);
+ dst_hold(xfrm_dst_path(dst));
+ dst = xfrm_lookup(net, xfrm_dst_path(dst), &fl, sk, 0);
if (IS_ERR(dst))
goto purge_queue;
@@ -1902,8 +1902,8 @@ static void xfrm_policy_queue_process(struct timer_list *t)
skb = __skb_dequeue(&list);
xfrm_decode_session(skb, &fl, skb_dst(skb)->ops->family);
- dst_hold(skb_dst(skb)->path);
- dst = xfrm_lookup(net, skb_dst(skb)->path, &fl, skb->sk, 0);
+ dst_hold(xfrm_dst_path(skb_dst(skb)));
+ dst = xfrm_lookup(net, xfrm_dst_path(skb_dst(skb)), &fl, skb->sk, 0);
if (IS_ERR(dst)) {
kfree_skb(skb);
continue;
@@ -2005,7 +2005,7 @@ static struct xfrm_dst *xfrm_create_dummy_bundle(struct net *net,
dst_hold(dst);
xfrm_dst_set_child(xdst, dst);
- dst1->path = dst;
+ xdst->path = dst;
xfrm_init_path((struct xfrm_dst *)dst1, dst, 0);
@@ -2624,7 +2624,7 @@ static int xfrm_bundle_ok(struct xfrm_dst *first)
struct xfrm_dst *last;
u32 mtu;
- if (!dst_check(dst->path, ((struct xfrm_dst *)dst)->path_cookie) ||
+ if (!dst_check(xfrm_dst_path(dst), ((struct xfrm_dst *)dst)->path_cookie) ||
(dst->dev && !netif_running(dst->dev)))
return 0;
@@ -2685,22 +2685,20 @@ static int xfrm_bundle_ok(struct xfrm_dst *first)
static unsigned int xfrm_default_advmss(const struct dst_entry *dst)
{
- return dst_metric_advmss(dst->path);
+ return dst_metric_advmss(xfrm_dst_path(dst));
}
static unsigned int xfrm_mtu(const struct dst_entry *dst)
{
unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
- return mtu ? : dst_mtu(dst->path);
+ return mtu ? : dst_mtu(xfrm_dst_path(dst));
}
static const void *xfrm_get_dst_nexthop(const struct dst_entry *dst,
const void *daddr)
{
- const struct dst_entry *path = dst->path;
-
- for (; dst != path; dst = xfrm_dst_child(dst)) {
+ while (dst->xfrm) {
const struct xfrm_state *xfrm = dst->xfrm;
if (xfrm->props.mode == XFRM_MODE_TRANSPORT)
@@ -2709,6 +2707,8 @@ static const void *xfrm_get_dst_nexthop(const struct dst_entry *dst,
daddr = xfrm->coaddr;
else if (!(xfrm->type->flags & XFRM_TYPE_LOCAL_COADDR))
daddr = &xfrm->id.daddr;
+
+ dst = xfrm_dst_child(dst);
}
return daddr;
}
@@ -2717,7 +2717,7 @@ static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst,
struct sk_buff *skb,
const void *daddr)
{
- const struct dst_entry *path = dst->path;
+ const struct dst_entry *path = xfrm_dst_path(dst);
if (!skb)
daddr = xfrm_get_dst_nexthop(dst, daddr);
@@ -2726,7 +2726,7 @@ static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst,
static void xfrm_confirm_neigh(const struct dst_entry *dst, const void *daddr)
{
- const struct dst_entry *path = dst->path;
+ const struct dst_entry *path = xfrm_dst_path(dst);
daddr = xfrm_get_dst_nexthop(dst, daddr);
path->ops->confirm_neigh(path, daddr);
--
2.13.6
^ permalink raw reply related
* [RFC PATCH 10/12] net: Rearrange dst_entry layout to avoid useless padding.
From: David Miller @ 2017-10-25 14:04 UTC (permalink / raw)
To: netdev
We have padding to try and align the refcount on a separate cache
line. But after several simplifications the padding has increased
substantially.
So now it's easy to change the layout to get rid of the padding
entirely.
We group the write-heavy __refcnt and __use with less often used
items such as the rcu_head and the error code.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/dst.h | 22 +++++-----------------
1 file changed, 5 insertions(+), 17 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index ca6495f237d5..403b1c02a26f 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -33,7 +33,6 @@ struct sk_buff;
struct dst_entry {
struct net_device *dev;
- struct rcu_head rcu_head;
struct dst_ops *ops;
unsigned long _metrics;
unsigned long expires;
@@ -55,8 +54,6 @@ struct dst_entry {
#define DST_XFRM_QUEUE 0x0040
#define DST_METADATA 0x0080
- short error;
-
/* A non-zero value of dst->obsolete forces by-hand validation
* of the route entry. Positive values are set by the generic
* dst layer to indicate that the entry has been forcefully
@@ -72,21 +69,7 @@ struct dst_entry {
#define DST_OBSOLETE_KILL -2
unsigned short header_len; /* more space at head required */
unsigned short trailer_len; /* space to reserve at tail */
- unsigned short __pad3;
-
-#ifdef CONFIG_IP_ROUTE_CLASSID
- __u32 tclassid;
-#else
- __u32 __pad2;
-#endif
-#ifdef CONFIG_64BIT
- /*
- * Align __refcnt to a 64 bytes alignment
- * (L1_CACHE_SIZE would be too much)
- */
- long __pad_to_align_refcnt[5];
-#endif
/*
* __refcnt wants to be on a different cache line from
* input/output/ops or performance tanks badly
@@ -95,6 +78,11 @@ struct dst_entry {
int __use;
unsigned long lastuse;
struct lwtunnel_state *lwtstate;
+ struct rcu_head rcu_head;
+ short error;
+ short __pad;
+ __u32 tclassid;
+
union {
struct dst_entry *next;
};
--
2.13.6
^ permalink raw reply related
* [RFC PATCH 11/12] xfrm: Stop using dst->next in bundle construction.
From: David Miller @ 2017-10-25 14:04 UTC (permalink / raw)
To: netdev
While building ipsec bundles, blocks of xfrm dsts are linked together
using dst->next from bottom to the top.
The only thing this is used for is initializing the pmtu values of the
xfrm stack, and for updating the mtu values at xfrm_bundle_ok() time.
The bundle pmtu entries must be processed in this order so that pmtu
values lower in the stack of routes can propagate up to the higher
ones.
Avoid using dst->next by simply maintaining an array of dst pointers
as we already do for the xfrm_state objects when building the bundle.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/xfrm/xfrm_policy.c | 56 ++++++++++++++++++++++++++++----------------------
1 file changed, 32 insertions(+), 24 deletions(-)
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 7b80ee7486db..b815884deb16 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -54,7 +54,7 @@ static struct xfrm_policy_afinfo const __rcu *xfrm_policy_afinfo[AF_INET6 + 1]
static struct kmem_cache *xfrm_dst_cache __read_mostly;
static __read_mostly seqcount_t xfrm_policy_hash_generation;
-static void xfrm_init_pmtu(struct dst_entry *dst);
+static void xfrm_init_pmtu(struct xfrm_dst **bundle, int nr);
static int stale_bundle(struct dst_entry *dst);
static int xfrm_bundle_ok(struct xfrm_dst *xdst);
static void xfrm_policy_queue_process(struct timer_list *t);
@@ -1537,7 +1537,9 @@ static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
*/
static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
- struct xfrm_state **xfrm, int nx,
+ struct xfrm_state **xfrm,
+ struct xfrm_dst **bundle,
+ int nx,
const struct flowi *fl,
struct dst_entry *dst)
{
@@ -1572,6 +1574,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
goto put_states;
}
+ bundle[i] = xdst;
if (!xdst_prev)
xdst0 = xdst;
else
@@ -1615,7 +1618,6 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
dst1->input = dst_discard;
dst1->output = inner_mode->afinfo->output;
- dst1->next = &xdst_prev->u.dst;
xdst_prev = xdst;
header_len += xfrm[i]->props.header_len;
@@ -1633,7 +1635,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
goto free_dst;
xfrm_init_path(xdst0, dst, nfheader_len);
- xfrm_init_pmtu(&xdst_prev->u.dst);
+ xfrm_init_pmtu(bundle, nx);
for (xdst_prev = xdst0; xdst_prev != (struct xfrm_dst *)dst;
xdst_prev = (struct xfrm_dst *) xfrm_dst_child(&xdst_prev->u.dst)) {
@@ -1807,6 +1809,7 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
{
struct net *net = xp_net(pols[0]);
struct xfrm_state *xfrm[XFRM_MAX_DEPTH];
+ struct xfrm_dst *bundle[XFRM_MAX_DEPTH];
struct xfrm_dst *xdst, *old;
struct dst_entry *dst;
int err;
@@ -1832,7 +1835,7 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
return ERR_PTR(err);
}
- dst = xfrm_bundle_create(pols[0], xfrm, err, fl, dst_orig);
+ dst = xfrm_bundle_create(pols[0], xfrm, bundle, err, fl, dst_orig);
if (IS_ERR(dst)) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLEGENERROR);
return ERR_CAST(dst);
@@ -2593,12 +2596,14 @@ static struct dst_entry *xfrm_negative_advice(struct dst_entry *dst)
return dst;
}
-static void xfrm_init_pmtu(struct dst_entry *dst)
+static void xfrm_init_pmtu(struct xfrm_dst **bundle, int nr)
{
- do {
- struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
+ while (nr--) {
+ struct xfrm_dst *xdst = bundle[nr];
u32 pmtu, route_mtu_cached;
+ struct dst_entry *dst;
+ dst = &xdst->u.dst;
pmtu = dst_mtu(xfrm_dst_child(dst));
xdst->child_mtu_cached = pmtu;
@@ -2611,7 +2616,7 @@ static void xfrm_init_pmtu(struct dst_entry *dst)
pmtu = route_mtu_cached;
dst_metric_set(dst, RTAX_MTU, pmtu);
- } while ((dst = dst->next));
+ }
}
/* Check that the bundle accepts the flow and its components are
@@ -2620,8 +2625,10 @@ static void xfrm_init_pmtu(struct dst_entry *dst)
static int xfrm_bundle_ok(struct xfrm_dst *first)
{
+ struct xfrm_dst *bundle[XFRM_MAX_DEPTH];
struct dst_entry *dst = &first->u.dst;
- struct xfrm_dst *last;
+ struct xfrm_dst *xdst;
+ int start_from, nr;
u32 mtu;
if (!dst_check(xfrm_dst_path(dst), ((struct xfrm_dst *)dst)->path_cookie) ||
@@ -2631,8 +2638,7 @@ static int xfrm_bundle_ok(struct xfrm_dst *first)
if (dst->flags & DST_XFRM_QUEUE)
return 1;
- last = NULL;
-
+ start_from = nr = 0;
do {
struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
@@ -2644,9 +2650,11 @@ static int xfrm_bundle_ok(struct xfrm_dst *first)
xdst->policy_genid != atomic_read(&xdst->pols[0]->genid))
return 0;
+ bundle[nr++] = xdst;
+
mtu = dst_mtu(xfrm_dst_child(dst));
if (xdst->child_mtu_cached != mtu) {
- last = xdst;
+ start_from = nr;
xdst->child_mtu_cached = mtu;
}
@@ -2654,30 +2662,30 @@ static int xfrm_bundle_ok(struct xfrm_dst *first)
return 0;
mtu = dst_mtu(xdst->route);
if (xdst->route_mtu_cached != mtu) {
- last = xdst;
+ start_from = nr;
xdst->route_mtu_cached = mtu;
}
dst = xfrm_dst_child(dst);
} while (dst->xfrm);
- if (likely(!last))
+ if (likely(!start_from))
return 1;
- mtu = last->child_mtu_cached;
- for (;;) {
- dst = &last->u.dst;
+ xdst = bundle[start_from - 1];
+ mtu = xdst->child_mtu_cached;
+ while (start_from--) {
+ dst = &xdst->u.dst;
mtu = xfrm_state_mtu(dst->xfrm, mtu);
- if (mtu > last->route_mtu_cached)
- mtu = last->route_mtu_cached;
+ if (mtu > xdst->route_mtu_cached)
+ mtu = xdst->route_mtu_cached;
dst_metric_set(dst, RTAX_MTU, mtu);
-
- if (last == first)
+ if (!start_from)
break;
- last = (struct xfrm_dst *)last->u.dst.next;
- last->child_mtu_cached = mtu;
+ xdst = bundle[start_from - 1];
+ xdst->child_mtu_cached = mtu;
}
return 1;
--
2.13.6
^ permalink raw reply related
* [RFC PATCH 12/12] net: Remove dst->next
From: David Miller @ 2017-10-25 14:04 UTC (permalink / raw)
To: netdev
There are no more users.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/dst.h | 4 ----
net/core/dst.c | 1 -
2 files changed, 5 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 403b1c02a26f..ad24d41c0149 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -82,10 +82,6 @@ struct dst_entry {
short error;
short __pad;
__u32 tclassid;
-
- union {
- struct dst_entry *next;
- };
};
struct dst_metrics {
diff --git a/net/core/dst.c b/net/core/dst.c
index 9bc3bb6e94ef..007aa0b08291 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -86,7 +86,6 @@ void dst_init(struct dst_entry *dst, struct dst_ops *ops,
dst->__use = 0;
dst->lastuse = jiffies;
dst->flags = flags;
- dst->next = NULL;
if (!(flags & DST_NOCOUNT))
dst_entries_add(ops, 1);
}
--
2.13.6
^ permalink raw reply related
* Re: [PATCH net] net/sched: cls_flower: Avoid attempt to delete from hw a flow which was not offloaded
From: Or Gerlitz @ 2017-10-25 14:07 UTC (permalink / raw)
To: Jiri Pirko
Cc: David S. Miller, netdev, Jiri Pirko, mlxsw, Roi Dayan,
Paul Blakey
In-Reply-To: <20171025135820.GB1976@nanopsycho.orion>
On 10/25/2017 4:58 PM, Jiri Pirko wrote:
> Wed, Oct 25, 2017 at 03:44:40PM CEST, ogerlitz@mellanox.com wrote:
>> If we failed to offload a flow to HW, we should not be attempting to delete
>> it from the HW. Also, on this case, we should be err-ing only if the flow is
>> not is SW, fix both issues.
>>
>> Fixes: 717503b9cf57 ('net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra')
>> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
>> ---
>> net/sched/cls_flower.c | 11 ++++-------
>> 1 file changed, 4 insertions(+), 7 deletions(-)
>>
>> diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
>> index 16f58ab..b98e0cb 100644
>> --- a/net/sched/cls_flower.c
>> +++ b/net/sched/cls_flower.c
>> @@ -230,15 +230,12 @@ static int fl_hw_replace_filter(struct tcf_proto *tp,
>>
>> err = tc_setup_cb_call(block, &f->exts, TC_SETUP_CLSFLOWER,
>> &cls_flower, skip_sw);
>> - if (err < 0) {
>> - fl_hw_destroy_filter(tp, f);
>> - return err;
>
> As I wrote in the other thread: Yes, that is intentional. The thing is, there might be multiple block callbacks registered and to be called. If there is a fail with one, we need to cleanup all. So in your case you have 1 cb registered, that means that in case of an error during insertion, you will get cb called to remove. Driver has to take care of that. I was checking that and was under impression that mlx5 deals with that.
I see, what about the other line I deleted of blankly returning err no
matter regardless if we' re on skip_sw or not, do you agree this fix is
needed, also see below
>> - } else if (err > 0) {
>> +
>> + if (err > 0)
>> f->flags |= TCA_CLS_FLAGS_IN_HW;
>> - }
>>
>> - if (skip_sw && !(f->flags & TCA_CLS_FLAGS_IN_HW))
>> - return -EINVAL;
>> + if (skip_sw)
>> + return err;
>>
>> return 0;
>> }
here's too, I don't see why we should return -EINVAL etc, and what's
wrong with the code as it wad before your patch, I just returned it to
how it was before which I think is correct
Or.
^ permalink raw reply
* Re: [PATCH net] net/sched: cls_flower: Avoid attempt to delete from hw a flow which was not offloaded
From: Jiri Pirko @ 2017-10-25 14:16 UTC (permalink / raw)
To: Or Gerlitz
Cc: David S. Miller, netdev, Jiri Pirko, mlxsw, Roi Dayan,
Paul Blakey
In-Reply-To: <8e6bb07f-7967-941b-cb67-a9c9af56fc6d@mellanox.com>
Wed, Oct 25, 2017 at 04:07:26PM CEST, ogerlitz@mellanox.com wrote:
>On 10/25/2017 4:58 PM, Jiri Pirko wrote:
>> Wed, Oct 25, 2017 at 03:44:40PM CEST, ogerlitz@mellanox.com wrote:
>> > If we failed to offload a flow to HW, we should not be attempting to delete
>> > it from the HW. Also, on this case, we should be err-ing only if the flow is
>> > not is SW, fix both issues.
>> >
>> > Fixes: 717503b9cf57 ('net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra')
>> > Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
>> > ---
>> > net/sched/cls_flower.c | 11 ++++-------
>> > 1 file changed, 4 insertions(+), 7 deletions(-)
>> >
>> > diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
>> > index 16f58ab..b98e0cb 100644
>> > --- a/net/sched/cls_flower.c
>> > +++ b/net/sched/cls_flower.c
>> > @@ -230,15 +230,12 @@ static int fl_hw_replace_filter(struct tcf_proto *tp,
>> >
>> > err = tc_setup_cb_call(block, &f->exts, TC_SETUP_CLSFLOWER,
>> > &cls_flower, skip_sw);
>> > - if (err < 0) {
>> > - fl_hw_destroy_filter(tp, f);
>> > - return err;
>>
>> As I wrote in the other thread: Yes, that is intentional. The thing is, there might be multiple block callbacks registered and to be called. If there is a fail with one, we need to cleanup all. So in your case you have 1 cb registered, that means that in case of an error during insertion, you will get cb called to remove. Driver has to take care of that. I was checking that and was under impression that mlx5 deals with that.
>
>I see, what about the other line I deleted of blankly returning err no matter
>regardless if we' re on skip_sw or not, do you agree this fix is needed, also
>see below
No. That is not needed. The current behaviour with the skip_sw is the
same as the original. I don't understand why you want to change it. I
also don't undestand why you do 2 things in one patch.
>> > - } else if (err > 0) {
>> > +
>> > + if (err > 0)
>> > f->flags |= TCA_CLS_FLAGS_IN_HW;
>> > - }
>> >
>> > - if (skip_sw && !(f->flags & TCA_CLS_FLAGS_IN_HW))
>> > - return -EINVAL;
>> > + if (skip_sw)
>> > + return err;
>> >
>> > return 0;
>> > }
>
>here's too, I don't see why we should return -EINVAL etc, and what's wrong
>with the code as it wad before your patch, I just returned it to how it was
>before which I think is correct
>
>Or.
^ permalink raw reply
* [net-next 1/1] tipc: eliminate KASAN warning
From: Jon Maloy @ 2017-10-25 14:19 UTC (permalink / raw)
To: davem, netdev; +Cc: parthasarathy.bhuvaragan, ying.xue, tipc-discussion
The following warning was reported by syzbot on Oct 24. 2017:
KASAN: slab-out-of-bounds Read in tipc_nametbl_lookup_dst_nodes
This is a harmless bug, but we still want to get rid of the warning,
so we swap the two conditions in question.
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/name_table.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 2856e19..b3829bc 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -697,7 +697,7 @@ void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower,
spin_lock_bh(&seq->lock);
sseq = seq->sseqs + nameseq_locate_subseq(seq, lower);
stop = seq->sseqs + seq->first_free;
- for (; sseq->lower <= upper && sseq != stop; sseq++) {
+ for (; sseq != stop && sseq->lower <= upper; sseq++) {
info = sseq->info;
list_for_each_entry(publ, &info->zone_list, zone_list) {
if (tipc_in_scope(domain, publ->node))
--
2.1.4
^ permalink raw reply related
* Re: [PATCH 1/1] l2tp: cleanup l2tp_tunnel_delete calls
From: Guillaume Nault @ 2017-10-25 14:27 UTC (permalink / raw)
To: Jiri Slaby; +Cc: davem, linux-kernel, Sabrina Dubroca, netdev
In-Reply-To: <20171025135755.25487-1-jslaby@suse.cz>
On Wed, Oct 25, 2017 at 03:57:55PM +0200, Jiri Slaby wrote:
> l2tp_tunnel_delete does not return anything since commit 62b982eeb458
> ("l2tp: fix race condition in l2tp_tunnel_delete"). But call sites of
> l2tp_tunnel_delete still do casts to void to avoid unused return value
> warnings.
>
> Kill these now useless casts.
>
Acked-by: Guillaume Nault <g.nault@alphalink.fr>
^ permalink raw reply
* Re: [PATCH net] net/sched: cls_flower: Avoid attempt to delete from hw a flow which was not offloaded
From: Or Gerlitz @ 2017-10-25 14:30 UTC (permalink / raw)
To: Jiri Pirko
Cc: Or Gerlitz, David S. Miller, Linux Netdev List, Jiri Pirko, mlxsw,
Roi Dayan, Paul Blakey
In-Reply-To: <20171025141614.GC1976@nanopsycho.orion>
On Wed, Oct 25, 2017 at 5:16 PM, Jiri Pirko <jiri@resnulli.us> wrote:
> Wed, Oct 25, 2017 at 04:07:26PM CEST, ogerlitz@mellanox.com wrote:
>>On 10/25/2017 4:58 PM, Jiri Pirko wrote:
>>> Wed, Oct 25, 2017 at 03:44:40PM CEST, ogerlitz@mellanox.com wrote:
>>> > If we failed to offload a flow to HW, we should not be attempting to delete
>>> > it from the HW. Also, on this case, we should be err-ing only if the flow is
>>> > not is SW, fix both issues.
>>> >
>>> > Fixes: 717503b9cf57 ('net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra')
>>> > Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
>>> > ---
>>> > net/sched/cls_flower.c | 11 ++++-------
>>> > 1 file changed, 4 insertions(+), 7 deletions(-)
>>> >
>>> > diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
>>> > index 16f58ab..b98e0cb 100644
>>> > --- a/net/sched/cls_flower.c
>>> > +++ b/net/sched/cls_flower.c
>>> > @@ -230,15 +230,12 @@ static int fl_hw_replace_filter(struct tcf_proto *tp,
>>> >
>>> > err = tc_setup_cb_call(block, &f->exts, TC_SETUP_CLSFLOWER,
>>> > &cls_flower, skip_sw);
>>> > - if (err < 0) {
>>> > - fl_hw_destroy_filter(tp, f);
>>> > - return err;
>>>
>>> As I wrote in the other thread: Yes, that is intentional. The thing is, there might be multiple block callbacks registered and to be called. If there is a fail with one, we need to cleanup all. So in your case you have 1 cb registered, that means that in case of an error during insertion, you will get cb called to remove. Driver has to take care of that. I was checking that and was under impression that mlx5 deals with that.
>>
>>I see, what about the other line I deleted of blankly returning err no matter
>>regardless if we' re on skip_sw or not, do you agree this fix is needed, also
>>see below
>
> No. That is not needed. The current behaviour with the skip_sw is the
> same as the original. I don't understand why you want to change it. I
> also don't undestand why you do 2 things in one patch.
fair enough, I will send another patch and we'll take it there
^ permalink raw reply
* [patch net-next 0/4] net: sched: block callbacks follow-up
From: Jiri Pirko @ 2017-10-25 14:34 UTC (permalink / raw)
To: netdev
Cc: davem, jhs, xiyou.wangcong, mlxsw, andrew, vivien.didelot,
f.fainelli, michael.chan, ganeshgr, jeffrey.t.kirsher, saeedm,
matanb, leonro, idosch, jakub.kicinski, simon.horman,
pieter.jansenvanvuuren, john.hurley, alexander.h.duyck
From: Jiri Pirko <jiri@mellanox.com>
This patchset does a bit of cleanup of leftovers after block callbacks
patchset. The main part is patch 2, which restores the original handling
of tc offload feature flag.
Jiri Pirko (4):
net: sched: remove unused tc_should_offload helper
net: sched: move the can_offload check from binding phase to rule
insertion phase
net: sched: remove tc_can_offload check from egdev call
net: sched: remove ndo_setup_tc check from tc_can_offload
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +-
drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 3 +++
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 3 +++
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +++
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 3 +++
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 3 +++
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 3 +++
drivers/net/ethernet/netronome/nfp/bpf/main.c | 3 +++
drivers/net/ethernet/netronome/nfp/flower/offload.c | 3 +++
include/net/pkt_cls.h | 13 +------------
net/dsa/slave.c | 3 +++
net/sched/cls_api.c | 4 ++--
12 files changed, 31 insertions(+), 15 deletions(-)
--
2.9.5
^ permalink raw reply
* [patch net-next 1/4] net: sched: remove unused tc_should_offload helper
From: Jiri Pirko @ 2017-10-25 14:34 UTC (permalink / raw)
To: netdev
Cc: davem, jhs, xiyou.wangcong, mlxsw, andrew, vivien.didelot,
f.fainelli, michael.chan, ganeshgr, jeffrey.t.kirsher, saeedm,
matanb, leonro, idosch, jakub.kicinski, simon.horman,
pieter.jansenvanvuuren, john.hurley, alexander.h.duyck
In-Reply-To: <20171025143500.28973-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@mellanox.com>
tc_should_offload is no longer used, remove it.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
include/net/pkt_cls.h | 7 -------
1 file changed, 7 deletions(-)
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 04caa24..0d24d22 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -621,13 +621,6 @@ static inline bool tc_skip_hw(u32 flags)
return (flags & TCA_CLS_FLAGS_SKIP_HW) ? true : false;
}
-static inline bool tc_should_offload(const struct net_device *dev, u32 flags)
-{
- if (tc_skip_hw(flags))
- return false;
- return tc_can_offload(dev);
-}
-
static inline bool tc_skip_sw(u32 flags)
{
return (flags & TCA_CLS_FLAGS_SKIP_SW) ? true : false;
--
2.9.5
^ permalink raw reply related
* [patch net-next 2/4] net: sched: move the can_offload check from binding phase to rule insertion phase
From: Jiri Pirko @ 2017-10-25 14:34 UTC (permalink / raw)
To: netdev
Cc: davem, jhs, xiyou.wangcong, mlxsw, andrew, vivien.didelot,
f.fainelli, michael.chan, ganeshgr, jeffrey.t.kirsher, saeedm,
matanb, leonro, idosch, jakub.kicinski, simon.horman,
pieter.jansenvanvuuren, john.hurley, alexander.h.duyck
In-Reply-To: <20171025143500.28973-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@mellanox.com>
This restores the original behaviour before the block callbacks were
introduced. Allow the drivers to do binding of block always, no matter
if the NETIF_F_HW_TC feature is on or off. Move the check to the block
callback which is called for rule insertion.
Reported-by: Alexander Duyck <alexander.duyck@gmail.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +-
drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 3 +++
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 3 +++
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +++
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 3 +++
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 3 +++
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 3 +++
drivers/net/ethernet/netronome/nfp/bpf/main.c | 3 +++
drivers/net/ethernet/netronome/nfp/flower/offload.c | 3 +++
net/dsa/slave.c | 3 +++
net/sched/cls_api.c | 2 +-
11 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 24d55724..e193232 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -7325,7 +7325,7 @@ static int bnxt_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
{
struct bnxt *bp = cb_priv;
- if (BNXT_VF(bp))
+ if (!tc_can_offload(bp->dev) || BNXT_VF(bp))
return -EOPNOTSUPP;
switch (type) {
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
index 4ae9359..2fa614f 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
@@ -124,6 +124,9 @@ static int bnxt_vf_rep_setup_tc_block_cb(enum tc_setup_type type,
struct bnxt *bp = vf_rep->bp;
int vf_fid = bp->pf.vf[vf_rep->vf_idx].fw_fid;
+ if (!tc_can_offload(bp->dev))
+ return -EOPNOTSUPP;
+
switch (type) {
case TC_SETUP_CLSFLOWER:
return bnxt_tc_setup_flower(bp, vf_fid, type_data);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index e16078d..b07eecf 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -2935,6 +2935,9 @@ static int cxgb_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
return -EINVAL;
}
+ if (!tc_can_offload(dev))
+ return -EOPNOTSUPP;
+
switch (type) {
case TC_SETUP_CLSU32:
return cxgb_setup_tc_cls_u32(dev, type_data);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 7f503d3..3520f28 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -9392,6 +9392,9 @@ static int ixgbe_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
{
struct ixgbe_adapter *adapter = cb_priv;
+ if (!tc_can_offload(adapter->netdev))
+ return -EOPNOTSUPP;
+
switch (type) {
case TC_SETUP_CLSU32:
return ixgbe_setup_tc_cls_u32(adapter, type_data);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 560b208..28ae00b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -3106,6 +3106,9 @@ int mlx5e_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
{
struct mlx5e_priv *priv = cb_priv;
+ if (!tc_can_offload(priv->netdev))
+ return -EOPNOTSUPP;
+
switch (type) {
case TC_SETUP_CLSFLOWER:
return mlx5e_setup_tc_cls_flower(priv, type_data);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 0edb706..2c43606 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -682,6 +682,9 @@ static int mlx5e_rep_setup_tc_cb(enum tc_setup_type type, void *type_data,
{
struct mlx5e_priv *priv = cb_priv;
+ if (!tc_can_offload(priv->netdev))
+ return -EOPNOTSUPP;
+
switch (type) {
case TC_SETUP_CLSFLOWER:
return mlx5e_rep_setup_tc_cls_flower(priv, type_data);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 8f8db6c..71aa603 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -1738,6 +1738,9 @@ static int mlxsw_sp_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
{
struct mlxsw_sp_port *mlxsw_sp_port = cb_priv;
+ if (!tc_can_offload(mlxsw_sp_port->dev))
+ return -EOPNOTSUPP;
+
switch (type) {
case TC_SETUP_CLSMATCHALL:
return mlxsw_sp_setup_tc_cls_matchall(mlxsw_sp_port, type_data,
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c
index fa0ac90..55fca38 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c
@@ -120,6 +120,9 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type,
struct tc_cls_bpf_offload *cls_bpf = type_data;
struct nfp_net *nn = cb_priv;
+ if (!tc_can_offload(nn->dp.netdev))
+ return -EOPNOTSUPP;
+
switch (type) {
case TC_SETUP_CLSBPF:
if (!nfp_net_ebpf_capable(nn) ||
diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c
index c47753f..7c6cab1 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c
@@ -470,6 +470,9 @@ static int nfp_flower_setup_tc_block_cb(enum tc_setup_type type,
{
struct nfp_net *nn = cb_priv;
+ if (!tc_can_offload(nn->dp.netdev))
+ return -EOPNOTSUPP;
+
switch (type) {
case TC_SETUP_CLSFLOWER:
return nfp_flower_repr_offload(nn->app, nn->port->netdev,
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index d0ae701..3481fd6 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -799,6 +799,9 @@ static int dsa_slave_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
{
struct net_device *dev = cb_priv;
+ if (!tc_can_offload(dev))
+ return -EOPNOTSUPP;
+
switch (type) {
case TC_SETUP_CLSMATCHALL:
return dsa_slave_setup_tc_cls_matchall(dev, type_data, ingress);
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 0e96cda..0636c19 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -247,7 +247,7 @@ static void tcf_block_offload_cmd(struct tcf_block *block, struct Qdisc *q,
struct net_device *dev = q->dev_queue->dev;
struct tc_block_offload bo = {};
- if (!tc_can_offload(dev))
+ if (!dev->netdev_ops->ndo_setup_tc)
return;
bo.command = command;
bo.binder_type = ei->binder_type;
--
2.9.5
^ permalink raw reply related
* [patch net-next 3/4] net: sched: remove tc_can_offload check from egdev call
From: Jiri Pirko @ 2017-10-25 14:34 UTC (permalink / raw)
To: netdev
Cc: davem, jhs, xiyou.wangcong, mlxsw, andrew, vivien.didelot,
f.fainelli, michael.chan, ganeshgr, jeffrey.t.kirsher, saeedm,
matanb, leonro, idosch, jakub.kicinski, simon.horman,
pieter.jansenvanvuuren, john.hurley, alexander.h.duyck
In-Reply-To: <20171025143500.28973-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@mellanox.com>
Since the only user, mlx5 driver does the check in
mlx5e_setup_tc_block_cb, no need to check here.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
net/sched/cls_api.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 0636c19..81e1eb3 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -1194,7 +1194,7 @@ static int tc_exts_setup_cb_egdev_call(struct tcf_exts *exts,
if (!a->ops->get_dev)
continue;
dev = a->ops->get_dev(a);
- if (!dev || !tc_can_offload(dev))
+ if (!dev)
continue;
ret = tc_setup_cb_egdev_call(dev, type, type_data, err_stop);
if (ret < 0)
--
2.9.5
^ permalink raw reply related
* [patch net-next 4/4] net: sched: remove ndo_setup_tc check from tc_can_offload
From: Jiri Pirko @ 2017-10-25 14:35 UTC (permalink / raw)
To: netdev
Cc: davem, jhs, xiyou.wangcong, mlxsw, andrew, vivien.didelot,
f.fainelli, michael.chan, ganeshgr, jeffrey.t.kirsher, saeedm,
matanb, leonro, idosch, jakub.kicinski, simon.horman,
pieter.jansenvanvuuren, john.hurley, alexander.h.duyck
In-Reply-To: <20171025143500.28973-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@mellanox.com>
Since tc_can_offload is always called from block callback or egdev
callback, no need to check if ndo_setup_tc exists.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
include/net/pkt_cls.h | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 0d24d22..4631f1a 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -609,11 +609,7 @@ struct tc_cls_u32_offload {
static inline bool tc_can_offload(const struct net_device *dev)
{
- if (!(dev->features & NETIF_F_HW_TC))
- return false;
- if (!dev->netdev_ops->ndo_setup_tc)
- return false;
- return true;
+ return dev->features & NETIF_F_HW_TC;
}
static inline bool tc_skip_hw(u32 flags)
--
2.9.5
^ permalink raw reply related
* [PATCH net] net/sched: cls_flower: Don't err on HW flow add failure unless we're on skip_sw
From: Or Gerlitz @ 2017-10-25 14:38 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Jiri Pirko, mlxsw, Roi Dayan, Paul Blakey, Or Gerlitz
If we failed to offload a flow to HW, we should be err-ing only if skip_sw
is set, otherwise this should go unnoted.
Fixes: 717503b9cf57 ('net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra')
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
net/sched/cls_flower.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 16f58ab..ae2b5c6 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -230,12 +230,10 @@ static int fl_hw_replace_filter(struct tcf_proto *tp,
err = tc_setup_cb_call(block, &f->exts, TC_SETUP_CLSFLOWER,
&cls_flower, skip_sw);
- if (err < 0) {
+ if (err < 0)
fl_hw_destroy_filter(tp, f);
- return err;
- } else if (err > 0) {
+ else if (err > 0)
f->flags |= TCA_CLS_FLAGS_IN_HW;
- }
if (skip_sw && !(f->flags & TCA_CLS_FLAGS_IN_HW))
return -EINVAL;
--
2.5.5
^ permalink raw reply related
* Re: [RFC PATCH 04/12] net: Make generic dst->child usage more explicit.
From: Eric Dumazet @ 2017-10-25 14:55 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20171025.230311.1944266209591105385.davem@davemloft.net>
On Wed, 2017-10-25 at 23:03 +0900, David Miller wrote:
> Only IPSEC (xfrm) routes have a dst->child which is non-NULL.
> xfrm routes are identified by dst->xfrm being non-NULL.
>
> Codify this explicitly in dst_destroy().
>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> ---
> net/core/dst.c | 8 +++++---
> 1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/net/core/dst.c b/net/core/dst.c
> index 662a2d4a3d19..6a3c21b8fc8d 100644
> --- a/net/core/dst.c
> +++ b/net/core/dst.c
> @@ -116,12 +116,14 @@ EXPORT_SYMBOL(dst_alloc);
>
> struct dst_entry *dst_destroy(struct dst_entry * dst)
> {
> - struct dst_entry *child;
> + struct dst_entry *child = NULL;
>
> smp_rmb();
>
> - child = dst->child;
> -
> +#ifdef CONFIG_XFRM
> + if (dst->xfrm)
> + child = dst->child;
> +#endif
> if (!(dst->flags & DST_NOCOUNT))
> dst_entries_add(dst->ops, -1);
>
You might squash this patch with the following one ;)
^ permalink raw reply
* Re: [PATCH net] net/sched: cls_flower: Don't err on HW flow add failure unless we're on skip_sw
From: Jiri Pirko @ 2017-10-25 15:01 UTC (permalink / raw)
To: Or Gerlitz
Cc: David S. Miller, netdev, Jiri Pirko, mlxsw, Roi Dayan,
Paul Blakey
In-Reply-To: <1508942313-544-1-git-send-email-ogerlitz@mellanox.com>
Wed, Oct 25, 2017 at 04:38:33PM CEST, ogerlitz@mellanox.com wrote:
>If we failed to offload a flow to HW, we should be err-ing only if skip_sw
>is set, otherwise this should go unnoted.
First of all, this patch should got to net-next, not net as you
indicate.
>
>Fixes: 717503b9cf57 ('net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra')
>Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
>---
> net/sched/cls_flower.c | 6 ++----
> 1 file changed, 2 insertions(+), 4 deletions(-)
>
>diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
>index 16f58ab..ae2b5c6 100644
>--- a/net/sched/cls_flower.c
>+++ b/net/sched/cls_flower.c
>@@ -230,12 +230,10 @@ static int fl_hw_replace_filter(struct tcf_proto *tp,
>
> err = tc_setup_cb_call(block, &f->exts, TC_SETUP_CLSFLOWER,
> &cls_flower, skip_sw);
>- if (err < 0) {
>+ if (err < 0)
> fl_hw_destroy_filter(tp, f);
>- return err;
I believe it is better to do just:
if (skip_sw)
return err;
The reason is that you would propagate the actual error, not just
"-EINVAL" in all cases.
The same issue is present for matchall, u32 and bpf classifiers. Do you
want to fix it in one go? If not, I can take care of it. Up to you.
Thanks
>- } else if (err > 0) {
>+ else if (err > 0)
> f->flags |= TCA_CLS_FLAGS_IN_HW;
>- }
>
> if (skip_sw && !(f->flags & TCA_CLS_FLAGS_IN_HW))
> return -EINVAL;
>--
>2.5.5
>
^ permalink raw reply
* Re: [iproute PATCH] ss: add detail explains of -m, -o, -e and -i options in ss man page
From: Roman Mashak @ 2017-10-25 15:06 UTC (permalink / raw)
To: peng yu; +Cc: netdev, stephen, phil
In-Reply-To: <CAG3TDc0XxtkA5TU_GDzdZv1ujuqf09e9kBYQm2p5QGbppt7efw@mail.gmail.com>
peng yu <yupeng0921@gmail.com> writes:
> commit 340a45f79395144bd14fdf9be1904c0036456b6e
> Author: yupeng <yupeng0921@gmail.com>
> Date: Tue Oct 24 23:55:29 2017 +0000
>
> add additional explain in ss man page
>
> Add detail explains of -m, -o, -e and -i options, which are not
> documented anywhere
>
> Signed-off-by: Peng Yu <yupeng0921@gmail.com>
>
> diff --git a/man/man8/ss.8 b/man/man8/ss.8
> index 3bec97f..4597733 100644
> --- a/man/man8/ss.8
> +++ b/man/man8/ss.8
> @@ -176,6 +176,147 @@ states except for
> - opposite to
> .B bucket
>
> +.SH Additional explain of -m, -o, -e and -i options
> +Some fields may have different meanings if the netowrk protocl is
> different. Below explain focus on tcp protocol.
> +.TP
> +.B -m option
> +skmem:(r<rmem_alloc>,rb<rcv_buf>,t<wmem_alloc>,tb<snd_buf>,f<fwd_alloc>,w<wmem_queued>,o<opt_mem>,bl<back_log>)
> +
> +.B <rmem_alloc>
> +the memory allocated for receiving package
> +
Need to change 'package' to 'packet' in multiple places.
[...]
^ permalink raw reply
* Re: [patch net-next RFC 1/7] devlink: Add support for resource abstraction
From: David Ahern @ 2017-10-25 15:26 UTC (permalink / raw)
To: Jiri Pirko, netdev, Arkadi Sharshevsky
Cc: davem, mlxsw, andrew, vivien.didelot, f.fainelli, michael.chan,
ganeshgr, saeedm, matanb, leonro, idosch, jakub.kicinski, ast,
daniel, simon.horman, pieter.jansenvanvuuren, john.hurley,
alexander.h.duyck, linville, gospo, steven.lin1, yuvalm, ogerlitz
In-Reply-To: <20171024092245.1386-2-jiri@resnulli.us>
On 10/24/17 3:22 AM, Jiri Pirko wrote:
> diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
> index 0cbca96..9db1d70 100644
> --- a/include/uapi/linux/devlink.h
> +++ b/include/uapi/linux/devlink.h
> @@ -69,6 +69,8 @@ enum devlink_command {
> DEVLINK_CMD_DPIPE_ENTRIES_GET,
> DEVLINK_CMD_DPIPE_HEADERS_GET,
> DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
> + DEVLINK_CMD_RESOURCE_SET,
> + DEVLINK_CMD_RESOURCE_DUMP,
>
> /* add new commands above here */
> __DEVLINK_CMD_MAX,
> @@ -201,6 +203,12 @@ enum devlink_attr {
> DEVLINK_ATTR_PAD,
>
> DEVLINK_ATTR_ESWITCH_ENCAP_MODE, /* u8 */
> + DEVLINK_ATTR_RESOURCES, /* nested */
> + DEVLINK_ATTR_RESOURCE, /* nested */
> + DEVLINK_ATTR_RESOURCE_NAME, /* string */
> + DEVLINK_ATTR_RESOURCE_SIZE, /* u64 */
> + DEVLINK_ATTR_RESOURCE_SIZE_NEW, /* u64 */
> + DEVLINK_ATTR_RESOURCE_ID, /* u64 */
>
> /* add new attributes above here, update the policy in devlink.c */
>
Where can I find the userspace patch to try out the RFC?
^ permalink raw reply
* Re: [patch net-next RFC 7/7] mlxsw: core: Add support for reload
From: David Ahern @ 2017-10-25 15:31 UTC (permalink / raw)
To: Jiri Pirko, netdev, Arkadi Sharshevsky
Cc: davem, mlxsw, andrew, vivien.didelot, f.fainelli, michael.chan,
ganeshgr, saeedm, matanb, leonro, idosch, jakub.kicinski, ast,
daniel, simon.horman, pieter.jansenvanvuuren, john.hurley,
alexander.h.duyck, linville, gospo, steven.lin1, yuvalm, ogerlitz
In-Reply-To: <20171024092245.1386-8-jiri@resnulli.us>
On 10/24/17 3:22 AM, Jiri Pirko wrote:
> @@ -980,7 +998,7 @@ static const struct devlink_ops mlxsw_devlink_ops = {
>
> int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
> const struct mlxsw_bus *mlxsw_bus,
> - void *bus_priv)
> + void *bus_priv, bool reload)
> {
> const char *device_kind = mlxsw_bus_info->device_kind;
> struct mlxsw_core *mlxsw_core;
> @@ -992,11 +1010,14 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
> mlxsw_driver = mlxsw_core_driver_get(device_kind);
> if (!mlxsw_driver)
> return -EINVAL;
> - alloc_size = sizeof(*mlxsw_core) + mlxsw_driver->priv_size;
> - devlink = devlink_alloc(&mlxsw_devlink_ops, alloc_size);
> - if (!devlink) {
> - err = -ENOMEM;
> - goto err_devlink_alloc;
> +
> + if (!reload) {
> + alloc_size = sizeof(*mlxsw_core) + mlxsw_driver->priv_size;
> + devlink = devlink_alloc(&mlxsw_devlink_ops, alloc_size);
> + if (!devlink) {
> + err = -ENOMEM;
> + goto err_devlink_alloc;
> + }
> }
>
> mlxsw_core = devlink_priv(devlink);
devlink is not set if reload is true, yet is used in the line above.
^ permalink raw reply
* RE: [PATCH net-next 2/2] net: dsa: lan9303: Learn addresses on CPU port when bridged
From: Woojung.Huh @ 2017-10-25 15:48 UTC (permalink / raw)
To: privat, andrew, vivien.didelot, f.fainelli, netdev, linux-kernel
In-Reply-To: <b0da2547-69d3-b323-6918-1022e112f7db@egil-hjelmeland.no>
Hi Egil,
> >> @@ -62,7 +80,10 @@ static struct sk_buff *lan9303_xmit(struct sk_buff
> *skb,
> >> struct net_device *dev)
> >>
> >> lan9303_tag = (u16 *)(skb->data + 2 * ETH_ALEN);
> >> lan9303_tag[0] = htons(ETH_P_8021Q);
> >> - lan9303_tag[1] = htons(dp->index | BIT(4));
> >> + lan9303_tag[1] = lan9303_tx_use_arl(dp, skb->data) ?
> >
> > How about using skb_mac_header(skb) than skb->data?
> >
> >> + LAN9303_TAG_TX_USE_ALR :
> >> + dp->index |
> >
>
> I am not the expert here.
>
> I see that skb_mac_header() is (skb->head + skb->mac_header). So it will
> cost a few nano seconds per packet. Not the end of the world though.
> But I see that other net/dsa/tag_*.c use skb->data, assuming that
> skb->data point to mac header.
>
Revisited skb_mac_header(). It is basically skb->data after math.
Understand that it would be extra steps than referring skb->data directly.
Unless no one comments on this, please keep first patch.
Thanks.
Woojung
^ permalink raw reply
* Re: [RFC PATCH 05/12] net: Create and use new helper xfrm_dst_child().
From: Shannon Nelson @ 2017-10-25 15:56 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20171025.230325.1201318483362616226.davem@davemloft.net>
On Wed, Oct 25, 2017 at 7:03 AM, David Miller <davem@davemloft.net> wrote:
>
>
> diff --git a/include/net/xfrm.h b/include/net/xfrm.h
> index f002a2c5e33c..4fa951112873 100644
> --- a/include/net/xfrm.h
> +++ b/include/net/xfrm.h
> @@ -994,6 +994,15 @@ struct xfrm_dst {
> };
>
> #ifdef CONFIG_XFRM
Perhaps the new xfrm_dst_child() code needs to go before this #ifdef?
sln
>
> +static inline struct dst_entry *xfrm_dst_child(const struct dst_entry *dst)
> +{
> +#ifdef CONFIG_XFRM
> + if (dst->xfrm)
> + return dst->child;
> +#endif
> + return NULL;
> +}
> +
--
==============================================
Mr. Shannon Nelson Parents can't afford to be squeamish.
^ 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