netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 net-next 0/7] net: Eliminate calls to flow_dissector and introduce flow_keys_digest
@ 2015-05-01 18:30 Tom Herbert
  2015-05-01 18:30 ` [PATCH v2 net-next 1/7] net: Add skb_get_hash_perturb Tom Herbert
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Tom Herbert @ 2015-05-01 18:30 UTC (permalink / raw)
  To: davem, netdev

In this patch set we add skb_get_hash_perturb which gets the skbuff
hash for a packet and perturbs it using a provided key and jhash1.
This function is used in serveral qdiscs and eliminates many calls
to flow_dissector and jhash3 to get a perturbed hash for a packet.

To handle the sch_choke issue (passes flow_keys in skbuff cb) we
add flow_keys_digest which is a digest of a flow constructed
from a flow_keys structure.

This is the second version of these patches I posted a while ago,
and is prerequisite work to increasing the size of the flow_keys
structure and hashing over it (full IPv6 address, flow label, VLAN ID,
etc.).

Version 2:

- Add keyval parameter to __flow_hash_from_keys which allows caller to
  set the initval for jhash
- Perturb always does flow dissection and creates hash based on
  input perturb value which acts as the keyval to __flow_hash_from_keys
- Added a _flow_keys_digest_data which is used in make_flow_keys_digest.
  This fills out the digest by populating individual fields instead
  of copying the whole structure.

Tom Herbert (7):
  net: Add skb_get_hash_perturb
  sched: Call skb_get_hash_perturb in sch_fq_codel
  sched: Call skb_get_hash_perturb in sch_hhf
  sched: Call skb_get_hash_perturb in sch_sfb
  sched: Call skb_get_hash_perturb in sch_sfq
  net: Add flow_keys digest
  sch_choke: Use flow_keys_digest

 include/linux/skbuff.h    |  2 ++
 include/net/flow_keys.h   | 16 ++++++++++++
 net/core/flow_dissector.c | 65 +++++++++++++++++++++++++++++++++++++++++------
 net/sched/sch_choke.c     | 14 +++-------
 net/sched/sch_fq_codel.c  | 11 ++------
 net/sched/sch_hhf.c       | 19 +-------------
 net/sched/sch_sfb.c       | 24 ++++++-----------
 net/sched/sch_sfq.c       | 27 ++------------------
 8 files changed, 92 insertions(+), 86 deletions(-)

-- 
1.8.1

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 net-next 1/7] net: Add skb_get_hash_perturb
  2015-05-01 18:30 [PATCH v2 net-next 0/7] net: Eliminate calls to flow_dissector and introduce flow_keys_digest Tom Herbert
@ 2015-05-01 18:30 ` Tom Herbert
  2015-05-01 18:30 ` [PATCH v2 net-next 2/7] sched: Call skb_get_hash_perturb in sch_fq_codel Tom Herbert
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2015-05-01 18:30 UTC (permalink / raw)
  To: davem, netdev

This calls flow_disect and __skb_get_hash to procure a hash for a
packet. Input includes a key to initialize jhash. This function
does not set skb->hash.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 include/linux/skbuff.h    |  2 ++
 net/core/flow_dissector.c | 38 ++++++++++++++++++++++++++++++--------
 2 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 66e374d..acb83e2 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -927,6 +927,8 @@ static inline __u32 skb_get_hash(struct sk_buff *skb)
 	return skb->hash;
 }
 
+__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb);
+
 static inline __u32 skb_get_hash_raw(const struct sk_buff *skb)
 {
 	return skb->hash;
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 2c35c02..b1df995 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -267,13 +267,12 @@ static __always_inline void __flow_hash_secret_init(void)
 	net_get_random_once(&hashrnd, sizeof(hashrnd));
 }
 
-static __always_inline u32 __flow_hash_3words(u32 a, u32 b, u32 c)
+static __always_inline u32 __flow_hash_3words(u32 a, u32 b, u32 c, u32 keyval)
 {
-	__flow_hash_secret_init();
-	return jhash_3words(a, b, c, hashrnd);
+	return jhash_3words(a, b, c, keyval);
 }
 
-static inline u32 __flow_hash_from_keys(struct flow_keys *keys)
+static inline u32 __flow_hash_from_keys(struct flow_keys *keys, u32 keyval)
 {
 	u32 hash;
 
@@ -287,7 +286,8 @@ static inline u32 __flow_hash_from_keys(struct flow_keys *keys)
 
 	hash = __flow_hash_3words((__force u32)keys->dst,
 				  (__force u32)keys->src,
-				  (__force u32)keys->ports);
+				  (__force u32)keys->ports,
+				  keyval);
 	if (!hash)
 		hash = 1;
 
@@ -296,10 +296,20 @@ static inline u32 __flow_hash_from_keys(struct flow_keys *keys)
 
 u32 flow_hash_from_keys(struct flow_keys *keys)
 {
-	return __flow_hash_from_keys(keys);
+	__flow_hash_secret_init();
+	return __flow_hash_from_keys(keys, hashrnd);
 }
 EXPORT_SYMBOL(flow_hash_from_keys);
 
+static inline u32 ___skb_get_hash(const struct sk_buff *skb,
+				  struct flow_keys *keys, u32 keyval)
+{
+	if (!skb_flow_dissect(skb, keys))
+		return 0;
+
+	return __flow_hash_from_keys(keys, keyval);
+}
+
 /*
  * __skb_get_hash: calculate a flow hash based on src/dst addresses
  * and src/dst port numbers.  Sets hash in skb to non-zero hash value
@@ -309,8 +319,12 @@ EXPORT_SYMBOL(flow_hash_from_keys);
 void __skb_get_hash(struct sk_buff *skb)
 {
 	struct flow_keys keys;
+	u32 hash;
 
-	if (!skb_flow_dissect(skb, &keys))
+	__flow_hash_secret_init();
+
+	hash = ___skb_get_hash(skb, &keys, hashrnd);
+	if (!hash)
 		return;
 
 	if (keys.ports)
@@ -318,10 +332,18 @@ void __skb_get_hash(struct sk_buff *skb)
 
 	skb->sw_hash = 1;
 
-	skb->hash = __flow_hash_from_keys(&keys);
+	skb->hash = hash;
 }
 EXPORT_SYMBOL(__skb_get_hash);
 
+__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb)
+{
+	struct flow_keys keys;
+
+	return ___skb_get_hash(skb, &keys, perturb);
+}
+EXPORT_SYMBOL(skb_get_hash_perturb);
+
 /*
  * Returns a Tx hash based on the given packet descriptor a Tx queues' number
  * to be used as a distribution range.
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 net-next 2/7] sched: Call skb_get_hash_perturb in sch_fq_codel
  2015-05-01 18:30 [PATCH v2 net-next 0/7] net: Eliminate calls to flow_dissector and introduce flow_keys_digest Tom Herbert
  2015-05-01 18:30 ` [PATCH v2 net-next 1/7] net: Add skb_get_hash_perturb Tom Herbert
