aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Herbert <therbert@google.com>2014-07-02 00:33:17 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-08 00:14:21 -0400
commita3b18ddb9cc1056eea24e3edc1828cfb3fd0726f (patch)
tree5100dd399922df55b29a1acf2b5a4dcc332c10b4
parentcb1ce2ef387b01686469487edd45994872d52d73 (diff)
net: Only do flow_dissector hash computation once per packet
Add sw_hash flag to skbuff to indicate that skb->hash was computed from flow_dissector. This flag is checked in skb_get_hash to avoid repeatedly trying to compute the hash (ie. in the case that no L4 hash can be computed). Signed-off-by: Tom Herbert <therbert@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/skbuff.h9
-rw-r--r--net/core/flow_dissector.c2
2 files changed, 9 insertions, 2 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index b297af70ac30..890fb3307dd6 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -455,6 +455,7 @@ static inline u32 skb_mstamp_us_delta(const struct skb_mstamp *t1,
455 * @ooo_okay: allow the mapping of a socket to a queue to be changed 455 * @ooo_okay: allow the mapping of a socket to a queue to be changed
456 * @l4_hash: indicate hash is a canonical 4-tuple hash over transport 456 * @l4_hash: indicate hash is a canonical 4-tuple hash over transport
457 * ports. 457 * ports.
458 * @sw_hash: indicates hash was computed in software stack
458 * @wifi_acked_valid: wifi_acked was set 459 * @wifi_acked_valid: wifi_acked was set
459 * @wifi_acked: whether frame was acked on wifi or not 460 * @wifi_acked: whether frame was acked on wifi or not
460 * @no_fcs: Request NIC to treat last 4 bytes as Ethernet FCS 461 * @no_fcs: Request NIC to treat last 4 bytes as Ethernet FCS
@@ -562,6 +563,7 @@ struct sk_buff {
562 __u8 pfmemalloc:1; 563 __u8 pfmemalloc:1;
563 __u8 ooo_okay:1; 564 __u8 ooo_okay:1;
564 __u8 l4_hash:1; 565 __u8 l4_hash:1;
566 __u8 sw_hash:1;
565 __u8 wifi_acked_valid:1; 567 __u8 wifi_acked_valid:1;
566 __u8 wifi_acked:1; 568 __u8 wifi_acked:1;
567 __u8 no_fcs:1; 569 __u8 no_fcs:1;
@@ -575,7 +577,7 @@ struct sk_buff {
575 __u8 encap_hdr_csum:1; 577 __u8 encap_hdr_csum:1;
576 __u8 csum_valid:1; 578 __u8 csum_valid:1;
577 __u8 csum_complete_sw:1; 579 __u8 csum_complete_sw:1;
578 /* 3/5 bit hole (depending on ndisc_nodetype presence) */ 580 /* 2/4 bit hole (depending on ndisc_nodetype presence) */
579 kmemcheck_bitfield_end(flags2); 581 kmemcheck_bitfield_end(flags2);
580 582
581#if defined CONFIG_NET_DMA || defined CONFIG_NET_RX_BUSY_POLL 583#if defined CONFIG_NET_DMA || defined CONFIG_NET_RX_BUSY_POLL
@@ -830,13 +832,14 @@ static inline void
830skb_set_hash(struct sk_buff *skb, __u32 hash, enum pkt_hash_types type) 832skb_set_hash(struct sk_buff *skb, __u32 hash, enum pkt_hash_types type)
831{ 833{
832 skb->l4_hash = (type == PKT_HASH_TYPE_L4); 834 skb->l4_hash = (type == PKT_HASH_TYPE_L4);
835 skb->sw_hash = 0;
833 skb->hash = hash; 836 skb->hash = hash;
834} 837}
835 838
836void __skb_get_hash(struct sk_buff *skb); 839void __skb_get_hash(struct sk_buff *skb);
837static inline __u32 skb_get_hash(struct sk_buff *skb) 840static inline __u32 skb_get_hash(struct sk_buff *skb)
838{ 841{
839 if (!skb->l4_hash) 842 if (!skb->l4_hash && !skb->sw_hash)
840 __skb_get_hash(skb); 843 __skb_get_hash(skb);
841 844
842 return skb->hash; 845 return skb->hash;
@@ -850,6 +853,7 @@ static inline __u32 skb_get_hash_raw(const struct sk_buff *skb)
850static inline void skb_clear_hash(struct sk_buff *skb) 853static inline void skb_clear_hash(struct sk_buff *skb)
851{ 854{
852 skb->hash = 0; 855 skb->hash = 0;
856 skb->sw_hash = 0;
853 skb->l4_hash = 0; 857 skb->l4_hash = 0;
854} 858}
855 859
@@ -862,6 +866,7 @@ static inline void skb_clear_hash_if_not_l4(struct sk_buff *skb)
862static inline void skb_copy_hash(struct sk_buff *to, const struct sk_buff *from) 866static inline void skb_copy_hash(struct sk_buff *to, const struct sk_buff *from)
863{ 867{
864 to->hash = from->hash; 868 to->hash = from->hash;
869 to->sw_hash = from->sw_hash;
865 to->l4_hash = from->l4_hash; 870 to->l4_hash = from->l4_hash;
866}; 871};
867 872
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index c5f3912dad4c..5f362c1d0332 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -256,6 +256,8 @@ void __skb_get_hash(struct sk_buff *skb)
256 if (keys.ports) 256 if (keys.ports)
257 skb->l4_hash = 1; 257 skb->l4_hash = 1;
258 258
259 skb->sw_hash = 1;
260
259 skb->hash = __flow_hash_from_keys(&keys); 261 skb->hash = __flow_hash_from_keys(&keys);
260} 262}
261EXPORT_SYMBOL(__skb_get_hash); 263EXPORT_SYMBOL(__skb_get_hash);