[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1489532891-33497-5-git-send-email-azhou@ovn.org>
Date: Tue, 14 Mar 2017 16:08:11 -0700
From: Andy Zhou <azhou@....org>
To: netdev@...r.kernel.org
Cc: joe@....org, pshelar@....org, Andy Zhou <azhou@....org>
Subject: [net-next sample action optimization v2 4/4] Openvswitch: Refactor sample and recirc actions implementation
Added execute_or_defer_actions() that both sample and recirc
action's implementation can use.
Signed-off-by: Andy Zhou <azhou@....org>
---
net/openvswitch/actions.c | 96 +++++++++++++++++++++++++++++------------------
1 file changed, 59 insertions(+), 37 deletions(-)
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index 1638370..fd7d903 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -44,10 +44,6 @@
#include "conntrack.h"
#include "vport.h"
-static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
- struct sw_flow_key *key,
- const struct nlattr *attr, int len);
-
struct deferred_action {
struct sk_buff *skb;
const struct nlattr *actions;
@@ -166,6 +162,12 @@ static bool is_flow_key_valid(const struct sw_flow_key *key)
return !(key->mac_proto & SW_FLOW_KEY_INVALID);
}
+static int execute_or_defer_actions(struct datapath *dp, struct sk_buff *skb,
+ struct sw_flow_key *clone,
+ struct sw_flow_key *key,
+ u32 *recirc_id,
+ const struct nlattr *actions, int len);
+
static void update_ethertype(struct sk_buff *skb, struct ethhdr *hdr,
__be16 ethertype)
{
@@ -941,7 +943,7 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
struct nlattr *sample_arg;
struct sw_flow_key *orig_key = key;
int rem = nla_len(attr);
- int err = 0;
+ int err;
const struct sample_arg *arg;
/* The first action is always 'OVS_SAMPLE_ATTR_ARG'. */
@@ -979,15 +981,8 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
key = clone_key(key);
}
- if (key) {
- err = do_execute_actions(dp, skb, key, actions, rem);
- } else if (!add_deferred_actions(skb, orig_key, actions, rem)) {
-
- if (net_ratelimit())
- pr_warn("%s: deferred action limit reached, drop sample action\n",
- ovs_dp_name(dp));
- kfree_skb(skb);
- }
+ err = execute_or_defer_actions(dp, skb, key, orig_key, NULL,
+ actions, rem);
if (!arg->exec)
__this_cpu_dec(exec_actions_level);
@@ -1105,8 +1100,7 @@ static int execute_recirc(struct datapath *dp, struct sk_buff *skb,
struct sw_flow_key *key,
const struct nlattr *a, int rem)
{
- struct sw_flow_key *recirc_key;
- struct deferred_action *da;
+ u32 recirc_id;
if (!is_flow_key_valid(key)) {
int err;
@@ -1130,27 +1124,9 @@ static int execute_recirc(struct datapath *dp, struct sk_buff *skb,
return 0;
}
- /* If within the limit of 'OVS_DEFERRED_ACTION_THRESHOLD',
- * recirc immediately, otherwise, defer it for later execution.
- */
- recirc_key = clone_key(key);
- if (recirc_key) {
- recirc_key->recirc_id = nla_get_u32(a);
- ovs_dp_process_packet(skb, recirc_key);
- } else {
- da = add_deferred_actions(skb, key, NULL, 0);
- if (da) {
- recirc_key = &da->pkt_key;
- recirc_key->recirc_id = nla_get_u32(a);
- } else {
- /* Log an error in case action fifo is full. */
- kfree_skb(skb);
- if (net_ratelimit())
- pr_warn("%s: deferred action limit reached, drop recirc action\n",
- ovs_dp_name(dp));
- }
- }
- return 0;
+ recirc_id = nla_get_u32(a);
+ return execute_or_defer_actions(dp, skb, clone_key(key),
+ key, &recirc_id, NULL, 0);
}
/* Execute a list of actions against 'skb'. */
@@ -1286,6 +1262,52 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
return 0;
}
+static int execute_or_defer_actions(struct datapath *dp, struct sk_buff *skb,
+ struct sw_flow_key *clone,
+ struct sw_flow_key *key,
+ u32 *recirc_id,
+ const struct nlattr *actions, int len)
+{
+ struct deferred_action *da;
+
+ /* If within the limit of 'OVS_DEFERRED_ACTION_THRESHOLD',
+ * recirc immediately, otherwise, defer it for later execution.
+ */
+ if (clone) {
+ if (recirc_id) {
+ clone->recirc_id = *recirc_id;
+ ovs_dp_process_packet(skb, clone);
+ return 0;
+ } else {
+ return do_execute_actions(dp, skb, clone,
+ actions, len);
+ }
+ }
+
+ da = add_deferred_actions(skb, key, actions, len);
+ if (da) {
+ if (recirc_id) {
+ key = &da->pkt_key;
+ key->recirc_id = *recirc_id;
+ }
+ } else {
+ /* Drop the SKB and log an error. */
+ kfree_skb(skb);
+
+ if (net_ratelimit()) {
+ if (recirc_id) {
+ pr_warn("%s: deferred action limit reached, drop recirc action\n",
+ ovs_dp_name(dp));
+ } else {
+ pr_warn("%s: deferred action limit reached, drop sample action\n",
+ ovs_dp_name(dp));
+ }
+ }
+ }
+
+ return 0;
+}
+
static void process_deferred_actions(struct datapath *dp)
{
struct action_fifo *fifo = this_cpu_ptr(action_fifos);
--
1.8.3.1
Powered by blists - more mailing lists