[ovs-dev] [v3 1/4] datapath: Add per-CPU recirc stack infrasturcutre

Andy Zhou azhou at nicira.com
Wed Aug 27 11:13:09 UTC 2014


Future pathces will make use of those functions.

Signed-off-by: Andy Zhou <azhou at nicira.com>
---
 datapath/Modules.mk |  1 +
 datapath/actions.c  | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 datapath/actions.h  | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
 datapath/datapath.c |  4 ++++
 datapath/datapath.h |  4 +---
 5 files changed, 117 insertions(+), 3 deletions(-)
 create mode 100644 datapath/actions.h

diff --git a/datapath/Modules.mk b/datapath/Modules.mk
index 90e158c..2e74f6e 100644
--- a/datapath/Modules.mk
+++ b/datapath/Modules.mk
@@ -23,6 +23,7 @@ openvswitch_sources = \
 
 openvswitch_headers = \
 	compat.h \
+	actions.h \
 	datapath.h \
 	flow.h \
 	flow_netlink.h \
diff --git a/datapath/actions.c b/datapath/actions.c
index 9ac5f7b..31fb57d 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -39,6 +39,39 @@
 #include "mpls.h"
 #include "vlan.h"
 #include "vport.h"
+#include "actions.h"
+
+static DEFINE_PER_CPU(struct ovs_action_stack, action_stacks);
+
+static inline void action_stack_init(struct ovs_action_stack *stack)
+{
+	stack->top = 0;
+}
+
+static inline bool action_stack_is_empty(struct ovs_action_stack *stack)
+{
+	return (stack->top == 0);
+}
+
+static inline struct ovs_deferred_action *
+action_stack_pop(struct ovs_action_stack *stack)
+{
+	if (stack->top) {
+		stack->top--;
+		return &stack->stack[stack->top];
+	}
+
+	return NULL;
+}
+
+static inline struct ovs_deferred_action *
+action_stack_push(struct ovs_action_stack *stack)
+{
+	if (stack->top >= OVS_ACTION_STACK_LIMIT - 1)
+		return NULL;
+
+	return &stack->stack[stack->top++];
+}
 
 static void flow_key_clone(struct sk_buff *skb, struct sw_flow_key *new_key)
 {
@@ -932,3 +965,27 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb, struct sw_flow
 {
 	return do_execute_actions(dp, skb, acts->actions, acts->actions_len);
 }
+
+void ovs_action_stacks_init(void)
+{
+	int i;
+
+	for_each_possible_cpu(i) {
+		struct ovs_action_stack *stack;
+
+		stack = &per_cpu(action_stacks, i);
+		action_stack_init(stack);
+	}
+}
+
+void ovs_action_stacks_exit(void)
+{
+	int i;
+
+	for_each_possible_cpu(i) {
+		struct ovs_action_stack *stack;
+
+		stack = &per_cpu(action_stacks, i);
+		BUG_ON(stack->top != 0);
+	}
+}
diff --git a/datapath/actions.h b/datapath/actions.h
new file mode 100644
index 0000000..5f98ad4
--- /dev/null
+++ b/datapath/actions.h
@@ -0,0 +1,54 @@
+/* Copyright (c) 2007-2014 Nicira, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#ifndef ACTION_H
+#define ACTION_H 1
+
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+
+#include "compat.h"
+#include "flow.h"
+#include "flow_table.h"
+#include "vlan.h"
+#include "vport.h"
+
+#define OVS_ACTION_STACK_LIMIT 10
+
+struct ovs_deferred_action {
+	struct sk_buff *skb;
+	struct nlattr *actions;
+	int rem;
+
+	/* Store pkt_key clone during recirc */
+	struct sw_flow_key pkt_key;
+};
+
+struct ovs_action_stack {
+	/* Deffered action stack */
+	int top;
+	struct ovs_deferred_action stack[OVS_ACTION_STACK_LIMIT];
+};
+
+void ovs_action_stacks_init(void);
+void ovs_action_stacks_exit(void);;
+int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb, struct sw_flow_actions *acts);
+void ovs_process_action_stack(void);
+
+#endif /* actions.h */
diff --git a/datapath/datapath.c b/datapath/datapath.c
index a668222..b61e0ae 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -61,6 +61,7 @@
 #include "vlan.h"
 #include "vport-internal_dev.h"
 #include "vport-netdev.h"
+#include "actions.h"
 
 int ovs_net_id __read_mostly;
 
@@ -2151,6 +2152,8 @@ static int __init dp_init(void)
 	if (err < 0)
 		goto error_unreg_notifier;
 
+	ovs_action_stacks_init();
+
 	return 0;
 
 error_unreg_notifier:
@@ -2173,6 +2176,7 @@ static void dp_cleanup(void)
 	rcu_barrier();
 	ovs_vport_exit();
 	ovs_flow_exit();
+	ovs_action_stacks_exit();
 }
 
 module_init(dp_init);
diff --git a/datapath/datapath.h b/datapath/datapath.h
index eba2fc4..dbe58d4 100644
--- a/datapath/datapath.h
+++ b/datapath/datapath.h
@@ -31,6 +31,7 @@
 #include "flow_table.h"
 #include "vlan.h"
 #include "vport.h"
+#include "actions.h"
 
 #define DP_MAX_PORTS		USHRT_MAX
 #define DP_VPORT_HASH_BUCKETS	1024
@@ -196,9 +197,6 @@ int ovs_dp_upcall(struct datapath *, struct sk_buff *,
 const char *ovs_dp_name(const struct datapath *dp);
 struct sk_buff *ovs_vport_cmd_build_info(struct vport *, u32 portid, u32 seq,
 					 u8 cmd);
-
-int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb,
-			struct sw_flow_actions *acts);
 void ovs_dp_notify_wq(struct work_struct *work);
 
 #define OVS_NLERR(fmt, ...)					\
-- 
1.9.1




More information about the dev mailing list