summaryrefslogtreecommitdiff
path: root/ofproto/ofproto-dpif-upcall.h
diff options
context:
space:
mode:
authorEthan Jackson <ethan@nicira.com>2013-06-25 14:45:43 -0700
committerEthan Jackson <ethan@nicira.com>2013-08-11 10:36:18 -0700
commite1ec7dd4608876283038c417065c4f9978255fa3 (patch)
tree4dc284a80d4b48fdfbdc24cf143727d80e7a443f /ofproto/ofproto-dpif-upcall.h
parentad3efdcb0d5812df189ab08f19dac4b39f3a9e27 (diff)
downloadopenvswitch-e1ec7dd4608876283038c417065c4f9978255fa3.tar.gz
ofproto-dpif: Implement multi-threaded miss handling.
This patch factors flow miss handling into its own module, ofproto-dpif-upcall which can utilize multiple threads to process misses. For some important benchmarks, this change improves Open vSwitch flow setup performance by roughly 50x (that's 50 times not 50%) in my testing. Signed-off-by: Ethan Jackson <ethan@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'ofproto/ofproto-dpif-upcall.h')
-rw-r--r--ofproto/ofproto-dpif-upcall.h130
1 files changed, 130 insertions, 0 deletions
diff --git a/ofproto/ofproto-dpif-upcall.h b/ofproto/ofproto-dpif-upcall.h
new file mode 100644
index 000000000..f74206031
--- /dev/null
+++ b/ofproto/ofproto-dpif-upcall.h
@@ -0,0 +1,130 @@
+/* Copyright (c) 2013 Nicira, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. */
+
+#ifndef OFPROTO_DPIF_UPCALL_H
+#define OFPROTO_DPIF_UPCALL_H
+
+#define FLOW_MISS_MAX_BATCH 50
+
+#include "dpif.h"
+#include "flow.h"
+#include "hmap.h"
+#include "list.h"
+#include "odp-util.h"
+#include "ofpbuf.h"
+#include "ofproto-dpif-xlate.h"
+
+struct dpif;
+struct dpif_backer;
+
+/* udif is responsible for retrieving upcalls from the kernel, processing miss
+ * upcalls, and handing more complex ones up to the main ofproto-dpif
+ * module. */
+
+struct udpif *udpif_create(struct dpif_backer *, struct dpif *);
+void udpif_recv_set(struct udpif *, size_t n_workers, bool enable);
+void udpif_destroy(struct udpif *);
+
+void udpif_run(struct udpif *);
+void udpif_wait(struct udpif *);
+
+void udpif_revalidate(struct udpif *);
+
+/* udpif can handle some upcalls on its own. Others need the main ofproto_dpif
+ * code to handle them. This interface passes upcalls not handled by udpif up
+ * to the ofproto_dpif main thread. */
+
+/* Type of an upcall. */
+enum upcall_type {
+ /* Handled internally by udpif code. Not returned by upcall_next().*/
+ BAD_UPCALL, /* Some kind of bug somewhere. */
+ MISS_UPCALL, /* A flow miss. */
+
+ /* Require main thread's involvement. May be returned by upcall_next(). */
+ SFLOW_UPCALL, /* sFlow sample. */
+ FLOW_SAMPLE_UPCALL, /* Per-flow sampling. */
+ IPFIX_UPCALL /* Per-bridge sampling. */
+};
+
+/* An upcall. */
+struct upcall {
+ struct list list_node; /* For queuing upcalls. */
+
+ enum upcall_type type; /* Classification. */
+
+ /* Raw upcall plus data for keeping track of the memory backing it. */
+ struct dpif_upcall dpif_upcall; /* As returned by dpif_recv() */
+ struct ofpbuf upcall_buf; /* Owns some data in 'dpif_upcall'. */
+ uint64_t upcall_stub[256 / 8]; /* Buffer to reduce need for malloc(). */
+};
+
+struct upcall *upcall_next(struct udpif *);
+void upcall_destroy(struct upcall *);
+
+/* udpif figures out how to forward packets, and does forward them, but it
+ * can't set up datapath flows on its own. This interface passes packet
+ * forwarding data from udpif to the higher level ofproto_dpif to allow the
+ * latter to set up datapath flows. */
+
+/* Flow miss batching.
+ *
+ * Some dpifs implement operations faster when you hand them off in a batch.
+ * To allow batching, "struct flow_miss" queues the dpif-related work needed
+ * for a given flow. Each "struct flow_miss" corresponds to sending one or
+ * more packets, plus possibly installing the flow in the dpif. */
+struct flow_miss {
+ struct hmap_node hmap_node;
+ struct ofproto_dpif *ofproto;
+
+ struct flow flow;
+ enum odp_key_fitness key_fitness;
+ const struct nlattr *key;
+ size_t key_len;
+ struct list packets;
+ enum dpif_upcall_type upcall_type;
+ struct dpif_flow_stats stats;
+
+ struct xlate_out xout;
+
+ struct list upcalls;
+};
+
+struct flow_miss_batch {
+ struct list list_node;
+
+ struct flow_miss miss_buf[FLOW_MISS_MAX_BATCH];
+ struct hmap misses;
+};
+
+struct flow_miss_batch *flow_miss_batch_next(struct udpif *);
+void flow_miss_batch_destroy(struct flow_miss_batch *);
+
+/* Drop keys are odp flow keys which have drop flows installed in the kernel.
+ * These are datapath flows which have no associated ofproto, if they did we
+ * would use facets.
+ *
+ * udpif can't install drop flows by itself. This interfaces allows udpif to
+ * pass the drop flows up to ofproto_dpif to get it to install them. */
+struct drop_key {
+ struct hmap_node hmap_node;
+ struct list list_node;
+ struct nlattr *key;
+ size_t key_len;
+};
+
+struct drop_key *drop_key_next(struct udpif *);
+void drop_key_destroy(struct drop_key *);
+void udpif_drop_key_clear(struct udpif *);
+
+#endif /* ofproto-dpif-upcall.h */