[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH net-next v1 1/8] skbuff: store hash type in socket buffer...
> -----Original Message----- > From: Tom Herbert [mailto:tom@xxxxxxxxxxxxxxx] > Sent: 14 February 2016 22:25 > To: Paul Durrant > Cc: Linux Kernel Network Developers; xen-devel@xxxxxxxxxxxxxxxxxxxx; David > S. Miller; Jay Vosburgh; Veaceslav Falico; Andy Gospodarek > Subject: Re: [PATCH net-next v1 1/8] skbuff: store hash type in socket > buffer... > > On Fri, Feb 12, 2016 at 11:13 AM, Paul Durrant <paul.durrant@xxxxxxxxxx> > wrote: > > ...rather than a boolean merely indicating a canonical L4 hash. > > > > skb_set_hash() takes a hash type (from enum pkt_hash_types) as an > > argument but information is lost since only a single bit in the skb > > stores whether that hash type is PKT_HASH_TYPE_L4 or not. > > > > By using two bits it's possible to store the complete hash type > > information for use by drivers. A subsequent patch to xen-netback > > needs this information to forward packet hashes to VM frontend drivers. > > > > Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> > > Cc: "David S. Miller" <davem@xxxxxxxxxxxxx> > > Cc: Jay Vosburgh <j.vosburgh@xxxxxxxxx> > > Cc: Veaceslav Falico <vfalico@xxxxxxxxx> > > Cc: Andy Gospodarek <gospo@xxxxxxxxxxxxxxxxxxx> > > --- > > drivers/net/bonding/bond_main.c | 2 +- > > include/linux/skbuff.h | 53 ++++++++++++++++++++++++++++------- > ------ > > include/net/flow_dissector.h | 5 ++++ > > include/net/sock.h | 2 +- > > include/trace/events/net.h | 2 +- > > net/core/flow_dissector.c | 27 ++++++++++++++++----- > > 6 files changed, 65 insertions(+), 26 deletions(-) > > > > diff --git a/drivers/net/bonding/bond_main.c > b/drivers/net/bonding/bond_main.c > > index 45bdd87..ad0ee00 100644 > > --- a/drivers/net/bonding/bond_main.c > > +++ b/drivers/net/bonding/bond_main.c > > @@ -3173,7 +3173,7 @@ u32 bond_xmit_hash(struct bonding *bond, > struct sk_buff *skb) > > u32 hash; > > > > if (bond->params.xmit_policy == BOND_XMIT_POLICY_ENCAP34 && > > - skb->l4_hash) > > + skb_has_l4_hash(skb)) > > return skb->hash; > > > > if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER2 || > > diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h > > index 6ec86f1..9021b52 100644 > > --- a/include/linux/skbuff.h > > +++ b/include/linux/skbuff.h > > @@ -595,8 +595,7 @@ static inline bool skb_mstamp_after(const struct > skb_mstamp *t1, > > * @xmit_more: More SKBs are pending for this queue > > * @ndisc_nodetype: router type (from link layer) > > * @ooo_okay: allow the mapping of a socket to a queue to be changed > > - * @l4_hash: indicate hash is a canonical 4-tuple hash over transport > > - * ports. > > + * @hash_type: indicates type of hash (see enum pkt_hash_types > below) > > * @sw_hash: indicates hash was computed in software stack > > * @wifi_acked_valid: wifi_acked was set > > * @wifi_acked: whether frame was acked on wifi or not > > @@ -701,10 +700,10 @@ struct sk_buff { > > __u8 nf_trace:1; > > __u8 ip_summed:2; > > __u8 ooo_okay:1; > > - __u8 l4_hash:1; > > __u8 sw_hash:1; > > __u8 wifi_acked_valid:1; > > __u8 wifi_acked:1; > > + /* 1 bit hole */ > > > > __u8 no_fcs:1; > > /* Indicates the inner headers are valid in the skbuff. */ > > @@ -721,7 +720,8 @@ struct sk_buff { > > __u8 ipvs_property:1; > > __u8 inner_protocol_type:1; > > __u8 remcsum_offload:1; > > - /* 3 or 5 bit hole */ > > + __u8 hash_type:2; > > This isn't needed by the stack-- we don't differentiate between L2 and > L3 hash anywhere. Also it doesn't help in the xen case for passing a > hash to Windows without having another bit to indicate that the hash > is indeed Toeplitz. > I hadn't read this before I split the patch and re-posted... Given that the header defines an enum for hash types that *does* distinguish between L2 and L3 I find this confusing. Shouldn't that enum be removed if no-one cares? Paul > > + /* 1 or 3 bit hole */ > > > > #ifdef CONFIG_NET_SCHED > > __u16 tc_index; /* traffic control index */ > > @@ -1030,19 +1030,35 @@ static inline void skb_clear_hash(struct sk_buff > *skb) > > { > > skb->hash = 0; > > skb->sw_hash = 0; > > - skb->l4_hash = 0; > > + skb->hash_type = 0; > > +} > > + > > +static inline enum pkt_hash_types skb_hash_type(struct sk_buff *skb) > > +{ > > + return skb->hash_type; > > +} > > + > > +static inline bool skb_has_l4_hash(struct sk_buff *skb) > > +{ > > + return skb_hash_type(skb) == PKT_HASH_TYPE_L4; > > +} > > + > > +static inline bool skb_has_sw_hash(struct sk_buff *skb) > > +{ > > + return !!skb->sw_hash; > > } > > > > static inline void skb_clear_hash_if_not_l4(struct sk_buff *skb) > > { > > - if (!skb->l4_hash) > > + if (!skb_has_l4_hash(skb)) > > skb_clear_hash(skb); > > } > > > > static inline void > > -__skb_set_hash(struct sk_buff *skb, __u32 hash, bool is_sw, bool is_l4) > > +__skb_set_hash(struct sk_buff *skb, __u32 hash, bool is_sw, > > + enum pkt_hash_types type) > > { > > - skb->l4_hash = is_l4; > > + skb->hash_type = type; > > skb->sw_hash = is_sw; > > skb->hash = hash; > > } > > @@ -1051,13 +1067,13 @@ static inline void > > skb_set_hash(struct sk_buff *skb, __u32 hash, enum pkt_hash_types > type) > > { > > /* Used by drivers to set hash from HW */ > > - __skb_set_hash(skb, hash, false, type == PKT_HASH_TYPE_L4); > > + __skb_set_hash(skb, hash, false, type); > > } > > > > static inline void > > -__skb_set_sw_hash(struct sk_buff *skb, __u32 hash, bool is_l4) > > +__skb_set_sw_hash(struct sk_buff *skb, __u32 hash, enum > pkt_hash_types type) > > { > > - __skb_set_hash(skb, hash, true, is_l4); > > + __skb_set_hash(skb, hash, true, type); > > } > > > > void __skb_get_hash(struct sk_buff *skb); > > @@ -1110,9 +1126,10 @@ static inline bool > skb_flow_dissect_flow_keys_buf(struct flow_keys *flow, > > data, proto, nhoff, hlen, flags); > > } > > > > + > > Extra line > > > static inline __u32 skb_get_hash(struct sk_buff *skb) > > { > > - if (!skb->l4_hash && !skb->sw_hash) > > + if (!skb_has_l4_hash(skb) && !skb_has_sw_hash(skb)) > > __skb_get_hash(skb); > > > > return skb->hash; > > @@ -1122,11 +1139,12 @@ __u32 __skb_get_hash_flowi6(struct sk_buff > *skb, const struct flowi6 *fl6); > > > > static inline __u32 skb_get_hash_flowi6(struct sk_buff *skb, const struct > flowi6 *fl6) > > { > > - if (!skb->l4_hash && !skb->sw_hash) { > > + if (!skb_has_l4_hash(skb) && !skb_has_sw_hash(skb)) { > > struct flow_keys keys; > > __u32 hash = __get_hash_from_flowi6(fl6, &keys); > > > > - __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys)); > > + __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys) ? > > + PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3); > > } > > > > return skb->hash; > > @@ -1136,11 +1154,12 @@ __u32 __skb_get_hash_flowi4(struct sk_buff > *skb, const struct flowi4 *fl); > > > > static inline __u32 skb_get_hash_flowi4(struct sk_buff *skb, const struct > flowi4 *fl4) > > { > > - if (!skb->l4_hash && !skb->sw_hash) { > > + if (!skb_has_l4_hash(skb) && !skb_has_sw_hash(skb)) { > > struct flow_keys keys; > > __u32 hash = __get_hash_from_flowi4(fl4, &keys); > > > > - __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys)); > > + __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys) ? > > + PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3); > > } > > > > return skb->hash; > > @@ -1157,7 +1176,7 @@ static inline void skb_copy_hash(struct sk_buff > *to, const struct sk_buff *from) > > { > > to->hash = from->hash; > > to->sw_hash = from->sw_hash; > > - to->l4_hash = from->l4_hash; > > + to->hash_type = from->hash_type; > > }; > > > > static inline void skb_sender_cpu_clear(struct sk_buff *skb) > > diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h > > index 8c8548c..418b8c5 100644 > > --- a/include/net/flow_dissector.h > > +++ b/include/net/flow_dissector.h > > @@ -182,6 +182,11 @@ static inline bool flow_keys_have_l4(struct > flow_keys *keys) > > return (keys->ports.ports || keys->tags.flow_label); > > } > > > > +static inline bool flow_keys_have_l3(struct flow_keys *keys) > > +{ > > + return !!keys->control.addr_type; > > +} > > + > > u32 flow_hash_from_keys(struct flow_keys *keys); > > > > #endif > > diff --git a/include/net/sock.h b/include/net/sock.h > > index 255d3e0..21b8cdc 100644 > > --- a/include/net/sock.h > > +++ b/include/net/sock.h > > @@ -1828,7 +1828,7 @@ static inline void sock_poll_wait(struct file *filp, > > static inline void skb_set_hash_from_sk(struct sk_buff *skb, struct sock > *sk) > > { > > if (sk->sk_txhash) { > > - skb->l4_hash = 1; > > + skb->hash_type = PKT_HASH_TYPE_L4; > > skb->hash = sk->sk_txhash; > > } > > } > > diff --git a/include/trace/events/net.h b/include/trace/events/net.h > > index 49cc7c3..25e7979 100644 > > --- a/include/trace/events/net.h > > +++ b/include/trace/events/net.h > > @@ -180,7 +180,7 @@ > DECLARE_EVENT_CLASS(net_dev_rx_verbose_template, > > __entry->protocol = ntohs(skb->protocol); > > __entry->ip_summed = skb->ip_summed; > > __entry->hash = skb->hash; > > - __entry->l4_hash = skb->l4_hash; > > + __entry->l4_hash = skb->hash_type == PKT_HASH_TYPE_L4; > > __entry->len = skb->len; > > __entry->data_len = skb->data_len; > > __entry->truesize = skb->truesize; > > diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c > > index d79699c..956208b 100644 > > --- a/net/core/flow_dissector.c > > +++ b/net/core/flow_dissector.c > > @@ -658,17 +658,30 @@ EXPORT_SYMBOL(make_flow_keys_digest); > > * > > * This function calculates a flow hash based on src/dst addresses > > * and src/dst port numbers. Sets hash in skb to non-zero hash value > > - * on success, zero indicates no valid hash. Also, sets l4_hash in skb > > - * if hash is a canonical 4-tuple hash over transport ports. > > + * on success, zero indicates no valid hash in which case the hash type > > + * is set to NONE. If the hash is a canonical 4-tuple hash over transport > > + * ports then type is set to L4. If the hash did not include transport > > + * then type is set to L3, otherwise it is assumed to be L2 only. > > */ > > void __skb_get_hash(struct sk_buff *skb) > > { > > struct flow_keys keys; > > + u32 hash; > > + enum pkt_hash_types type; > > > > __flow_hash_secret_init(); > > > > - __skb_set_sw_hash(skb, ___skb_get_hash(skb, &keys, hashrnd), > > - flow_keys_have_l4(&keys)); > > + hash = ___skb_get_hash(skb, &keys, hashrnd); > > + if (hash == 0) > > + type = PKT_HASH_TYPE_NONE; > > + else if (flow_keys_have_l4(&keys)) > > + type = PKT_HASH_TYPE_L4; > > + else if (flow_keys_have_l3(&keys)) > > + type = PKT_HASH_TYPE_L3; > > + else > > + type = PKT_HASH_TYPE_L2; > > + > > + __skb_set_sw_hash(skb, hash, type); > > } > > EXPORT_SYMBOL(__skb_get_hash); > > > > @@ -698,7 +711,8 @@ __u32 __skb_get_hash_flowi6(struct sk_buff *skb, > const struct flowi6 *fl6) > > keys.basic.ip_proto = fl6->flowi6_proto; > > > > __skb_set_sw_hash(skb, flow_hash_from_keys(&keys), > > - flow_keys_have_l4(&keys)); > > + flow_keys_have_l4(&keys) ? > > + PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3); > > > > return skb->hash; > > } > > @@ -719,7 +733,8 @@ __u32 __skb_get_hash_flowi4(struct sk_buff *skb, > const struct flowi4 *fl4) > > keys.basic.ip_proto = fl4->flowi4_proto; > > > > __skb_set_sw_hash(skb, flow_hash_from_keys(&keys), > > - flow_keys_have_l4(&keys)); > > + flow_keys_have_l4(&keys) ? > > + PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3); > > > > return skb->hash; > > } > > -- > > 2.1.4 > > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |