summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorAndy Zhou <azhou@nicira.com>2014-09-08 11:35:02 +0400
committerPravin B Shelar <pshelar@nicira.com>2014-11-06 10:52:34 +0300
commit738967b8bf57e582db1a23ce773c36fefd4b7d37 (patch)
treeb8a6a56e9eaa280fc10371002bb6d8fef790ab04 /net
parent426cda5cc177301f9c196f3a9b6a1287051ba599 (diff)
downloadlinux-738967b8bf57e582db1a23ce773c36fefd4b7d37.tar.xz
openvswitch: refactor do_output() to move NULL check out of fast path
skb_clone() NULL check is implemented in do_output(), as past of the common (fast) path. Refactoring so that NULL check is done in the slow path, immediately after skb_clone() is called. Besides optimization, this change also improves code readability by making the skb_clone() NULL check consistent within OVS datapath module. Signed-off-by: Andy Zhou <azhou@nicira.com> Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Diffstat (limited to 'net')
-rw-r--r--net/openvswitch/actions.c25
1 files changed, 11 insertions, 14 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index 930b1b6e4cef..9fd33c0bf173 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -551,21 +551,14 @@ static int set_sctp(struct sk_buff *skb,
return 0;
}
-static int do_output(struct datapath *dp, struct sk_buff *skb, int out_port)
+static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port)
{
- struct vport *vport;
+ struct vport *vport = ovs_vport_rcu(dp, out_port);
- if (unlikely(!skb))
- return -ENOMEM;
-
- vport = ovs_vport_rcu(dp, out_port);
- if (unlikely(!vport)) {
+ if (likely(vport))
+ ovs_vport_send(vport, skb);
+ else
kfree_skb(skb);
- return -ENODEV;
- }
-
- ovs_vport_send(vport, skb);
- return 0;
}
static int output_userspace(struct datapath *dp, struct sk_buff *skb,
@@ -768,8 +761,12 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
a = nla_next(a, &rem)) {
int err = 0;
- if (prev_port != -1) {
- do_output(dp, skb_clone(skb, GFP_ATOMIC), prev_port);
+ if (unlikely(prev_port != -1)) {
+ struct sk_buff *out_skb = skb_clone(skb, GFP_ATOMIC);
+
+ if (out_skb)
+ do_output(dp, out_skb, prev_port);
+
prev_port = -1;
}