Skip to content

Commit e8eedb8

Browse files
author
Pravin B Shelar
committed
openvswitch: Remove redundant key ref from upcall_info.
struct dp_upcall_info has pointer to pkt_key which is already available in OVS_CB. This also simplifies upcall handling for gso packet. Signed-off-by: Pravin B Shelar <[email protected]> Acked-by: Andy Zhou <[email protected]>
1 parent fff06c3 commit e8eedb8

File tree

3 files changed

+32
-28
lines changed

3 files changed

+32
-28
lines changed

net/openvswitch/actions.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,6 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
624624
int rem;
625625

626626
upcall.cmd = OVS_PACKET_CMD_ACTION;
627-
upcall.key = key;
628627
upcall.userdata = NULL;
629628
upcall.portid = 0;
630629
upcall.egress_tun_info = NULL;
@@ -659,7 +658,7 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
659658
} /* End of switch. */
660659
}
661660

662-
return ovs_dp_upcall(dp, skb, &upcall);
661+
return ovs_dp_upcall(dp, skb, key, &upcall);
663662
}
664663

665664
static int sample(struct datapath *dp, struct sk_buff *skb,

net/openvswitch/datapath.c

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,10 @@ EXPORT_SYMBOL_GPL(lockdep_ovsl_is_held);
136136

137137
static struct vport *new_vport(const struct vport_parms *);
138138
static int queue_gso_packets(struct datapath *dp, struct sk_buff *,
139+
const struct sw_flow_key *,
139140
const struct dp_upcall_info *);
140141
static int queue_userspace_packet(struct datapath *dp, struct sk_buff *,
142+
const struct sw_flow_key *,
141143
const struct dp_upcall_info *);
142144

143145
/* Must be called with rcu_read_lock. */
@@ -271,11 +273,10 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
271273
int error;
272274

273275
upcall.cmd = OVS_PACKET_CMD_MISS;
274-
upcall.key = key;
275276
upcall.userdata = NULL;
276277
upcall.portid = ovs_vport_find_upcall_portid(p, skb);
277278
upcall.egress_tun_info = NULL;
278-
error = ovs_dp_upcall(dp, skb, &upcall);
279+
error = ovs_dp_upcall(dp, skb, key, &upcall);
279280
if (unlikely(error))
280281
kfree_skb(skb);
281282
else
@@ -299,6 +300,7 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
299300
}
300301

301302
int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
303+
const struct sw_flow_key *key,
302304
const struct dp_upcall_info *upcall_info)
303305
{
304306
struct dp_stats_percpu *stats;
@@ -310,9 +312,9 @@ int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
310312
}
311313

312314
if (!skb_is_gso(skb))
313-
err = queue_userspace_packet(dp, skb, upcall_info);
315+
err = queue_userspace_packet(dp, skb, key, upcall_info);
314316
else
315-
err = queue_gso_packets(dp, skb, upcall_info);
317+
err = queue_gso_packets(dp, skb, key, upcall_info);
316318
if (err)
317319
goto err;
318320

@@ -329,39 +331,43 @@ int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
329331
}
330332