@ 2015-05-01 18:30 ` Tom Herbert
  2015-05-01 18:30 ` [PATCH v2 net-next 3/7] sched: Call skb_get_hash_perturb in sch_hhf Tom Herbert
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2015-05-01 18:30 UTC (permalink / raw)
  To: davem, netdev

Call skb_get_hash_perturb instead of doing skb_flow_dissect and then
jhash by hand.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 net/sched/sch_fq_codel.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
index 1e52dec..a6fc53d 100644
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -23,7 +23,6 @@
 #include <linux/vmalloc.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
-#include <net/flow_keys.h>
 #include <net/codel.h>
 
 /*	Fair Queue CoDel.
@@ -68,15 +67,9 @@ struct fq_codel_sched_data {
 };
 
 static unsigned int fq_codel_hash(const struct fq_codel_sched_data *q,
-				  const struct sk_buff *skb)
+				  struct sk_buff *skb)
 {
-	struct flow_keys keys;
-	unsigned int hash;
-
-	skb_flow_dissect(skb, &keys);
-	hash = jhash_3words((__force u32)keys.dst,
-			    (__force u32)keys.src ^ keys.ip_proto,
-			    (__force u32)keys.ports, q->perturbation);
+	u32 hash = skb_get_hash_perturb(skb, q->perturbation);
 
 	return reciprocal_scale(hash, q->flows_cnt);
 }
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 net-next 3/7] sched: Call skb_get_hash_perturb in sch_hhf
  2015-05-01 18:30 [PATCH v2 net-next 0/7] net: Eliminate calls to flow_dissector and introduce flow_keys_digest Tom Herbert
  2015-05-01 18:30 ` [PATCH v2 net-next 1/7] net: Add skb_get_hash_perturb Tom Herbert
  2015-05-01 18:30 ` [PATCH v2 net-next 2/7] sched: Call skb_get_hash_perturb in sch_fq_codel Tom Herbert
@ 2015-05-01 18:30 ` Tom Herbert
  2015-05-01 18:30 ` [PATCH v2 net-next 4/7] sched: Call skb_get_hash_perturb in sch_sfb Tom Herbert
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2015-05-01 18:30 UTC (permalink / raw)
  To: davem, netdev

Call skb_get_hash_perturb instead of doing skb_flow_dissect and then
jhash by hand.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 net/sched/sch_hhf.c | 19 +------------------
 1 file changed, 1 insertion(+), 18 deletions(-)

diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c
index 15d3aab..9d15cb6 100644
--- a/net/sched/sch_hhf.c
+++ b/net/sched/sch_hhf.c
@@ -9,7 +9,6 @@
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/vmalloc.h>
-#include <net/flow_keys.h>
 #include <net/pkt_sched.h>
 #include <net/sock.h>
 
@@ -176,22 +175,6 @@ static u32 hhf_time_stamp(void)
 	return jiffies;
 }
 
-static unsigned int skb_hash(const struct hhf_sched_data *q,
-			     const struct sk_buff *skb)
-{
-	struct flow_keys keys;
-	unsigned int hash;
-
-	if (skb->sk && skb->sk->sk_hash)
-		return skb->sk->sk_hash;
-
-	skb_flow_dissect(skb, &keys);
-	hash = jhash_3words((__force u32)keys.dst,
-			    (__force u32)keys.src ^ keys.ip_proto,
-			    (__force u32)keys.ports, q->perturbation);
-	return hash;
-}
-
 /* Looks up a heavy-hitter flow in a chaining list of table T. */
 static struct hh_flow_state *seek_list(const u32 hash,
 				       struct list_head *head,
@@ -280,7 +263,7 @@ static enum wdrr_bucket_idx hhf_classify(struct sk_buff *skb, struct Qdisc *sch)
 	}
 
 	/* Get hashed flow-id of the skb. */
