* Re: [PATCH net-next 1/2] net: Header length compution function
From: David Miller @ 2014-08-23 19:19 UTC (permalink / raw)
To: alexander.h.duyck; +Cc: eric.dumazet, amirv, netdev, ogerlitz, yevgenyp, idos
In-Reply-To: <53DA61FE.40406@intel.com>
From: Alexander Duyck <alexander.h.duyck@intel.com>
Date: Thu, 31 Jul 2014 08:34:22 -0700
> On 07/30/2014 06:39 PM, David Miller wrote:
>> I don't think my proposed patch is a bad trade off. Where we have the
>> __skb_header_pointer() thing that takes preloaded pointers and header
>> length values. It adds only one test which frankly should never
>> trigger and can be moved down into skb_copy_bits() or similar.
>
> This works for me. Once it is in I can see about pushing a patch to add
> some FCoE support and work on moving over igb and ixgbe.
You should be able to do this against net-next now, just FYI.
^ permalink raw reply
* [PATCH] net: Allow raw buffers to be passed into the flow dissector.
From: David Miller @ 2014-08-23 19:18 UTC (permalink / raw)
To: amirv; +Cc: alexander.h.duyck, netdev, ogerlitz, yevgenyp, idos, eric.dumazet
Drivers, and perhaps other entities we have not yet considered,
sometimes want to know how deep the protocol headers go before
deciding how large of an SKB to allocate and how much of the packet to
place into the linear SKB area.
For example, consider a driver which has a device which DMAs into
pools of pages and then tells the driver where the data went in the
DMA descriptor(s). The driver can then build an SKB and reference
most of the data via SKB fragments (which are page/offset/length
triplets).
However at least some of the front of the packet should be placed into
the linear SKB area, which comes before the fragments, so that packet
processing can get at the headers efficiently. The first thing each
protocol layer is going to do is a "pskb_may_pull()" so we might as
well aggregate as much of this as possible while we're building the
SKB in the driver.
Part of supporting this is that we don't have an SKB yet, so we want
to be able to let the flow dissector operate on a raw buffer in order
to compute the offset of the end of the headers.
So now we have a __skb_flow_dissect() which takes an explicit data
pointer and length.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
I'll commit this to net-next.
Amir, please re-spin your changes on top of this. Thanks!
include/linux/skbuff.h | 18 ++++++++++++------
include/net/flow_keys.h | 14 ++++++++++++--
net/core/flow_dissector.c | 40 ++++++++++++++++++++++++++--------------
3 files changed, 50 insertions(+), 22 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index abde271..18ddf96 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2567,20 +2567,26 @@ __wsum __skb_checksum(const struct sk_buff *skb, int offset, int len,
__wsum skb_checksum(const struct sk_buff *skb, int offset, int len,
__wsum csum);
-static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
- int len, void *buffer)
+static inline void *__skb_header_pointer(const struct sk_buff *skb, int offset,
+ int len, void *data, int hlen, void *buffer)
{
- int hlen = skb_headlen(skb);
-
if (hlen - offset >= len)
- return skb->data + offset;
+ return data + offset;
- if (skb_copy_bits(skb, offset, buffer, len) < 0)
+ if (!skb ||
+ skb_copy_bits(skb, offset, buffer, len) < 0)
return NULL;
return buffer;
}
+static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
+ int len, void *buffer)
+{
+ return __skb_header_pointer(skb, offset, len, skb->data,
+ skb_headlen(skb), buffer);
+}
+
/**
* skb_needs_linearize - check if we need to linearize a given skb
* depending on the given device features.
diff --git a/include/net/flow_keys.h b/include/net/flow_keys.h
index 6667a05..4040f63 100644
--- a/include/net/flow_keys.h
+++ b/include/net/flow_keys.h
@@ -27,7 +27,17 @@ struct flow_keys {
u8 ip_proto;
};
-bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow);
-__be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto);
+bool __skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow,
+ void *data, int hlen);
+static inline bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow)
+{
+ return __skb_flow_dissect(skb, flow, NULL, 0);
+}
+__be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,
+ void *data, int hlen_proto);
+static inline __be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto)
+{
+ return __skb_flow_get_ports(skb, thoff, ip_proto, NULL, 0);
+}
u32 flow_hash_from_keys(struct flow_keys *keys);
#endif
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 5f362c1..660c649 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -34,29 +34,40 @@ static void iph_to_flow_copy_addrs(struct flow_keys *flow, const struct iphdr *i
* The function will try to retrieve the ports at offset thoff + poff where poff
* is the protocol port offset returned from proto_ports_offset
*/
-__be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto)
+__be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,
+ void *data, int hlen)
{
int poff = proto_ports_offset(ip_proto);
+ if (!data) {
+ data = skb->data;
+ hlen = skb_headlen(skb);
+ }
+
if (poff >= 0) {
__be32 *ports, _ports;
- ports = skb_header_pointer(skb, thoff + poff,
- sizeof(_ports), &_ports);
+ ports = __skb_header_pointer(skb, thoff + poff,
+ sizeof(_ports), data, hlen, &_ports);
if (ports)
return *ports;
}
return 0;
}
-EXPORT_SYMBOL(skb_flow_get_ports);
+EXPORT_SYMBOL(__skb_flow_get_ports);
-bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow)
+bool __skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow, void *data, int hlen)
{
int nhoff = skb_network_offset(skb);
u8 ip_proto;
__be16 proto = skb->protocol;
+ if (!data) {
+ data = skb->data;
+ hlen = skb_headlen(skb);
+ }
+
memset(flow, 0, sizeof(*flow));
again:
@@ -65,7 +76,7 @@ again:
const struct iphdr *iph;
struct iphdr _iph;
ip:
- iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
+ iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
if (!iph || iph->ihl < 5)
return false;
nhoff += iph->ihl * 4;
@@ -83,7 +94,7 @@ ip:
__be32 flow_label;
ipv6:
- iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
+ iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
if (!iph)
return false;
@@ -113,7 +124,7 @@ ipv6:
const struct vlan_hdr *vlan;
struct vlan_hdr _vlan;
- vlan = skb_header_pointer(skb, nhoff, sizeof(_vlan), &_vlan);
+ vlan = __skb_header_pointer(skb, nhoff, sizeof(_vlan), data, hlen, &_vlan);
if (!vlan)
return false;
@@ -126,7 +137,7 @@ ipv6:
struct pppoe_hdr hdr;
__be16 proto;
} *hdr, _hdr;
- hdr = skb_header_pointer(skb, nhoff, sizeof(_hdr), &_hdr);
+ hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
if (!hdr)
return false;
proto = hdr->proto;
@@ -151,7 +162,7 @@ ipv6:
__be16 proto;
} *hdr, _hdr;
- hdr = skb_header_pointer(skb, nhoff, sizeof(_hdr), &_hdr);
+ hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
if (!hdr)
return false;
/*
@@ -171,8 +182,9 @@ ipv6:
const struct ethhdr *eth;
struct ethhdr _eth;
- eth = skb_header_pointer(skb, nhoff,
- sizeof(_eth), &_eth);
+ eth = __skb_header_pointer(skb, nhoff,
+ sizeof(_eth),
+ data, hlen, &_eth);
if (!eth)
return false;
proto = eth->h_proto;
@@ -194,12 +206,12 @@ ipv6:
flow->n_proto = proto;
flow->ip_proto = ip_proto;
- flow->ports = skb_flow_get_ports(skb, nhoff, ip_proto);
+ flow->ports = __skb_flow_get_ports(skb, nhoff, ip_proto, data, hlen);
flow->thoff = (u16) nhoff;
return true;
}
-EXPORT_SYMBOL(skb_flow_dissect);
+EXPORT_SYMBOL(__skb_flow_dissect);
static u32 hashrnd __read_mostly;
static __always_inline void __flow_hash_secret_init(void)
--
1.7.11.7
^ permalink raw reply related
* [PATCH net-next] net: use reciprocal_scale() helper
From: Daniel Borkmann @ 2014-08-23 18:58 UTC (permalink / raw)
To: davem; +Cc: netdev, netfilter-devel, Hannes Frederic Sowa
Replace open codings of (((u64) <x> * <y>) >> 32) with reciprocal_scale().
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
net/core/dev.c | 3 +--
net/core/flow_dissector.c | 7 +++----
net/ipv4/inet_hashtables.c | 2 +-
net/ipv4/netfilter/ipt_CLUSTERIP.c | 2 +-
net/ipv4/udp.c | 6 +++---
net/ipv6/inet6_hashtables.c | 2 +-
net/ipv6/udp.c | 4 ++--
net/netfilter/nf_conntrack_core.c | 2 +-
net/netfilter/nf_conntrack_expect.c | 3 ++-
net/netfilter/nf_nat_core.c | 5 +++--
net/netfilter/xt_HMARK.c | 2 +-
net/netfilter/xt_cluster.c | 3 ++-
net/netfilter/xt_hashlimit.c | 2 +-
net/sched/sch_fq_codel.c | 3 ++-
14 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index b65a505..1421dad 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3124,8 +3124,7 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
}
if (map) {
- tcpu = map->cpus[((u64) hash * map->len) >> 32];
-
+ tcpu = map->cpus[reciprocal_scale(hash, map->len)];
if (cpu_online(tcpu)) {
cpu = tcpu;
goto done;
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 5f362c1..624869c 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -286,7 +286,7 @@ u16 __skb_tx_hash(const struct net_device *dev, struct sk_buff *skb,
qcount = dev->tc_to_txq[tc].count;
}
- return (u16) (((u64)skb_get_hash(skb) * qcount) >> 32) + qoffset;
+ return (u16) reciprocal_scale(skb_get_hash(skb), qcount) + qoffset;
}
EXPORT_SYMBOL(__skb_tx_hash);
@@ -359,9 +359,8 @@ static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb)
if (map->len == 1)
queue_index = map->queues[0];
else
- queue_index = map->queues[
- ((u64)skb_get_hash(skb) * map->len) >> 32];
-
+ queue_index = map->queues[reciprocal_scale(skb_get_hash(skb),
+ map->len)];
if (unlikely(queue_index >= dev->real_num_tx_queues))
queue_index = -1;
}
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 43116e8..9111a4e 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -229,7 +229,7 @@ begin:
}
} else if (score == hiscore && reuseport) {
matches++;
- if (((u64)phash * matches) >> 32 == 0)
+ if (reciprocal_scale(phash, matches) == 0)
result = sk;
phash = next_pseudo_random32(phash);
}
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 2510c02..e90f83a 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -285,7 +285,7 @@ clusterip_hashfn(const struct sk_buff *skb,
}
/* node numbers are 1..n, not 0..n */
- return (((u64)hashval * config->num_total_nodes) >> 32) + 1;
+ return reciprocal_scale(hashval, config->num_total_nodes) + 1;
}
static inline int
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index f57c0e4..32f9571 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -224,7 +224,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
remaining = (high - low) + 1;
rand = prandom_u32();
- first = (((u64)rand * remaining) >> 32) + low;
+ first = reciprocal_scale(rand, remaining) + low;
/*
* force rand to be an odd multiple of UDP_HTABLE_SIZE
*/
@@ -448,7 +448,7 @@ begin:
}
} else if (score == badness && reuseport) {
matches++;
- if (((u64)hash * matches) >> 32 == 0)
+ if (reciprocal_scale(hash, matches) == 0)
result = sk;
hash = next_pseudo_random32(hash);
}
@@ -529,7 +529,7 @@ begin:
}
} else if (score == badness && reuseport) {
matches++;
- if (((u64)hash * matches) >> 32 == 0)
+ if (reciprocal_scale(hash, matches) == 0)
result = sk;
hash = next_pseudo_random32(hash);
}
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 262e13c..8260190 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -198,7 +198,7 @@ begin:
}
} else if (score == hiscore && reuseport) {
matches++;
- if (((u64)phash * matches) >> 32 == 0)
+ if (reciprocal_scale(phash, matches) == 0)
result = sk;
phash = next_pseudo_random32(phash);
}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 4836af8..25ffe73 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -243,7 +243,7 @@ begin:
goto exact_match;
} else if (score == badness && reuseport) {
matches++;
- if (((u64)hash * matches) >> 32 == 0)
+ if (reciprocal_scale(hash, matches) == 0)
result = sk;
hash = next_pseudo_random32(hash);
}
@@ -323,7 +323,7 @@ begin:
}
} else if (score == badness && reuseport) {
matches++;
- if (((u64)hash * matches) >> 32 == 0)
+ if (reciprocal_scale(hash, matches) == 0)
result = sk;
hash = next_pseudo_random32(hash);
}
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index de88c4a..b7daee0 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -142,7 +142,7 @@ static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple, u16 zone)
static u32 __hash_bucket(u32 hash, unsigned int size)
{
- return ((u64)hash * size) >> 32;
+ return reciprocal_scale(hash, size);
}
static u32 hash_bucket(u32 hash, const struct net *net)
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index f87e8f6..91a1837 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -83,7 +83,8 @@ static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple
hash = jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all),
(((tuple->dst.protonum ^ tuple->src.l3num) << 16) |
(__force __u16)tuple->dst.u.all) ^ nf_conntrack_hash_rnd);
- return ((u64)hash * nf_ct_expect_hsize) >> 32;
+
+ return reciprocal_scale(hash, nf_ct_expect_hsize);
}
struct nf_conntrack_expect *
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 552f97c..4e0b478 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -126,7 +126,8 @@ hash_by_src(const struct net *net, u16 zone,
/* Original src, to ensure we map it consistently if poss. */
hash = jhash2((u32 *)&tuple->src, sizeof(tuple->src) / sizeof(u32),
tuple->dst.protonum ^ zone ^ nf_conntrack_hash_rnd);
- return ((u64)hash * net->ct.nat_htable_size) >> 32;
+
+ return reciprocal_scale(hash, net->ct.nat_htable_size);
}
/* Is this tuple already taken? (not by us) */
@@ -274,7 +275,7 @@ find_best_ips_proto(u16 zone, struct nf_conntrack_tuple *tuple,
}
var_ipp->all[i] = (__force __u32)
- htonl(minip + (((u64)j * dist) >> 32));
+ htonl(minip + reciprocal_scale(j, dist));
if (var_ipp->all[i] != range->max_addr.all[i])
full_range = true;
diff --git a/net/netfilter/xt_HMARK.c b/net/netfilter/xt_HMARK.c
index 73b73f6..02afaf4 100644
--- a/net/netfilter/xt_HMARK.c
+++ b/net/netfilter/xt_HMARK.c
@@ -126,7 +126,7 @@ hmark_hash(struct hmark_tuple *t, const struct xt_hmark_info *info)
hash = jhash_3words(src, dst, t->uports.v32, info->hashrnd);
hash = hash ^ (t->proto & info->proto_mask);
- return (((u64)hash * info->hmodulus) >> 32) + info->hoffset;
+ return reciprocal_scale(hash, info->hmodulus) + info->hoffset;
}
static void
diff --git a/net/netfilter/xt_cluster.c b/net/netfilter/xt_cluster.c
index f4af1bf..96fa26b 100644
--- a/net/netfilter/xt_cluster.c
+++ b/net/netfilter/xt_cluster.c
@@ -55,7 +55,8 @@ xt_cluster_hash(const struct nf_conn *ct,
WARN_ON(1);
break;
}
- return (((u64)hash * info->total_nodes) >> 32);
+
+ return reciprocal_scale(hash, info->total_nodes);
}
static inline bool
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 47dc683..52eb3e0 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -135,7 +135,7 @@ hash_dst(const struct xt_hashlimit_htable *ht, const struct dsthash_dst *dst)
* give results between [0 and cfg.size-1] and same hash distribution,
* but using a multiply, less expensive than a divide
*/
- return ((u64)hash * ht->cfg.size) >> 32;
+ return reciprocal_scale(hash, ht->cfg.size);
}
static struct dsthash_ent *
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
index 063b726..cc56c8b 100644
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -77,7 +77,8 @@ static unsigned int fq_codel_hash(const struct fq_codel_sched_data *q,
hash = jhash_3words((__force u32)keys.dst,
(__force u32)keys.src ^ keys.ip_proto,
(__force u32)keys.ports, q->perturbation);
- return ((u64)hash * q->flows_cnt) >> 32;
+
+ return reciprocal_scale(hash, q->flows_cnt);
}
static unsigned int fq_codel_classify(struct sk_buff *skb, struct Qdisc *sch,
--
1.9.3
^ permalink raw reply related
* Re: [PATCH 5/8] i40e: Fix TSO and hw checksums for non-accelerated vlan packets.
From: David Miller @ 2014-08-23 18:43 UTC (permalink / raw)
To: vyasevich
Cc: netdev, vyasevic, jeffrey.t.kirsher, jesse.brandeburg,
bruce.w.allan, carolyn.wyborny, donald.c.skidmore, gregory.v.rose,
alexander.h.duyck, john.ronciak, mitch.a.williams, linux.nics,
e1000-devel
In-Reply-To: <1408760230-7457-6-git-send-email-vysevich@gmail.com>
From: vyasevich@gmail.com
Date: Fri, 22 Aug 2014 22:17:07 -0400
> @@ -2295,7 +2295,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
> goto out_drop;
>
> /* obtain protocol of skb */
> - protocol = skb->protocol;
> + protocol = get_vlan_protocol(skb);
I don't think this even compiles.
It's "vlan_get_protocol" not "get_vlan_protocol".
^ permalink raw reply
* Re: [PATCH net-next 0/7] net: phy: bcm7xxx: APD and EEE support
From: David Miller @ 2014-08-23 18:39 UTC (permalink / raw)
To: f.fainelli; +Cc: netdev
In-Reply-To: <1408758945-18908-1-git-send-email-f.fainelli@gmail.com>
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Fri, 22 Aug 2014 18:55:38 -0700
> This patch series enables Auto-power down and EEE for the BCM7xxx integrated
> Gigabit PHYs.
>
> I also put a fix for the fixed PHY that would allow clause 45 over clause 22
> reads/writes but would return bogus data by using e.g: ethtool --show-eee
Nice clean work as always, applied, thanks Florian.
^ permalink raw reply
* Re: [PATCH net-next 00/17] tipc: Merge port and socket layer code
From: David Miller @ 2014-08-23 18:19 UTC (permalink / raw)
To: jon.maloy
Cc: netdev, paul.gortmaker, erik.hugne, ying.xue, maloy,
tipc-discussion
In-Reply-To: <1408745360-23560-1-git-send-email-jon.maloy@ericsson.com>
From: Jon Maloy <jon.maloy@ericsson.com>
Date: Fri, 22 Aug 2014 18:09:03 -0400
> After the removal of the TIPC native interface, there is no reason to
> keep a distinction between a "generic" port layer and a "specific"
> socket layer in the code. Throughout the last months, we have posted
> several series that aimed at facilitating removal of the port layer,
> and in particular the port_lock spinlock, which in reality duplicates
> the role normally kept by lock_sock()/bh_lock_sock().
>
> In this series, we finalize this work, by making a significant number of
> changes to the link, node, port and socket code, all with the aim of
> reducing dependencies between the layers. In the final commits, we then
> remove the port spinlock, port.c and port.h altogether.
>
> After this series, we have a socket layer that has only few dependencies
> to the rest of the stack, so that it should be possible to continue
> cleanups of its code without significantly affecting other code.
Series applied, thanks Jon.
> It should be noted that commit ##1 and 2 are already in 'net'
> (ac32c7f705692b92fe12dcbe88fe87136fdfff6f and
> 02784f1b05b8f241c8180af88869e717e2758593), but not yet in net-next.
> Since they are prerequisites for the rest of the series to apply, I
> prepend them to the series.
I decided to handle this by merging 'net' into 'net-next' and then
just skipping those first two patches in the series. Thanks for
letting me know about this dependency.
^ permalink raw reply
* Re: [patch net-next RFC 10/12] openvswitch: add support for datapath hardware offload
From: John Fastabend @ 2014-08-23 17:09 UTC (permalink / raw)
To: Thomas Graf
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w, ronye-VPRAkNaXOzVWk0Htik3J/w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw, Jiri Pirko,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
netdev-u79uwXL29TY76Z2rM5mHXA,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <20140823145126.GB24116-FZi0V3Vbi30CUdFEqe4BF2D2FQJk+8+b@public.gmane.org>
On 08/23/2014 07:51 AM, Thomas Graf wrote:
> On 08/23/14 at 11:24am, Jiri Pirko wrote:
>> Sat, Aug 23, 2014 at 12:53:34AM CEST, sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR@public.gmane.org wrote:
>>>
>>> On Aug 22, 2014, at 12:39 PM, John Fastabend <john.fastabend-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>>>> - this requires OVS to be loaded to work. If all I want is
>>>> direct access to the hardware flow tables requiring openvswitch.ko
>>>> shouldn't be needed IMO. For example I may want to use the
>>>> hardware flow tables with something not openvswitch and we
>>>> shouldn't preclude that.
>>>>
>>>
>>> The intent is to use openvswitch.ko’s struct sw_flow to program hardware via the ndo_swdev_flow_* ops, but otherwise be independent of OVS. So the upper layer of the driver is struct sw_flow and any module above the driver can construct a struct sw_flow and push it down via ndo_swdev_flow_*. So your non-OVS use-case should be handled. OVS is another use-case. struct sw_flow should not be OVS-aware, but rather a generic flow match/action sufficient to offload the data plane to HW.
>>
>> Yes. I was thinking about simple Netlink API that would expose direct
>> sw_flow manipulation (ndo_swdev_flow_* wrapper) to userspace. I will
>> think abou that more and perhaps add it to my next patchset version.
>
> I agree that this might help to give a better API consumption example
> for everyone not familiar with OVS.
Yep and it solves one of my simple cases where I have macvlan configured
with SR-IOV or the l2-dfwd-offload bit set and want to push some basic
static ACLs into the flow table. If you have to bring the port into the
OVS framework I'm not sure how make this coexist.
>
>>>> - Also there is no programmatic way to learn which flows are
>>>> in hardware and which in software. There is a pr_warn but
>>>> that doesn't help when interacting with the hardware remotely.
>>>> I need some mechanism to dump the set of hardware tables and
>>>> the set of software tables.
>>>
>>> Agreed, we need a way to annotate which flows are installed hardware.
>>
>> Yes, we discussed that already. We need to make OVS daemon hw-offload
>> aware indicating which flow it want/prefers to be offloaded. This is I
>> believe easily extentable feature and can be added whenever the right
>> time is.
>
> I think the swdev flow API is good as-is. The bitmask specyfing the
> offload preference with all the granularity (offload-or-fail,
> try-to-offload, never-offload) needed can be added later, either in
> OVS only or in swdev itself.
>
> What is unclear in this patch is how OVS user space can know which
> flows are offloaded and which aren't. A status field would help here
> which indicates either: flow inserted and offloaded, flow inserted but
> not offloaded. Given that, the API consumer can easily keep track of
> which flows are currently offloaded.
>
Right. I think this is basically what Jiri and I discussed when he
originally posted the series. For my use cases this is one of the
more interesting pieces. If no one else is looking at it I can try
it on some of the already existing open source drivers that have some
very simple support for ingress flow tables read flow director.
> Also, I'm not sure whether flow expiration is something the API must
> take care of. The current proposal assumes that HW flows are only
> ever removed by the API itself. Could the switch CPU run code which
> removes flows as well? That would call for Netlink notifications.
> Not that it's needed at this stage of the code but maybe worth
> considerating for the API design.
I think this will be very useful when we get to a point where we
can use this on some of the switch silicon that supports bigger tables
with more capabilities. Like you say we probably don't need it in
the first draft but having a path to support it is needed.
>
>>>> - Simply duplicating the software flow/action into
>>>> hardware may not optimally use the hardware tables. If I have
>>>> a TCAM in hardware for instance. (This is how I read the patch
>>>> let me know if I missed something)
>>>
>>> The hardware-specific driver is the right place to handle optimizing the flow/action in hardware since only the driver can know the size/shape of the device. struct sw_flow is a generic flow description; how (or if) a flow gets programmed into hardware must be handled in the swdev driver. If the device driver can’t make the sw_flow fit into HW because of resource limitations or the flow simply can’t be represented in HW, then the flow is SW only.
>>>
>>> In the rocker driver posted in this patch set, the steps are to parse the struct sw_flow to figure out what type of flow match/action we’re dealing with (L2 or L3 or L4, ucast or mcast, ipv4 or ipv6, etc) and then install the correct entries into the corresponding device tables within the constraints of the device’s pipeline. Any optimizations, like coalescing HW entries, is something only the driver can do.
>
> The later examples definitely make sense and I'm not argueing against
> that. There is also a non hardware capabilities perspective that I
> would like to present:
>
> 1) TCAM capacity is limtied, we offload based on some priority assigned
> to flows. Some are critical and need to be in HW, others are best effort,
> others never go into hardware. An API user will likely want to offload
> best-effort flows until some watermark is reached and then switch to
> critical flows only. The driver is not the right place for high level
> optimization like this. The kernel API might but doesn't really have to
> either because it would mean we need APIs to transfer all of the
> needed context for the decision in the kernel. It might be easier to
> expose the hardware context to user space instead and handle these
> kind of optimizations in something like Quagga.
>
> 2) There is definitely a desire to allow adapting the software flow table
> based on the hardware capabilities. Example, given a route like this:
>
> 20.1.0.0/16, mark=50, tos=0x12, actions: output:eth1
>
> The hardware can satisfy everything except the mark=50 match. Given a
> a blind 1:1 copy between hardware and software we cannot offload
> because a mach would be illegal. With the full context as available
> north of the API, this could be translated into something like this:
>
> HW: 20.1.0.0/16, tos=0x12, actions: meta=1, output:cpu
> SW: meta=1, mark=50, output:eth1
>
> This will allow for partial offloads to bypass expensive masked flow
> table lookups by converting them into efficient flat exact match
> tables, offload TC classifiers, nftables or even the existing L2 and
> L3 forwarding path.
Thanks. This is exactly what I was trying to hint at and why the
optimization can not be done in the driver. The driver shouldn't
have to know about the cost models of SW vs HW rules or how to
break up rules into sets of complimentary hw/sw rules.
the other thing I've been thinking about is how to handle hardware
with multiple flow tables. We could let the driver handle this
but if I ever want to employ a new optimization strategy then I
need to rewrite the driver. To me this looks a lot like policy
which should not be driven by the kernel. We can probably ignore
this case for the moment until we get some of the other things
addressed.
>
> In summary, I think the swdev API as proposed is a good start as the
> in-kernel flow abstraction is sufficient for many API users but we
> should consider enabling the model described above as well once we
> have the basic model put in place. I will be very interested in helping
> out on this for both existing classifiers and OVS flow tables.
>
>
>>>> - I need a way to specify put this flow/action in hardware,
>>>> put this flow/action in software, or put this in both software
>>>> and hardware.
>>>>
>>>
>>> This seems above the swdev layer. In other words, don’t call ndo_swdev_flow_* if you don’t want flow match/action install in HW.
>
> It can certainly be done northbound but this seems like a basic
> requirement and we might end up avoiding the code duplication and
> extending the API instead.
>
IMO I think extending the API is the easiest route but the best
way to resolve this is to try and write the code. I'll take a
stab at it next week.
by the way Jiri I think the patches are a great start.
Thanks,
John
--
John Fastabend Intel Corporation
^ permalink raw reply
* [PATCH iproute2] ll_types: add netlink ARPHRD
From: Daniel Borkmann @ 2014-08-23 15:13 UTC (permalink / raw)
To: stephen; +Cc: netdev
This adds ARPHRD_NETLINK to ll_types so that it can be properly
shown e.g. in `ip a`:
8: nlmon: <NOARP,UP,LOWER_UP> mtu 3776 qdisc noqueue state UNKNOWN group default
link/netlink
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
lib/ll_types.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/ll_types.c b/lib/ll_types.c
index 0c39183..2c5bf8b 100644
--- a/lib/ll_types.c
+++ b/lib/ll_types.c
@@ -104,6 +104,7 @@ __PF(PHONET, phonet)
__PF(PHONET_PIPE, phonet_pipe)
__PF(CAIF, caif)
__PF(IP6GRE, gre6)
+__PF(NETLINK, netlink)
__PF(NONE, none)
__PF(VOID,void)
--
1.7.11.7
^ permalink raw reply related
* [PATCH net-next] random32: improvements to prandom_bytes
From: Daniel Borkmann @ 2014-08-23 15:03 UTC (permalink / raw)
To: davem; +Cc: akinobu.mita, LW, netdev, Hannes Frederic Sowa
This patch addresses a couple of minor items, mostly addesssing
prandom_bytes(): 1) prandom_bytes{,_state}() should use size_t
for length arguments, 2) We can use put_unaligned() when filling
the array instead of open coding it [ perhaps some archs will
further benefit from their own arch specific implementation when
GCC cannot make up for it ], 3) Fix a typo, 4) Better use unsigned
int as type for getting the arch seed, 5) Make use of
prandom_u32_max() for timer slack.
Regarding the change to put_unaligned(), callers of prandom_bytes()
which internally invoke prandom_bytes_state(), don't bother as
they expect the array to be filled randomly and don't have any
control of the internal state what-so-ever (that's also why we
have periodic reseeding there, etc), so they really don't care.
Now for the direct callers of prandom_bytes_state(), which
are solely located in test cases for MTD devices, that is,
drivers/mtd/tests/{oobtest.c,pagetest.c,subpagetest.c}:
These tests basically fill a test write-vector through
prandom_bytes_state() with an a-priori defined seed each time
and write that to a MTD device. Later on, they set up a read-vector
and read back that blocks from the device. So in the verification
phase, the write-vector is being re-setup [ so same seed and
prandom_bytes_state() called ], and then memcmp()'ed against the
read-vector to check if the data is the same.
Akinobu, Lothar and I also tested this patch and it runs through
the 3 relevant MTD test cases w/o any errors on the nandsim device
(simulator for MTD devs) for x86_64, ppc64, ARM (i.MX28, i.MX53
and i.MX6):
# modprobe nandsim first_id_byte=0x20 second_id_byte=0xac \
third_id_byte=0x00 fourth_id_byte=0x15
# modprobe mtd_oobtest dev=0
# modprobe mtd_pagetest dev=0
# modprobe mtd_subpagetest dev=0
We also don't have any users depending directly on a particular
result of the PRNG (except the PRNG self-test itself), and that's
just fine as it e.g. allowed us easily to do things like upgrading
from taus88 to taus113.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Tested-by: Akinobu Mita <akinobu.mita@gmail.com>
Tested-by: Lothar Waßmann <LW@KARO-electronics.de>
Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
v1->v2:
- resending as per: http://patchwork.ozlabs.org/patch/375418/
- rebased, retested
include/linux/random.h | 4 ++--
lib/random32.c | 39 ++++++++++++++++++---------------------
2 files changed, 20 insertions(+), 23 deletions(-)
diff --git a/include/linux/random.h b/include/linux/random.h
index 57fbbff..b05856e 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -26,7 +26,7 @@ unsigned int get_random_int(void);
unsigned long randomize_range(unsigned long start, unsigned long end, unsigned long len);
u32 prandom_u32(void);
-void prandom_bytes(void *buf, int nbytes);
+void prandom_bytes(void *buf, size_t nbytes);
void prandom_seed(u32 seed);
void prandom_reseed_late(void);
@@ -35,7 +35,7 @@ struct rnd_state {
};
u32 prandom_u32_state(struct rnd_state *state);
-void prandom_bytes_state(struct rnd_state *state, void *buf, int nbytes);
+void prandom_bytes_state(struct rnd_state *state, void *buf, size_t nbytes);
/**
* prandom_u32_max - returns a pseudo-random number in interval [0, ep_ro)
diff --git a/lib/random32.c b/lib/random32.c
index c9b6bf3..0bee183 100644
--- a/lib/random32.c
+++ b/lib/random32.c
@@ -37,6 +37,7 @@
#include <linux/jiffies.h>
#include <linux/random.h>
#include <linux/sched.h>
+#include <asm/unaligned.h>
#ifdef CONFIG_RANDOM32_SELFTEST
static void __init prandom_state_selftest(void);
@@ -96,27 +97,23 @@ EXPORT_SYMBOL(prandom_u32);
* This is used for pseudo-randomness with no outside seeding.
* For more random results, use prandom_bytes().
*/
-void prandom_bytes_state(struct rnd_state *state, void *buf, int bytes)
+void prandom_bytes_state(struct rnd_state *state, void *buf, size_t bytes)
{
- unsigned char *p = buf;
- int i;
-
- for (i = 0; i < round_down(bytes, sizeof(u32)); i += sizeof(u32)) {
- u32 random = prandom_u32_state(state);
- int j;
+ u8 *ptr = buf;
- for (j = 0; j < sizeof(u32); j++) {
- p[i + j] = random;
- random >>= BITS_PER_BYTE;
- }
+ while (bytes >= sizeof(u32)) {
+ put_unaligned(prandom_u32_state(state), (u32 *) ptr);
+ ptr += sizeof(u32);
+ bytes -= sizeof(u32);
}
- if (i < bytes) {
- u32 random = prandom_u32_state(state);
- for (; i < bytes; i++) {
- p[i] = random;
- random >>= BITS_PER_BYTE;
- }
+ if (bytes > 0) {
+ u32 rem = prandom_u32_state(state);
+ do {
+ *ptr++ = (u8) rem;
+ bytes--;
+ rem >>= BITS_PER_BYTE;
+ } while (bytes > 0);
}
}
EXPORT_SYMBOL(prandom_bytes_state);
@@ -126,7 +123,7 @@ EXPORT_SYMBOL(prandom_bytes_state);
* @buf: where to copy the pseudo-random bytes to
* @bytes: the requested number of bytes
*/
-void prandom_bytes(void *buf, int bytes)
+void prandom_bytes(void *buf, size_t bytes)
{
struct rnd_state *state = &get_cpu_var(net_rand_state);
@@ -137,7 +134,7 @@ EXPORT_SYMBOL(prandom_bytes);
static void prandom_warmup(struct rnd_state *state)
{
- /* Calling RNG ten times to satify recurrence condition */
+ /* Calling RNG ten times to satisfy recurrence condition */
prandom_u32_state(state);
prandom_u32_state(state);
prandom_u32_state(state);
@@ -152,7 +149,7 @@ static void prandom_warmup(struct rnd_state *state)
static u32 __extract_hwseed(void)
{
- u32 val = 0;
+ unsigned int val = 0;
(void)(arch_get_random_seed_int(&val) ||
arch_get_random_int(&val));
@@ -228,7 +225,7 @@ static void __prandom_timer(unsigned long dontcare)
prandom_seed(entropy);
/* reseed every ~60 seconds, in [40 .. 80) interval with slack */
- expires = 40 + (prandom_u32() % 40);
+ expires = 40 + prandom_u32_max(40);
seed_timer.expires = jiffies + msecs_to_jiffies(expires * MSEC_PER_SEC);
add_timer(&seed_timer);
--
1.7.11.7
^ permalink raw reply related
* Re: [patch net-next RFC 10/12] openvswitch: add support for datapath hardware offload
From: Thomas Graf @ 2014-08-23 14:51 UTC (permalink / raw)
To: Jiri Pirko
Cc: Scott Feldman, John Fastabend, netdev, davem, nhorman, andy,
dborkman, ogerlitz, jesse, pshelar, azhou, ben, stephen,
jeffrey.t.kirsher, vyasevic, xiyou.wangcong, john.r.fastabend,
edumazet, jhs, f.fainelli, roopa, linville, dev, jasowang,
ebiederm, nicolas.dichtel, ryazanov.s.a, buytenh, aviadr, nbd,
alexei.starovoitov, Neil.Jerram, ronye
In-Reply-To: <20140823092458.GC1854@nanopsycho.orion>
On 08/23/14 at 11:24am, Jiri Pirko wrote:
> Sat, Aug 23, 2014 at 12:53:34AM CEST, sfeldma@cumulusnetworks.com wrote:
> >
> >On Aug 22, 2014, at 12:39 PM, John Fastabend <john.fastabend@gmail.com> wrote:
> >> - this requires OVS to be loaded to work. If all I want is
> >> direct access to the hardware flow tables requiring openvswitch.ko
> >> shouldn't be needed IMO. For example I may want to use the
> >> hardware flow tables with something not openvswitch and we
> >> shouldn't preclude that.
> >>
> >
> >The intent is to use openvswitch.ko’s struct sw_flow to program hardware via the ndo_swdev_flow_* ops, but otherwise be independent of OVS. So the upper layer of the driver is struct sw_flow and any module above the driver can construct a struct sw_flow and push it down via ndo_swdev_flow_*. So your non-OVS use-case should be handled. OVS is another use-case. struct sw_flow should not be OVS-aware, but rather a generic flow match/action sufficient to offload the data plane to HW.
>
> Yes. I was thinking about simple Netlink API that would expose direct
> sw_flow manipulation (ndo_swdev_flow_* wrapper) to userspace. I will
> think abou that more and perhaps add it to my next patchset version.
I agree that this might help to give a better API consumption example
for everyone not familiar with OVS.
> >> - Also there is no programmatic way to learn which flows are
> >> in hardware and which in software. There is a pr_warn but
> >> that doesn't help when interacting with the hardware remotely.
> >> I need some mechanism to dump the set of hardware tables and
> >> the set of software tables.
> >
> >Agreed, we need a way to annotate which flows are installed hardware.
>
> Yes, we discussed that already. We need to make OVS daemon hw-offload
> aware indicating which flow it want/prefers to be offloaded. This is I
> believe easily extentable feature and can be added whenever the right
> time is.
I think the swdev flow API is good as-is. The bitmask specyfing the
offload preference with all the granularity (offload-or-fail,
try-to-offload, never-offload) needed can be added later, either in
OVS only or in swdev itself.
What is unclear in this patch is how OVS user space can know which
flows are offloaded and which aren't. A status field would help here
which indicates either: flow inserted and offloaded, flow inserted but
not offloaded. Given that, the API consumer can easily keep track of
which flows are currently offloaded.
Also, I'm not sure whether flow expiration is something the API must
take care of. The current proposal assumes that HW flows are only
ever removed by the API itself. Could the switch CPU run code which
removes flows as well? That would call for Netlink notifications.
Not that it's needed at this stage of the code but maybe worth
considerating for the API design.
> >> - Simply duplicating the software flow/action into
> >> hardware may not optimally use the hardware tables. If I have
> >> a TCAM in hardware for instance. (This is how I read the patch
> >> let me know if I missed something)
> >
> >The hardware-specific driver is the right place to handle optimizing the flow/action in hardware since only the driver can know the size/shape of the device. struct sw_flow is a generic flow description; how (or if) a flow gets programmed into hardware must be handled in the swdev driver. If the device driver can’t make the sw_flow fit into HW because of resource limitations or the flow simply can’t be represented in HW, then the flow is SW only.
> >
> >In the rocker driver posted in this patch set, the steps are to parse the struct sw_flow to figure out what type of flow match/action we’re dealing with (L2 or L3 or L4, ucast or mcast, ipv4 or ipv6, etc) and then install the correct entries into the corresponding device tables within the constraints of the device’s pipeline. Any optimizations, like coalescing HW entries, is something only the driver can do.
The later examples definitely make sense and I'm not argueing against
that. There is also a non hardware capabilities perspective that I
would like to present:
1) TCAM capacity is limtied, we offload based on some priority assigned
to flows. Some are critical and need to be in HW, others are best effort,
others never go into hardware. An API user will likely want to offload
best-effort flows until some watermark is reached and then switch to
critical flows only. The driver is not the right place for high level
optimization like this. The kernel API might but doesn't really have to
either because it would mean we need APIs to transfer all of the
needed context for the decision in the kernel. It might be easier to
expose the hardware context to user space instead and handle these
kind of optimizations in something like Quagga.
2) There is definitely a desire to allow adapting the software flow table
based on the hardware capabilities. Example, given a route like this:
20.1.0.0/16, mark=50, tos=0x12, actions: output:eth1
The hardware can satisfy everything except the mark=50 match. Given a
a blind 1:1 copy between hardware and software we cannot offload
because a mach would be illegal. With the full context as available
north of the API, this could be translated into something like this:
HW: 20.1.0.0/16, tos=0x12, actions: meta=1, output:cpu
SW: meta=1, mark=50, output:eth1
This will allow for partial offloads to bypass expensive masked flow
table lookups by converting them into efficient flat exact match
tables, offload TC classifiers, nftables or even the existing L2 and
L3 forwarding path.
In summary, I think the swdev API as proposed is a good start as the
in-kernel flow abstraction is sufficient for many API users but we
should consider enabling the model described above as well once we
have the basic model put in place. I will be very interested in helping
out on this for both existing classifiers and OVS flow tables.
> >> - I need a way to specify put this flow/action in hardware,
> >> put this flow/action in software, or put this in both software
> >> and hardware.
> >>
> >
> >This seems above the swdev layer. In other words, don’t call ndo_swdev_flow_* if you don’t want flow match/action install in HW.
It can certainly be done northbound but this seems like a basic
requirement and we might end up avoiding the code duplication and
extending the API instead.
^ permalink raw reply
* Urgent Assistance from Syria
From: Abdul Nasser Sokariah @ 2014-08-23 14:08 UTC (permalink / raw)
--
Good Day From Syria,
My name is Abdul Nasser Sokariah and I am writing you from Syria, I
choose to contact you directly as I need a reliable person to trust
who can help me make claims to my huge deposit with a vault company in
AFRICA, and based on my present situation in Syria, I need you
urgently to take possession of everything and further
modalities/directives will follow.
Contact me only on my private Email:nabdul247@gmail.com for
clarifications,I await your response.
Yours truly, Abdul Nasser Sokariah
Contact Email:nabdul247@gmail.com
^ permalink raw reply
* Re: [patch net-next RFC 12/12] rocker: introduce rocker switch driver
From: Thomas Graf @ 2014-08-23 14:04 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, nhorman, andy, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, jeffrey.t.kirsher, vyasevic, xiyou.wangcong,
john.r.fastabend, edumazet, jhs, sfeldma, f.fainelli, roopa,
linville, dev, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye
In-Reply-To: <1408637945-10390-13-git-send-email-jiri@resnulli.us>
On 08/21/14 at 06:19pm, Jiri Pirko wrote:
> This patch introduces the first driver to benefit from the switchdev
> infrastructure and to implement newly introduced switch ndos. This is a
> driver for emulated switch chip implemented in qemu:
> https://github.com/sfeldma/qemu-rocker/
The design looks very clean. I noticed that the TLV API is almost an
exact dupliate of the Netlink attributes API. Any specific reason for
not reusing lib/nlattr.c and add what is missing?
^ permalink raw reply
* Dear friend
From: mr.tomcoulibaly @ 2014-08-23 13:05 UTC (permalink / raw)
Dear friend
I am contacting you on a business deal of $17.5 Million US Dollars, ready for
transfer into your account The depositor of the said fund died with
his entire family during the Iraq war in 2006, unfortunately leaving
nobody for the claim. if we make this claim, we will share it
60%/40%.100% risk free and it will be legally backed up with
government approved If you are interested reply for more details.Reply
to alternative email address. (mr.tomcoulibaly@gmail.com) Waiting for
your reply
Best regard, Mr.Tom Coulibaly
^ permalink raw reply
* Re: [patch net-next RFC 07/12] dsa: implement ndo_swdev_get_id
From: Eric W. Biederman @ 2014-08-23 11:33 UTC (permalink / raw)
To: Jiri Pirko
Cc: Sergey Ryazanov, jasowang-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org,
John Fastabend, Neil Jerram, Eric Dumazet, Andy Gospodarek, dev,
Felix Fietkau, Florian Fainelli, ronye-VPRAkNaXOzVWk0Htik3J/w,
Jeff Kirsher, ogerlitz, Ben Hutchings, Lennert Buytenhek,
Roopa Prabhu, Jamal Hadi Salim, Aviad Raveh, Nicolas Dichtel,
vyasevic, Neil Horman, netdev, Stephen Hemminger, dborkman,
David
In-Reply-To: <20140821170645.GB10633-6KJVSR23iU5sFDB2n11ItA@public.gmane.org>
Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org> writes:
> Thu, Aug 21, 2014 at 06:56:13PM CEST, f.fainelli-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:
>>2014-08-21 9:19 GMT-07:00 Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>:
>>> Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
>>> ---
>>> net/dsa/Kconfig | 2 +-
>>> net/dsa/slave.c | 16 ++++++++++++++++
>>> 2 files changed, 17 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
>>> index f5eede1..66c445a 100644
>>> --- a/net/dsa/Kconfig
>>> +++ b/net/dsa/Kconfig
>>> @@ -1,6 +1,6 @@
>>> config HAVE_NET_DSA
>>> def_bool y
>>> - depends on NETDEVICES && !S390
>>> + depends on NETDEVICES && NET_SWITCHDEV && !S390
>>>
>>> # Drivers must select NET_DSA and the appropriate tagging format
>>>
>>> diff --git a/net/dsa/slave.c b/net/dsa/slave.c
>>> index 45a1e34..e069ba3 100644
>>> --- a/net/dsa/slave.c
>>> +++ b/net/dsa/slave.c
>>> @@ -171,6 +171,19 @@ static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
>>> return -EOPNOTSUPP;
>>> }
>>>
>>> +static int dsa_slave_swdev_get_id(struct net_device *dev,
>>> + struct netdev_phys_item_id *psid)
>>> +{
>>> + struct dsa_slave_priv *p = netdev_priv(dev);
>>> + struct dsa_switch *ds = p->parent;
>>> + u64 tmp = (u64) ds;
>>> +
>>> + /* TODO: add more sophisticated id generation */
>>> + memcpy(&psid->id, &tmp, sizeof(tmp));
>>> + psid->id_len = sizeof(tmp);
>>
>>There is already an unique id generated, which is the index in the
>>switch tree, and which is stored in struct dsa_switch, so this could
>>probably be simplified to:
>>
>>psid->id = ds->index
>
> That index is 0..n if I understand that correctly. That is not enough.
> The point is to have unique id for every chip in the system. If we would
> have 0,1,2... the collision is very likely.
I am just kibitzing but ethernet switches capable of speaking stp
require a mac address per port. So if you want a unique id I would
pick one of your mac addresses, which should be uniuqe.
I can understand low end devices where sophisticated things will never
happen fudging on the mac address requirements but by the time you care
I expect you have a mac address.
Eric
^ permalink raw reply
* Re: [patch net-next RFC 10/12] openvswitch: add support for datapath hardware offload
From: Jiri Pirko @ 2014-08-23 9:24 UTC (permalink / raw)
To: Scott Feldman
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w, ronye-VPRAkNaXOzVWk0Htik3J/w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w, John Fastabend,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
netdev-u79uwXL29TY76Z2rM5mHXA,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <464DB0A8-0073-4CE0-9483-0F36B73A53A1-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR@public.gmane.org>
Sat, Aug 23, 2014 at 12:53:34AM CEST, sfeldma@cumulusnetworks.com wrote:
>
>On Aug 22, 2014, at 12:39 PM, John Fastabend <john.fastabend@gmail.com> wrote:
>
>> On 08/21/2014 09:19 AM, Jiri Pirko wrote:
>>> Benefit from the possibility to work with flows in switch devices and
>>> use the swdev api to offload flow datapath.
>>
>> we should add a description here on the strategy being used.
>>
>> If I read this correctly this will try to add any flow to the
>> hardware along with the actions and duplicate it in software.
>>
>> There are a couple things I don't like,
>>
>> - this requires OVS to be loaded to work. If all I want is
>> direct access to the hardware flow tables requiring openvswitch.ko
>> shouldn't be needed IMO. For example I may want to use the
>> hardware flow tables with something not openvswitch and we
>> shouldn't preclude that.
>>
>
>The intent is to use openvswitch.ko’s struct sw_flow to program hardware via the ndo_swdev_flow_* ops, but otherwise be independent of OVS. So the upper layer of the driver is struct sw_flow and any module above the driver can construct a struct sw_flow and push it down via ndo_swdev_flow_*. So your non-OVS use-case should be handled. OVS is another use-case. struct sw_flow should not be OVS-aware, but rather a generic flow match/action sufficient to offload the data plane to HW.
Yes. I was thinking about simple Netlink API that would expose direct
sw_flow manipulation (ndo_swdev_flow_* wrapper) to userspace. I will
think abou that more and perhaps add it to my next patchset version.
>
>> - Also there is no programmatic way to learn which flows are
>> in hardware and which in software. There is a pr_warn but
>> that doesn't help when interacting with the hardware remotely.
>> I need some mechanism to dump the set of hardware tables and
>> the set of software tables.
>
>Agreed, we need a way to annotate which flows are installed hardware.
Yes, we discussed that already. We need to make OVS daemon hw-offload
aware indicating which flow it want/prefers to be offloaded. This is I
believe easily extentable feature and can be added whenever the right
time is.
>
>> - Simply duplicating the software flow/action into
>> hardware may not optimally use the hardware tables. If I have
>> a TCAM in hardware for instance. (This is how I read the patch
>> let me know if I missed something)
>
>The hardware-specific driver is the right place to handle optimizing the flow/action in hardware since only the driver can know the size/shape of the device. struct sw_flow is a generic flow description; how (or if) a flow gets programmed into hardware must be handled in the swdev driver. If the device driver can’t make the sw_flow fit into HW because of resource limitations or the flow simply can’t be represented in HW, then the flow is SW only.
>
>In the rocker driver posted in this patch set, the steps are to parse the struct sw_flow to figure out what type of flow match/action we’re dealing with (L2 or L3 or L4, ucast or mcast, ipv4 or ipv6, etc) and then install the correct entries into the corresponding device tables within the constraints of the device’s pipeline. Any optimizations, like coalescing HW entries, is something only the driver can do.
>
>>
>> - I need a way to specify put this flow/action in hardware,
>> put this flow/action in software, or put this in both software
>> and hardware.
>>
>
>This seems above the swdev layer. In other words, don’t call ndo_swdev_flow_* if you don’t want flow match/action install in HW.
>
>> We did this with a bitmask in the fdb L2 stuff and it seems to
>> work reasonable well so maybe something like that would help.
>>
>> For example if I don't have this what happens if I have an
>> entry to decrement TTL in both hardware and software. If the
>> flow hits both the hardware path and software path the TTL
>> gets decremented. Here userspace needs to indicate where to
>> do the decrement to avoid the duplication.
>
>I’m not following why a flow would hit both HW and SW paths. That seems bad, and negating to effort of offloading the flow to HW in the first place. My simple view is if flow hits HW path, then SW path is unaware. Clearly work is needed to provide coherent view to user with respect to stat counters and such, but I believe do-able.
>
>>
>> I think if we can pull this out OVS and add the hw/sw bitmask (or
>> maybe a better implementation of that idea) then this should work
>> for the stuff I'm looking at. I want to try and get it working on
>> the i40e driver as a fdir replacement but it might take me a bit
>> to get to it.
>
>That sounds cool and would really help get the interface in place. Take another look at the way Jiri has busted out sw_flow.h and see if this works for you outside of an OVS context. If not, we need to fix it.
Great. John, please keep us posted about your progress.
Let me know if you need any help.
>
>
>>
>> Thanks,
>> John
>>
>>
>> --
>> John Fastabend Intel Corporation
>> --
>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
>-scott
>
>
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev
^ permalink raw reply
* Re: [patch net-next RFC 03/12] net: introduce generic switch devices support
From: Jiri Pirko @ 2014-08-23 9:17 UTC (permalink / raw)
To: Florian Fainelli
Cc: Sergey Ryazanov, jasowang-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org,
John Fastabend, Neil Jerram, Eric Dumazet, Andy Gospodarek, dev,
Felix Fietkau, ronye-VPRAkNaXOzVWk0Htik3J/w, Jeff Kirsher,
ogerlitz, Ben Hutchings, Lennert Buytenhek, Roopa Prabhu,
Jamal Hadi Salim, Aviad Raveh, Nicolas Dichtel, vyasevic,
Neil Horman, netdev, Stephen Hemminger, dborkman,
Eric W. Biederman, David
In-Reply-To: <CAGVrzcZS=Y2stxSNMfVjWTpPT8GoDOpOD9tExnDnoF0jj_owoQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Sat, Aug 23, 2014 at 03:02:10AM CEST, f.fainelli-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:
>2014-08-22 5:56 GMT-07:00 Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>:
>> Fri, Aug 22, 2014 at 02:42:04PM CEST, jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org wrote:
>>>On 08/21/14 13:05, Florian Fainelli wrote:
>>>>2014-08-21 9:18 GMT-07:00 Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>:
>>>>>The goal of this is to provide a possibility to suport various switch
>>>>>chips. Drivers should implement relevant ndos to do so. Now there is a
>>>>>couple of ndos defines:
>>>>>- for getting physical switch id is in place.
>>>>>- for work with flows.
>>>>>
>>>>>Note that user can use random port netdevice to access the switch.
>>>>
>>>>I read through this patch set, and I still think that DSA is the
>>>>generic switch infrastructure we already have because it does provide
>>>>the following:
>>>>
>>>>- taking a generic platform data structure (C struct or Device Tree),
>>>>validate, parse it and map it to internal kernel structures
>>>>- instantiate per-port network devices based on the configuration data provided
>>>>- delegate netdev_ops to the switch driver and/or the CPU NIC when relevant
>>>>- provide support for hooking RX and TX traffic coming from the CPU NIC
>>>>
>>>>I would rather we build on the existing DSA infrastructure and add the
>>>>flow-related netdev_ops rather than having the two remain in
>>>>disconnect while flow-oriented switches driver get progressively
>>>>added. I guess I should take a closer look at the rocker driver to see
>>>>how hard would that be for you.
>>>>
>>>>What do you think?
>>>
>>>
>>>I thought we had concluded that DSA was a good path forward? Or maybe at
>>>this stage we need to have several alternative approaches
>>>and we eventually converge?
>>
>> That is true. I'm still unsure how to fit this on to DSA or how to change DSA
>> the way this fits. This is my quest now. Will report back in a week or so.
>
>I don't want to hold off this patch series, so let's proceed with your
>submission, since I believe John Fastabend would also directly benefit
>from this.
>
>In the meantime, I will keep working on DSA, and prototype changes
>with the rocker driver.
>
>Once we are confident we have bridged the gap, we can unify things.
>How does that sound?
Sounds good.
^ permalink raw reply
* Re: [PATCH net-next] tcp: improve undo on timeout
From: David Miller @ 2014-08-23 4:28 UTC (permalink / raw)
To: ycheng; +Cc: ncardwell, netdev
In-Reply-To: <1408742122-23674-1-git-send-email-ycheng@google.com>
From: Yuchung Cheng <ycheng@google.com>
Date: Fri, 22 Aug 2014 14:15:22 -0700
> Upon timeout, undo (via both timestamps/Eifel and DSACKs) was
> disabled if any retransmits were still in flight. The concern was
> perhaps that spurious retransmission sent in a previous recovery
> episode may trigger DSACKs to falsely undo the current recovery.
>
> However, this inadvertently misses undo opportunities (using either
> TCP timestamps or DSACKs) when timeout occurs during a loss episode,
> i.e. recurring timeouts or timeout during fast recovery. In these
> cases some retransmissions will be in flight but we should allow
> undo. Furthermore, we should only reset undo_marker and undo_retrans
> upon timeout if we are starting a new recovery episode. Finally,
> when we do reset our undo state, we now do so in a manner similar
> to tcp_enter_recovery(), so that we require a DSACK for each of
> the outstsanding retransmissions. This will achieve the original
> goal by requiring that we receive the same number of DSACKs as
> retransmissions.
>
> This patch increases the undo events by 50% on Google servers.
>
> Signed-off-by: Yuchung Cheng <ycheng@google.com>
> Signed-off-by: Neal Cardwell <ncardwell@google.com>
Looks good, applied, thanks!
^ permalink raw reply
* Re: [PATCH] phylib: use MDIO_DEVS[12]
From: David Miller @ 2014-08-23 4:17 UTC (permalink / raw)
To: sergei.shtylyov; +Cc: netdev, f.fainelli
In-Reply-To: <1920521.UOn8o4CGAS@wasted.cogentembedded.com>
From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Date: Fri, 22 Aug 2014 23:56:47 +0400
> The bare register numbers are used despite <uapi/linux/mdio.h> has MDIO_DEVS[12]
> #define'd for those.
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Applied, thank you.
^ permalink raw reply
* Re: [PATCH net-next] net: remove dead code after sk_data_ready change
From: David Miller @ 2014-08-23 4:09 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1408764612.5604.46.camel@edumazet-glaptop2.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 22 Aug 2014 20:30:12 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> As a followup to commit 676d23690fb ("net: Fix use after free by
> removing length arg from sk_data_ready callbacks"), we can remove
> some useless code in sock_queue_rcv_skb() and rxrpc_queue_rcv_skb()
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Good catch, applied.
^ permalink raw reply
* [PATCH net-next] net: remove dead code after sk_data_ready change
From: Eric Dumazet @ 2014-08-23 3:30 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
As a followup to commit 676d23690fb ("net: Fix use after free by
removing length arg from sk_data_ready callbacks"), we can remove
some useless code in sock_queue_rcv_skb() and rxrpc_queue_rcv_skb()
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/core/sock.c | 8 --------
net/rxrpc/ar-input.c | 9 +--------
2 files changed, 1 insertion(+), 16 deletions(-)
diff --git a/net/core/sock.c b/net/core/sock.c
index 2714811afbd8..f7f2352200ad 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -437,7 +437,6 @@ static void sock_disable_timestamp(struct sock *sk, unsigned long flags)
int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
int err;
- int skb_len;
unsigned long flags;
struct sk_buff_head *list = &sk->sk_receive_queue;
@@ -459,13 +458,6 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
skb->dev = NULL;
skb_set_owner_r(skb, sk);
- /* Cache the SKB length before we tack it onto the receive
- * queue. Once it is added it no longer belongs to us and
- * may be freed by other threads of control pulling packets
- * from the queue.
- */
- skb_len = skb->len;
-
/* we escape from rcu protected region, make sure we dont leak
* a norefcounted dst
*/
diff --git a/net/rxrpc/ar-input.c b/net/rxrpc/ar-input.c
index 63b21e580de9..481f89f93789 100644
--- a/net/rxrpc/ar-input.c
+++ b/net/rxrpc/ar-input.c
@@ -45,7 +45,7 @@ int rxrpc_queue_rcv_skb(struct rxrpc_call *call, struct sk_buff *skb,
struct rxrpc_skb_priv *sp;
struct rxrpc_sock *rx = call->socket;
struct sock *sk;
- int skb_len, ret;
+ int ret;
_enter(",,%d,%d", force, terminal);
@@ -101,13 +101,6 @@ int rxrpc_queue_rcv_skb(struct rxrpc_call *call, struct sk_buff *skb,
rx->interceptor(sk, call->user_call_ID, skb);
spin_unlock_bh(&sk->sk_receive_queue.lock);
} else {
-
- /* Cache the SKB length before we tack it onto the
- * receive queue. Once it is added it no longer
- * belongs to us and may be freed by other threads of
- * control pulling packets from the queue */
- skb_len = skb->len;
-
_net("post skb %p", skb);
__skb_queue_tail(&sk->sk_receive_queue, skb);
spin_unlock_bh(&sk->sk_receive_queue.lock);
^ permalink raw reply related
* Re: [PATCH net-next] net: use ktime_get_ns() and ktime_get_real_ns() helpers
From: David Miller @ 2014-08-23 2:57 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1408757529.5604.41.camel@edumazet-glaptop2.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 22 Aug 2014 18:32:09 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> ktime_get_ns() replaces ktime_to_ns(ktime_get())
>
> ktime_get_real_ns() replaces ktime_to_ns(ktime_get_real())
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied, thanks Eric.
^ permalink raw reply
* Re: [PATCH v2 net] vxlan: fix incorrect initializer in union vxlan_addr
From: David Miller @ 2014-08-23 2:55 UTC (permalink / raw)
To: gstenzel; +Cc: netdev
In-Reply-To: <53F79B38.8070806@linux.vnet.ibm.com>
From: Gerhard Stenzel <gstenzel@linux.vnet.ibm.com>
Date: Fri, 22 Aug 2014 21:34:16 +0200
> The first initializer in the following
>
> union vxlan_addr ipa = {
> .sin.sin_addr.s_addr = tip,
> .sa.sa_family = AF_INET,
> };
>
> is optimised away by the compiler, due to the second initializer,
> therefore initialising .sin.sin_addr.s_addr always to 0.
> This results in netlink messages indicating a L3 miss never contain the
> missed IP address. This was observed with GCC 4.8 and 4.9. I do not know about previous versions.
> The problem affects user space programs relying on an IP address being
> sent as part of a netlink message indicating a L3 miss.
>
> Changing
> .sa.sa_family = AF_INET,
> to
> .sin.sin_family = AF_INET,
> fixes the problem.
>
> Signed-off-by: Gerhard Stenzel <gerhard.stenzel@de.ibm.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* Re: pull-request: can-next 2014-08-20
From: David Miller @ 2014-08-23 2:43 UTC (permalink / raw)
To: mkl; +Cc: netdev, linux-can, kernel
In-Reply-To: <53F4B580.3030802@pengutronix.de>
From: Marc Kleine-Budde <mkl@pengutronix.de>
Date: Wed, 20 Aug 2014 16:49:36 +0200
> There is one patch by Wolfram Sang to clean up the build system.
> Two patches by Stefan Agner that add vf610 support to the flexcan
> driver. Dong Aisheng add support for bosch's m_can core, which is found
> in the new freescale ARM SoCs. Sergei Shtylyov improves the rcar_can
> driver by supporting all input clocks and adding device tree support.
> The next patch is a small cleanup for the bit rate calculation function
> by Lad, Prabhakar. And finally a patch by Himangi Saraogi, which
> converts the mcp251x driver to use dmam_alloc_coherent.
Pulled, thanks Marc.
^ permalink raw reply
* Re: [PATCH net-next 0/4] r8152: firmware support
From: David Miller @ 2014-08-23 2:41 UTC (permalink / raw)
To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb
In-Reply-To: <1394712342-15778-16-Taiwan-albertk@realtek.com>
From: Hayes Wang <hayeswang@realtek.com>
Date: Wed, 20 Aug 2014 16:58:35 +0800
> Parsing, checking, and writing the firmware.
You haven't told us why you need to do this.
These are just programming registers in the chip, and I see no reason
to not keep these in the driver with real code.
I'm not applying this series, you haven't explained what is happening
here and the reason for doing so. Ironically, that's exactly what you
are supposed to provide in this 0/4 header email.
^ permalink raw reply
* [PATCH 8/8] qlge: Fix TSO for non-accelerated vlan traffic
From: vyasevich @ 2014-08-23 2:17 UTC (permalink / raw)
To: netdev
Cc: Vladislav Yasevich, Shahed Shaikh, Jitendra Kalsaria, Ron Mercer,
linux-driver
In-Reply-To: <1408760230-7457-1-git-send-email-vysevich@gmail.com>
From: Vladislav Yasevich <vyasevic@redhat.com>
This device claims TSO support for vlans. It also allows a user to
control vlan acceleration offloading. As such, it is possible to turn
off vlan acceleration and configure a vlan which will continue to send
TSO traffic.
In such situation the packet passed down the the device will contain
a vlan header and skb->protocol will be set to ETH_P_8021Q.
The device assumes that skb->protocol contains network protocol
value and uses that value to set up TSO information.
This results in corrupted frames sent on the wire.
This patch extracts the protocol value correctly by using a
vlan_get_protocol() helper and corrects corrupt TSO frames.
CC: Shahed Shaikh <shahed.shaikh@qlogic.com>
CC: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
CC: Ron Mercer <ron.mercer@qlogic.com>
CC: linux-driver@qlogic.com
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
drivers/net/ethernet/qlogic/qlge/qlge_main.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
index 188626e..3e96f26 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
@@ -2556,6 +2556,7 @@ static int ql_tso(struct sk_buff *skb, struct ob_mac_tso_iocb_req *mac_iocb_ptr)
if (skb_is_gso(skb)) {
int err;
+ __be16 l3_proto = vlan_get_protocol(skb);
err = skb_cow_head(skb, 0);
if (err < 0)
@@ -2572,7 +2573,7 @@ static int ql_tso(struct sk_buff *skb, struct ob_mac_tso_iocb_req *mac_iocb_ptr)
<< OB_MAC_TRANSPORT_HDR_SHIFT);
mac_iocb_ptr->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
mac_iocb_ptr->flags2 |= OB_MAC_TSO_IOCB_LSO;
- if (likely(skb->protocol == htons(ETH_P_IP))) {
+ if (likely(l3_proto == htons(ETH_P_IP))) {
struct iphdr *iph = ip_hdr(skb);
iph->check = 0;
mac_iocb_ptr->flags1 |= OB_MAC_TSO_IOCB_IP4;
@@ -2580,7 +2581,7 @@ static int ql_tso(struct sk_buff *skb, struct ob_mac_tso_iocb_req *mac_iocb_ptr)
iph->daddr, 0,
IPPROTO_TCP,
0);
- } else if (skb->protocol == htons(ETH_P_IPV6)) {
+ } else if (l3_proto == htons(ETH_P_IPV6)) {
mac_iocb_ptr->flags1 |= OB_MAC_TSO_IOCB_IP6;
tcp_hdr(skb)->check =
~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
--
1.9.3
^ permalink raw reply related
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