331333
static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb,
334+
const struct sw_flow_key *key,
332335
const struct dp_upcall_info *upcall_info)
333336
{
334337
unsigned short gso_type = skb_shinfo(skb)->gso_type;
335-
struct dp_upcall_info later_info;
336338
struct sw_flow_key later_key;
337339
struct sk_buff *segs, *nskb;
340+
struct ovs_skb_cb ovs_cb;
338341
int err;
339342

343+
ovs_cb = *OVS_CB(skb);
340344
segs = __skb_gso_segment(skb, NETIF_F_SG, false);
345+
*OVS_CB(skb) = ovs_cb;
341346
if (IS_ERR(segs))
342347
return PTR_ERR(segs);
343348
if (segs == NULL)
344349
return -EINVAL;
345350

351+
if (gso_type & SKB_GSO_UDP) {
352+
/* The initial flow key extracted by ovs_flow_key_extract()
353+
* in this case is for a first fragment, so we need to
354+
* properly mark later fragments.
355+
*/
356+
later_key = *key;
357+
later_key.ip.frag = OVS_FRAG_TYPE_LATER;
358+
}
359+
346360
/* Queue all of the segments. */
347361
skb = segs;
348362
do {
349-
err = queue_userspace_packet(dp, skb, upcall_info);
363+
*OVS_CB(skb) = ovs_cb;
364+
if (gso_type & SKB_GSO_UDP && skb != segs)
365+
key = &later_key;
366+
367+
err = queue_userspace_packet(dp, skb, key, upcall_info);
350368
if (err)
351369
break;
352370

353-
if (skb == segs && gso_type & SKB_GSO_UDP) {
354-
/* The initial flow key extracted by ovs_flow_extract()
355-
* in this case is for a first fragment, so we need to
356-
* properly mark later fragments.
357-
*/
358-
later_key = *upcall_info->key;
359-
later_key.ip.frag = OVS_FRAG_TYPE_LATER;
360-
361-
later_info = *upcall_info;
362-
later_info.key = &later_key;
363-
upcall_info = &later_info;
364-
}
365371
} while ((skb = skb->next));
366372

367373
/* Free all of the segments. */
@@ -395,6 +401,7 @@ static size_t upcall_msg_size(const struct dp_upcall_info *upcall_info,
395401
}
396402

397403
static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
404+
const struct sw_flow_key *key,
398405
const struct dp_upcall_info *upcall_info)
399406
{
400407
struct ovs_header *upcall;
@@ -457,7 +464,7 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
457464
upcall->dp_ifindex = dp_ifindex;
458465

459466
nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY);
460-
err = ovs_nla_put_flow(upcall_info->key, upcall_info->key, user_skb);
467+
err = ovs_nla_put_flow(key, key, user_skb);
461468
BUG_ON(err);
462469
nla_nest_end(user_skb, nla);
463470

net/openvswitch/datapath.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,20 +108,18 @@ struct ovs_skb_cb {
108108
/**
109109
* struct dp_upcall - metadata to include with a packet to send to userspace
110110
* @cmd: One of %OVS_PACKET_CMD_*.
111-
* @key: Becomes %OVS_PACKET_ATTR_KEY. Must be nonnull.
112111
* @userdata: If nonnull, its variable-length value is passed to userspace as
113112
* %OVS_PACKET_ATTR_USERDATA.
114-
* @pid: Netlink PID to which packet should be sent. If @pid is 0 then no
115-
* packet is sent and the packet is accounted in the datapath's @n_lost
113+
* @portid: Netlink portid to which packet should be sent. If @portid is 0
114+
* then no packet is sent and the packet is accounted in the datapath's @n_lost
116115
* counter.
117116
* @egress_tun_info: If nonnull, becomes %OVS_PACKET_ATTR_EGRESS_TUN_KEY.
118117
*/
119118
struct dp_upcall_info {
120-
u8 cmd;
121-
const struct sw_flow_key *key;
119+
const struct ovs_tunnel_info *egress_tun_info;
122120
const struct nlattr *userdata;
123121
u32 portid;
124-
const struct ovs_tunnel_info *egress_tun_info;
122+
u8 cmd;
125123
};
126124

127125
/**
@@ -187,7 +185,7 @@ extern struct genl_family dp_vport_genl_family;
187185
void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key);
188186
void ovs_dp_detach_port(struct vport *);
189187
int ovs_dp_upcall(struct datapath *, struct sk_buff *,
190-
const struct dp_upcall_info *);
188+
const struct sw_flow_key *, const struct dp_upcall_info *);
191189

192190
const char *ovs_dp_name(const struct datapath *dp);
193191
struct sk_buff *ovs_vport_cmd_build_info(struct vport *, u32 pid, u32 seq,

0 commit comments

Comments
 (0)