-	hash = skb_hash(q, skb);
+	hash = skb_get_hash_perturb(skb, q->perturbation);
 
 	/* Check if this packet belongs to an already established HH flow. */
 	flow_pos = hash & HHF_BIT_MASK;
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 net-next 4/7] sched: Call skb_get_hash_perturb in sch_sfb
  2015-05-01 18:30 [PATCH v2 net-next 0/7] net: Eliminate calls to flow_dissector and introduce flow_keys_digest Tom Herbert
                   ` (2 preceding siblings ...)
  2015-05-01 18:30 ` [PATCH v2 net-next 3/7] sched: Call skb_get_hash_perturb in sch_hhf Tom Herbert
@ 2015-05-01 18:30 ` Tom Herbert
  2015-05-01 18:30 ` [PATCH v2 net-next 5/7] sched: Call skb_get_hash_perturb in sch_sfq Tom Herbert
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2015-05-01 18:30 UTC (permalink / raw)
  To: davem, netdev

Call skb_get_hash_perturb instead of doing skb_flow_dissect and then
jhash by hand.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 net/sched/sch_sfb.c | 24 ++++++++----------------
 1 file changed, 8 insertions(+), 16 deletions(-)

diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
index 5819dd8..4b81519 100644
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -26,7 +26,6 @@
 #include <net/ip.h>
 #include <net/pkt_sched.h>
 #include <net/inet_ecn.h>
