Skip to content

Commit 316d4d7

Browse files
Jarno Rajahalmedavem330
authored andcommitted
openvswitch: Pack struct sw_flow_key.
struct sw_flow_key has two 16-bit holes. Move the most matched conntrack match fields there. In some typical cases this reduces the size of the key that needs to be hashed into half and into one cache line. Signed-off-by: Jarno Rajahalme <[email protected]> Acked-by: Joe Stringer <[email protected]> Acked-by: Pravin B Shelar <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent dd41d33 commit 316d4d7

File tree

4 files changed

+39
-34
lines changed

4 files changed

+39
-34
lines changed

net/openvswitch/conntrack.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ static void __ovs_ct_update_key_orig_tp(struct sw_flow_key *key,
152152
const struct nf_conntrack_tuple *orig,
153153
u8 icmp_proto)
154154
{
155-
key->ct.orig_proto = orig->dst.protonum;
155+
key->ct_orig_proto = orig->dst.protonum;
156156
if (orig->dst.protonum == icmp_proto) {
157157
key->ct.orig_tp.src = htons(orig->dst.u.icmp.type);
158158
key->ct.orig_tp.dst = htons(orig->dst.u.icmp.code);
@@ -166,8 +166,8 @@ static void __ovs_ct_update_key(struct sw_flow_key *key, u8 state,
166166
const struct nf_conntrack_zone *zone,
167167
const struct nf_conn *ct)
168168
{
169-
key->ct.state = state;
170-
key->ct.zone = zone->id;
169+
key->ct_state = state;
170+
key->ct_zone = zone->id;
171171
key->ct.mark = ovs_ct_get_mark(ct);
172172
ovs_ct_get_labels(ct, &key->ct.labels);
173173

@@ -195,10 +195,10 @@ static void __ovs_ct_update_key(struct sw_flow_key *key, u8 state,
195195
return;
196196
}
197197
}
198-
/* Clear 'ct.orig_proto' to mark the non-existence of conntrack
198+
/* Clear 'ct_orig_proto' to mark the non-existence of conntrack
199199
* original direction key fields.
200200
*/
201-
key->ct.orig_proto = 0;
201+
key->ct_orig_proto = 0;
202202
}
203203

204204
/* Update 'key' based on skb->_nfct. If 'post_ct' is true, then OVS has
@@ -228,7 +228,7 @@ static void ovs_ct_update_key(const struct sk_buff *skb,
228228
if (ct->master)
229229
state |= OVS_CS_F_RELATED;
230230
if (keep_nat_flags) {
231-
state |= key->ct.state & OVS_CS_F_NAT_MASK;
231+
state |= key->ct_state & OVS_CS_F_NAT_MASK;
232232
} else {
233233
if (ct->status & IPS_SRC_NAT)
234234
state |= OVS_CS_F_SRC_NAT;
@@ -259,11 +259,11 @@ void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key)
259259
int ovs_ct_put_key(const struct sw_flow_key *swkey,
260260
const struct sw_flow_key *output, struct sk_buff *skb)
261261
{
262-
if (nla_put_u32(skb, OVS_KEY_ATTR_CT_STATE, output->ct.state))
262+
if (nla_put_u32(skb, OVS_KEY_ATTR_CT_STATE, output->ct_state))
263263
return -EMSGSIZE;
264264

265265
if (IS_ENABLED(CONFIG_NF_CONNTRACK_ZONES) &&
266-
nla_put_u16(skb, OVS_KEY_ATTR_CT_ZONE, output->ct.zone))
266+
nla_put_u16(skb, OVS_KEY_ATTR_CT_ZONE, output->ct_zone))
267267
return -EMSGSIZE;
268268

269269
if (IS_ENABLED(CONFIG_NF_CONNTRACK_MARK) &&
@@ -275,14 +275,14 @@ int ovs_ct_put_key(const struct sw_flow_key *swkey,
275275
&output->ct.labels))
276276
return -EMSGSIZE;
277277

278-
if (swkey->ct.orig_proto) {
278+
if (swkey->ct_orig_proto) {
279279
if (swkey->eth.type == htons(ETH_P_IP)) {
280280
struct ovs_key_ct_tuple_ipv4 orig = {
281281
output->ipv4.ct_orig.src,
282282
output->ipv4.ct_orig.dst,
283283
output->ct.orig_tp.src,
284284
output->ct.orig_tp.dst,
285-
output->ct.orig_proto,
285+
output->ct_orig_proto,
286286
};
287287
if (nla_put(skb, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4,
288288
sizeof(orig), &orig))
@@ -293,7 +293,7 @@ int ovs_ct_put_key(const struct sw_flow_key *swkey,
293293
IN6_ADDR_INITIALIZER(output->ipv6.ct_orig.dst),
294294
output->ct.orig_tp.src,
295295
output->ct.orig_tp.dst,
296-
output->ct.orig_proto,
296+
output->ct_orig_proto,
297297
};
298298
if (nla_put(skb, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6,
299299
sizeof(orig), &orig))
@@ -612,11 +612,11 @@ static bool skb_nfct_cached(struct net *net,
612612
* due to an upcall. If the connection was not confirmed, it is not
613613
* cached and needs to be run through conntrack again.
614614
*/
615-
if (!ct && key->ct.state & OVS_CS_F_TRACKED &&
616-
!(key->ct.state & OVS_CS_F_INVALID) &&
617-
key->ct.zone == info->zone.id) {
615+
if (!ct && key->ct_state & OVS_CS_F_TRACKED &&
616+
!(key->ct_state & OVS_CS_F_INVALID) &&
617+
key->ct_zone == info->zone.id) {
618618
ct = ovs_ct_find_existing(net, &info->zone, info->family, skb,
619-
!!(key->ct.state
619+
!!(key->ct_state
620620
& OVS_CS_F_NAT_MASK));
621621
if (ct)
622622
nf_ct_get(skb, &ctinfo);
@@ -740,7 +740,7 @@ static void ovs_nat_update_key(struct sw_flow_key *key,
740740
if (maniptype == NF_NAT_MANIP_SRC) {
741741
__be16 src;
742742

743-
key->ct.state |= OVS_CS_F_SRC_NAT;
743+
key->ct_state |= OVS_CS_F_SRC_NAT;
744744
if (key->eth.type == htons(ETH_P_IP))
745745
key->ipv4.addr.src = ip_hdr(skb)->saddr;
746746
else if (key->eth.type == htons(ETH_P_IPV6))
@@ -762,7 +762,7 @@ static void ovs_nat_update_key(struct sw_flow_key *key,
762762
} else {
763763
__be16 dst;
764764

765-
key->ct.state |= OVS_CS_F_DST_NAT;
765+
key->ct_state |= OVS_CS_F_DST_NAT;
766766
if (key->eth.type == htons(ETH_P_IP))
767767
key->ipv4.addr.dst = ip_hdr(skb)->daddr;
768768
else if (key->eth.type == htons(ETH_P_IPV6))
@@ -886,7 +886,7 @@ static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
886886
* NAT after the nf_conntrack_in() call. We can actually clear
887887
* the whole state, as it will be re-initialized below.
888888
*/
889-
key->ct.state = 0;
889+
key->ct_state = 0;
890890

891891
/* Update the key, but keep the NAT flags. */
892892
ovs_ct_update_key(skb, info, key, true, true);
@@ -902,9 +902,9 @@ static int __ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
902902
*
903903
* NAT will be done only if the CT action has NAT, and only
904904
* once per packet (per zone), as guarded by the NAT bits in
905-
* the key->ct.state.
905+
* the key->ct_state.
906906
*/
907-
if (info->nat && !(key->ct.state & OVS_CS_F_NAT_MASK) &&
907+
if (info->nat && !(key->ct_state & OVS_CS_F_NAT_MASK) &&
908908
(nf_ct_is_confirmed(ct) || info->commit) &&
909909
ovs_ct_nat(net, key, info, skb, ct, ctinfo) != NF_ACCEPT) {
910910
return -EINVAL;

net/openvswitch/conntrack.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,14 @@ static inline int ovs_ct_execute(struct net *net, struct sk_buff *skb,
7676
static inline void ovs_ct_fill_key(const struct sk_buff *skb,
7777
struct sw_flow_key *key)
7878
{
79-
key->ct.state = 0;
80-
key->ct.zone = 0;
79+
key->ct_state = 0;
80+
key->ct_zone = 0;
8181
key->ct.mark = 0;
8282
memset(&key->ct.labels, 0, sizeof(key->ct.labels));
83-
/* Clear 'ct.orig_proto' to mark the non-existence of original
83+
/* Clear 'ct_orig_proto' to mark the non-existence of original
8484
* direction key fields.
8585
*/
86-
key->ct.orig_proto = 0;
86+
key->ct_orig_proto = 0;
8787
}
8888

8989
static inline int ovs_ct_put_key(const struct sw_flow_key *swkey,

net/openvswitch/flow.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ struct sw_flow_key {
8585
struct vlan_head cvlan;
8686
__be16 type; /* Ethernet frame type. */
8787
} eth;
88+
/* Filling a hole of two bytes. */
89+
u8 ct_state;
90+
u8 ct_orig_proto; /* CT original direction tuple IP
91+
* protocol.
92+
*/
8893
union {
8994
struct {
9095
__be32 top_lse; /* top label stack entry */
@@ -96,6 +101,7 @@ struct sw_flow_key {
96101
u8 frag; /* One of OVS_FRAG_TYPE_*. */
97102
} ip;
98103
};
104+
u16 ct_zone; /* Conntrack zone. */
99105
struct {
100106
__be16 src; /* TCP/UDP/SCTP source port. */
101107
__be16 dst; /* TCP/UDP/SCTP destination port. */
@@ -138,16 +144,12 @@ struct sw_flow_key {
138144
} ipv6;
139145
};
140146
struct {
141-
/* Connection tracking fields. */
142-
u8 state;
143-
u8 orig_proto; /* CT orig tuple IP protocol. */
144-
u16 zone;
145-
u32 mark;
147+
/* Connection tracking fields not packed above. */
146148
struct {
147149
__be16 src; /* CT orig tuple tp src port. */
148150
__be16 dst; /* CT orig tuple tp dst port. */
149151
} orig_tp;
150-
152+
u32 mark;
151153
struct ovs_key_ct_labels labels;
152154
} ct;
153155

net/openvswitch/flow_netlink.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,14 +1072,14 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
10721072
return -EINVAL;
10731073
}
10741074

1075-
SW_FLOW_KEY_PUT(match, ct.state, ct_state, is_mask);
1075+
SW_FLOW_KEY_PUT(match, ct_state, ct_state, is_mask);
10761076
*attrs &= ~(1ULL << OVS_KEY_ATTR_CT_STATE);
10771077
}
10781078
if (*attrs & (1 << OVS_KEY_ATTR_CT_ZONE) &&
10791079
ovs_ct_verify(net, OVS_KEY_ATTR_CT_ZONE)) {
10801080
u16 ct_zone = nla_get_u16(a[OVS_KEY_ATTR_CT_ZONE]);
10811081

1082-
SW_FLOW_KEY_PUT(match, ct.zone, ct_zone, is_mask);
1082+
SW_FLOW_KEY_PUT(match, ct_zone, ct_zone, is_mask);
10831083
*attrs &= ~(1ULL << OVS_KEY_ATTR_CT_ZONE);
10841084
}
10851085
if (*attrs & (1 << OVS_KEY_ATTR_CT_MARK) &&
@@ -1107,7 +1107,7 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
11071107
SW_FLOW_KEY_PUT(match, ipv4.ct_orig.dst, ct->ipv4_dst, is_mask);
11081108
SW_FLOW_KEY_PUT(match, ct.orig_tp.src, ct->src_port, is_mask);
11091109
SW_FLOW_KEY_PUT(match, ct.orig_tp.dst, ct->dst_port, is_mask);
1110-
SW_FLOW_KEY_PUT(match, ct.orig_proto, ct->ipv4_proto, is_mask);
1110+
SW_FLOW_KEY_PUT(match, ct_orig_proto, ct->ipv4_proto, is_mask);
11111111
*attrs &= ~(1ULL << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4);
11121112
}
11131113
if (*attrs & (1ULL << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6)) {
@@ -1123,7 +1123,7 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
11231123
is_mask);
11241124
SW_FLOW_KEY_PUT(match, ct.orig_tp.src, ct->src_port, is_mask);
11251125
SW_FLOW_KEY_PUT(match, ct.orig_tp.dst, ct->dst_port, is_mask);
1126-
SW_FLOW_KEY_PUT(match, ct.orig_proto, ct->ipv6_proto, is_mask);
1126+
SW_FLOW_KEY_PUT(match, ct_orig_proto, ct->ipv6_proto, is_mask);
11271127
*attrs &= ~(1ULL << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6);
11281128
}
11291129

@@ -1564,6 +1564,9 @@ int ovs_nla_get_flow_metadata(struct net *net,
15641564
memset(&match, 0, sizeof(match));
15651565
match.key = key;
15661566

1567+
key->ct_state = 0;
1568+
key->ct_zone = 0;
1569+
key->ct_orig_proto = 0;
15671570
memset(&key->ct, 0, sizeof(key->ct));
15681571
memset(&key->ipv4.ct_orig, 0, sizeof(key->ipv4.ct_orig));
15691572
memset(&key->ipv6.ct_orig, 0, sizeof(key->ipv6.ct_orig));

0 commit comments

Comments
 (0)