-#include <net/flow_keys.h>
 
 /*
  * SFB uses two B[l][n] : L x N arrays of bins (L levels, N bins per level)
@@ -285,9 +284,9 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 	int i;
 	u32 p_min = ~0;
 	u32 minqlen = ~0;
-	u32 r, slot, salt, sfbhash;
+	u32 r, sfbhash;
+	u32 slot = q->slot;
 	int ret = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
-	struct flow_keys keys;
 
 	if (unlikely(sch->q.qlen >= q->limit)) {
 		qdisc_qstats_overlimit(sch);
@@ -309,22 +308,17 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 
 	fl = rcu_dereference_bh(q->filter_list);
 	if (fl) {
+		u32 salt;
+
 		/* If using external classifiers, get result and record it. */
 		if (!sfb_classify(skb, fl, &ret, &salt))
 			goto other_drop;
-		keys.src = salt;
-		keys.dst = 0;
-		keys.ports = 0;
+		sfbhash = jhash_1word(salt, q->bins[slot].perturbation);
 	} else {
-		skb_flow_dissect(skb, &keys);
+		sfbhash = skb_get_hash_perturb(skb, q->bins[slot].perturbation);
 	}
 
-	slot = q->slot;
 
-	sfbhash = jhash_3words((__force u32)keys.dst,
-			       (__force u32)keys.src,
-			       (__force u32)keys.ports,
-			       q->bins[slot].perturbation);
 	if (!sfbhash)
 		sfbhash = 1;
 	sfb_skb_cb(skb)->hashes[slot] = sfbhash;
@@ -356,10 +350,8 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 	if (unlikely(p_min >= SFB_MAX_PROB)) {
 		/* Inelastic flow */
 		if (q->double_buffering) {
-			sfbhash = jhash_3words((__force u32)keys.dst,
-					       (__force u32)keys.src,
-					       (__force u32)keys.ports,
-					       q->bins[slot].perturbation);
+			sfbhash = skb_get_hash_perturb(skb,
+			    q->bins[slot].perturbation);
 			if (!sfbhash)
 				sfbhash = 1;
 			sfb_skb_cb(skb)->hashes[slot] = sfbhash;
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 net-next 5/7] sched: Call skb_get_hash_perturb in sch_sfq
  2015-05-01 18:30 [PATCH v2 net-next 0/7] net: Eliminate calls to flow_dissector and introduce flow_keys_digest Tom Herbert
                   ` (3 preceding siblings ...)
  2015-05-01 18:30 ` [PATCH v2 net-next 4/7] sched: Call skb_get_hash_perturb in sch_sfb Tom Herbert
@ 2015-05-01 18:30 ` Tom Herbert
  2015-05-01 18:30 ` [PATCH v2 net-next 6/7] net: Add flow_keys digest Tom Herbert
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2015-05-01 18:30 UTC (permalink / raw)
  To: davem, netdev

Call skb_get_hash_perturb instead of doing skb_flow_dissect and then
jhash by hand.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 net/sched/sch_sfq.c | 27 ++-------------------------
 1 file changed, 2 insertions(+), 25 deletions(-)

diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index b877140..7d14926 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -23,7 +23,6 @@
 #include <linux/vmalloc.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
-#include <net/flow_keys.h>
 #include <net/red.h>
 
 
@@ -156,30 +155,10 @@ static inline struct sfq_head *sfq_dep_head(struct sfq_sched_data *q, sfq_index
 	return &q->dep[val - SFQ_MAX_FLOWS];
 }
 
-/*
- * In order to be able to quickly rehash our queue when timer changes
- * q->perturbation, we store flow_keys in skb->cb[]
- */
-struct sfq_skb_cb {
-       struct flow_keys        keys;
-};
-
-static inline struct sfq_skb_cb *sfq_skb_cb(const struct sk_buff *skb)
-{
-	qdisc_cb_private_validate(skb, sizeof(struct sfq_skb_cb));
-	return (struct sfq_skb_cb *)qdisc_skb_cb(skb)->data;
-}
-
 static unsigned int sfq_hash(const struct sfq_sched_data *q,
 			     const struct sk_buff *skb)
 {
-	const struct flow_keys *keys = &sfq_skb_cb(skb)->keys;
-	unsigned int hash;
-
-	hash = jhash_3words((__force u32)keys->dst,
-			    (__force u32)keys->src ^ keys->ip_proto,
-			    (__force u32)keys->ports, q->perturbation);
-	return hash & (q->divisor - 1);
+	return skb_get_hash_perturb(skb, q->perturbation) & (q->divisor - 1);
 }
 
 static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch,
@@ -196,10 +175,8 @@ static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch,
 		return TC_H_MIN(skb->priority);
 
 	fl = rcu_dereference_bh(q->filter_list);
-	if (!fl) {
-		skb_flow_dissect(skb, &sfq_skb_cb(skb)->keys);
+	if (!fl)
 		return sfq_hash(q, skb) + 1;
-	}
 
 	*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
 	result = tc_classify(skb, fl, &res);
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 net-next 6/7] net: Add flow_keys digest
  2015-05-01 18:30 [PATCH v2 net-next 0/7] net: Eliminate calls to flow_dissector and introduce flow_keys_digest Tom Herbert
                   ` (4 preceding siblings ...)
  2015-05-01 18:30 ` [PATCH v2 net-next 5/7] sched: Call skb_get_hash_perturb in sch_sfq Tom Herbert
@ 2015-05-01 18:30 ` Tom Herbert
  2015-05-01 18:30 ` [PATCH v2 net-next 7/7] sch_choke: Use flow_keys_digest Tom Herbert
  2015-05-04  4:09 ` [PATCH v2 net-next 0/7] net: Eliminate calls to flow_dissector and introduce flow_keys_digest David Miller
  7 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2015-05-01 18:30 UTC (permalink / raw)
  To: davem, netdev

Some users of flow keys (well just sch_choke now) need to pass
flow_keys in skbuff cb, and use them for exact comparisons of flows
so that skb->hash is not sufficient. In order to increase size of
the flow_keys structure, we introduce another structure for
the purpose of passing flow keys in skbuff cb. We limit this structure
to sixteen bytes, and we will technically treat this as a digest of
flow_keys struct hence its name flow_keys_digest. In the first
incaranation we just copy the flow_keys structure up to 16 bytes--
this is the same information previously passed in the cb. In the
future, we'll adapt this for larger flow_keys and could use something
like SHA-1 over the whole flow_keys to improve the quality of the
digest.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 include/net/flow_keys.h   | 16 ++++++++++++++++
 net/core/flow_dissector.c | 27 +++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/include/net/flow_keys.h b/include/net/flow_keys.h
index dc8fd81..6d6ef62 100644
--- a/include/net/flow_keys.h
+++ b/include/net/flow_keys.h
@@ -42,4 +42,20 @@ static inline __be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8
 u32 flow_hash_from_keys(struct flow_keys *keys);
 unsigned int flow_get_hlen(const unsigned char *data, unsigned int max_len,
 			   __be16 protocol);
+
+/* struct flow_keys_digest:
+ *
+ * This structure is used to hold a digest of the full flow keys. This is a
+ * larger "hash" of a flow to allow definitively matching specific flows where
+ * the 32 bit skb->hash is not large enough. The size is limited to 16 bytes so
+ * that it can by used in CB of skb (see sch_choke for an example).
+ */
+#define FLOW_KEYS_DIGEST_LEN	16
+struct flow_keys_digest {
+	u8	data[FLOW_KEYS_DIGEST_LEN];
+};
+
+void make_flow_keys_digest(struct flow_keys_digest *digest,
+			   const struct flow_keys *flow);
+
 #endif
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index b1df995..d3acc4d 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -310,6 +310,33 @@ static inline u32 ___skb_get_hash(const struct sk_buff *skb,
 	return __flow_hash_from_keys(keys, keyval);
 }
 
+struct _flow_keys_digest_data {
+	__be16	n_proto;
+	u8	ip_proto;
+	u8	padding;
+	__be32	ports;
+	__be32	src;
+	__be32	dst;
+};
+
+void make_flow_keys_digest(struct flow_keys_digest *digest,
+			   const struct flow_keys *flow)
+{
+	struct _flow_keys_digest_data *data =
+	    (struct _flow_keys_digest_data *)digest;
+
+	BUILD_BUG_ON(sizeof(*data) > sizeof(*digest));
+
+	memset(digest, 0, sizeof(*digest));
+
+	data->n_proto = flow->n_proto;
+	data->ip_proto = flow->ip_proto;
+	data->ports = flow->ports;
+	data->src = flow->src;
+	data->dst = flow->dst;
+}
+EXPORT_SYMBOL(make_flow_keys_digest);
+
 /*
  * __skb_get_hash: calculate a flow hash based on src/dst addresses
  * and src/dst port numbers.  Sets hash in skb to non-zero hash value
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 net-next 7/7] sch_choke: Use flow_keys_digest
  2015-05-01 18:30 [PATCH v2 net-next 0/7] net: Eliminate calls to flow_dissector and introduce flow_keys_digest Tom Herbert
                   ` (5 preceding siblings ...)
  2015-05-01 18:30 ` [PATCH v2 net-next 6/7] net: Add flow_keys digest Tom Herbert
@ 2015-05-01 18:30 ` Tom Herbert
  2015-05-04  4:09 ` [PATCH v2 net-next 0/7] net: Eliminate calls to flow_dissector and introduce flow_keys_digest David Miller
  7 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2015-05-01 18:30 UTC (permalink / raw)
  To: davem, netdev

Call make_flow_keys_digest to get a digest from flow keys and
use that to pass skbuff cb and for comparing flows.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 net/sched/sch_choke.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c
index c009eb9..dfe3da7 100644
--- a/net/sched/sch_choke.c
+++ b/net/sched/sch_choke.c
@@ -133,16 +133,10 @@ static void choke_drop_by_idx(struct Qdisc *sch, unsigned int idx)
 	--sch->q.qlen;
 }
 
-/* private part of skb->cb[] that a qdisc is allowed to use
- * is limited to QDISC_CB_PRIV_LEN bytes.
- * As a flow key might be too large, we store a part of it only.
- */
-#define CHOKE_K_LEN min_t(u32, sizeof(struct flow_keys), QDISC_CB_PRIV_LEN - 3)
-
 struct choke_skb_cb {
 	u16			classid;
 	u8			keys_valid;
-	u8			keys[QDISC_CB_PRIV_LEN - 3];
+	struct			flow_keys_digest keys;
 };
 
 static inline struct choke_skb_cb *choke_skb_cb(const struct sk_buff *skb)
@@ -177,18 +171,18 @@ static bool choke_match_flow(struct sk_buff *skb1,
 	if (!choke_skb_cb(skb1)->keys_valid) {
 		choke_skb_cb(skb1)->keys_valid = 1;
 		skb_flow_dissect(skb1, &temp);
-		memcpy(&choke_skb_cb(skb1)->keys, &temp, CHOKE_K_LEN);
+		make_flow_keys_digest(&choke_skb_cb(skb1)->keys, &temp);
 	}
 
 	if (!choke_skb_cb(skb2)->keys_valid) {
 		choke_skb_cb(skb2)->keys_valid = 1;
 		skb_flow_dissect(skb2, &temp);
-		memcpy(&choke_skb_cb(skb2)->keys, &temp, CHOKE_K_LEN);
+		make_flow_keys_digest(&choke_skb_cb(skb2)->keys, &temp);
 	}
 
 	return !memcmp(&choke_skb_cb(skb1)->keys,
 		       &choke_skb_cb(skb2)->keys,
-		       CHOKE_K_LEN);
+		       sizeof(choke_skb_cb(skb1)->keys));
 }
 
 /*
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 net-next 0/7] net: Eliminate calls to flow_dissector and introduce flow_keys_digest
  2015-05-01 18:30 [PATCH v2 net-next 0/7] net: Eliminate calls to flow_dissector and introduce flow_keys_digest Tom Herbert
                   ` (6 preceding siblings ...)
  2015-05-01 18:30 ` [PATCH v2 net-next 7/7] sch_choke: Use flow_keys_digest Tom Herbert
@ 2015-05-04  4:09 ` David Miller
  7 siblings, 0 replies; 9+ messages in thread
From: David Miller @ 2015-05-04  4:09 UTC (permalink / raw)
  To: tom; +Cc: netdev

From: Tom Herbert <tom@herbertland.com>
Date: Fri, 1 May 2015 11:30:11 -0700

> In this patch set we add skb_get_hash_perturb which gets the skbuff
> hash for a packet and perturbs it using a provided key and jhash1.
> This function is used in serveral qdiscs and eliminates many calls
> to flow_dissector and jhash3 to get a perturbed hash for a packet.
> 
> To handle the sch_choke issue (passes flow_keys in skbuff cb) we
> add flow_keys_digest which is a digest of a flow constructed
> from a flow_keys structure.
> 
> This is the second version of these patches I posted a while ago,
> and is prerequisite work to increasing the size of the flow_keys
> structure and hashing over it (full IPv6 address, flow label, VLAN ID,
> etc.).
> 
> Version 2:
> 
> - Add keyval parameter to __flow_hash_from_keys which allows caller to
>   set the initval for jhash
> - Perturb always does flow dissection and creates hash based on
>   input perturb value which acts as the keyval to __flow_hash_from_keys
> - Added a _flow_keys_digest_data which is used in make_flow_keys_digest.
>   This fills out the digest by populating individual fields instead
>   of copying the whole structure.

Series applied, thanks Tom.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-05-04  4:09 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-01 18:30 [PATCH v2 net-next 0/7] net: Eliminate calls to flow_dissector and introduce flow_keys_digest Tom Herbert
2015-05-01 18:30 ` [PATCH v2 net-next 1/7] net: Add skb_get_hash_perturb Tom Herbert
2015-05-01 18:30 ` [PATCH v2 net-next 2/7] sched: Call skb_get_hash_perturb in sch_fq_codel Tom Herbert
2015-05-01 18:30 ` [PATCH v2 net-next 3/7] sched: Call skb_get_hash_perturb in sch_hhf Tom Herbert
2015-05-01 18:30 ` [PATCH v2 net-next 4/7] sched: Call skb_get_hash_perturb in sch_sfb Tom Herbert
2015-05-01 18:30 ` [PATCH v2 net-next 5/7] sched: Call skb_get_hash_perturb in sch_sfq Tom Herbert
2015-05-01 18:30 ` [PATCH v2 net-next 6/7] net: Add flow_keys digest Tom Herbert
2015-05-01 18:30 ` [PATCH v2 net-next 7/7] sch_choke: Use flow_keys_digest Tom Herbert
2015-05-04  4:09 ` [PATCH v2 net-next 0/7] net: Eliminate calls to flow_dissector and introduce flow_keys_digest David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).