ofproto: Add type "run", "run_fast", and "wait" provider methods.
authorJustin Pettit <jpettit@nicira.com>
Fri, 12 Oct 2012 00:17:40 +0000 (17:17 -0700)
committerJustin Pettit <jpettit@nicira.com>
Fri, 2 Nov 2012 05:54:27 +0000 (22:54 -0700)
Add the ability for ofproto providers to have top-level "run",
"run_fast", and "wait" methods, similar to the current ofproto ones.
There are no current users, but this will be useful in a future commit.

Signed-off-by: Justin Pettit <jpettit@nicira.com>
ofproto/ofproto-dpif.c
ofproto/ofproto-provider.h
ofproto/ofproto.c
ofproto/ofproto.h
vswitchd/bridge.c

index a452a378fe8bd84ebcde8722a92a44ec5e9f9282..90cbb412ac595e3c99747ca80f9b0ceb50b99efa 100644 (file)
@@ -7493,6 +7493,9 @@ const struct ofproto_class ofproto_dpif_class = {
     enumerate_types,
     enumerate_names,
     del,
+    NULL,                       /* type_run */
+    NULL,                       /* type_run_fast */
+    NULL,                       /* type_wait */
     alloc,
     construct,
     destruct,
index 6286d8197c72f9e03bd73a1631ff129e2ad0339d..4736b440f536871c8a7bfe96433777eb38619beb 100644 (file)
@@ -359,6 +359,37 @@ struct ofproto_class {
      */
     int (*del)(const char *type, const char *name);
 
+/* ## ------------------------ ## */
+/* ## Top-Level type Functions ## */
+/* ## ------------------------ ## */
+
+    /* Performs any periodic activity required on ofprotos of type
+     * 'type'.
+     *
+     * An ofproto provider may implement it or not, depending on whether
+     * it needs type-level maintenance.
+     *
+     * Returns 0 if successful, otherwise a positive errno value. */
+    int (*type_run)(const char *type);
+
+    /* Performs periodic activity required on ofprotos of type 'type'
+     * that needs to be done with the least possible latency.
+     *
+     * This is run multiple times per main loop.  An ofproto provider may
+     * implement it or not, according to whether it provides a performance
+     * boost for that ofproto implementation.
+     *
+     * Returns 0 if successful, otherwise a positive errno value. */
+    int (*type_run_fast)(const char *type);
+
+    /* Causes the poll loop to wake up when a type 'type''s 'run'
+     * function needs to be called, e.g. by calling the timer or fd
+     * waiting functions in poll-loop.h.
+     *
+     * An ofproto provider may implement it or not, depending on whether
+     * it needs type-level maintenance. */
+    void (*type_wait)(const char *type);
+
 /* ## --------------------------- ## */
 /* ## Top-Level ofproto Functions ## */
 /* ## --------------------------- ## */
index cd09bbd1146d70beec07d1ca055865c8d202dd63..bf11ab3b8926b013befa4ab5606049484caaab95 100644 (file)
@@ -1097,6 +1097,53 @@ process_port_change(struct ofproto *ofproto, int error, char *devname)
     }
 }
 
+int
+ofproto_type_run(const char *datapath_type)
+{
+    const struct ofproto_class *class;
+    int error;
+
+    datapath_type = ofproto_normalize_type(datapath_type);
+    class = ofproto_class_find__(datapath_type);
+
+    error = class->type_run ? class->type_run(datapath_type) : 0;
+    if (error && error != EAGAIN) {
+        VLOG_ERR_RL(&rl, "%s: type_run failed (%s)",
+                    datapath_type, strerror(error));
+    }
+    return error;
+}
+
+int
+ofproto_type_run_fast(const char *datapath_type)
+{
+    const struct ofproto_class *class;
+    int error;
+
+    datapath_type = ofproto_normalize_type(datapath_type);
+    class = ofproto_class_find__(datapath_type);
+
+    error = class->type_run_fast ? class->type_run_fast(datapath_type) : 0;
+    if (error && error != EAGAIN) {
+        VLOG_ERR_RL(&rl, "%s: type_run_fast failed (%s)",
+                    datapath_type, strerror(error));
+    }
+    return error;
+}
+
+void
+ofproto_type_wait(const char *datapath_type)
+{
+    const struct ofproto_class *class;
+
+    datapath_type = ofproto_normalize_type(datapath_type);
+    class = ofproto_class_find__(datapath_type);
+
+    if (class->type_wait) {
+        class->type_wait(datapath_type);
+    }
+}
+
 int
 ofproto_run(struct ofproto *p)
 {
index 96dde6a852a8405aa55ec837103d409d83e6689a..20335a2eb748aa585702e1f94c7d7d845df19b70 100644 (file)
@@ -154,6 +154,10 @@ struct iface_hint {
 
 void ofproto_init(const struct shash *iface_hints);
 
+int ofproto_type_run(const char *datapath_type);
+int ofproto_type_run_fast(const char *datapath_type);
+void ofproto_type_wait(const char *datapath_type);
+
 int ofproto_create(const char *datapath, const char *datapath_type,
                    struct ofproto **ofprotop);
 void ofproto_destroy(struct ofproto *);
index f7ed68a6692267b2a36790c2566137ca13b808ae..3356a049673c363caaa142607f26dc45cefe57a8 100644 (file)
@@ -2078,8 +2078,17 @@ refresh_instant_stats(void)
 void
 bridge_run_fast(void)
 {
+    struct sset types;
+    const char *type;
     struct bridge *br;
 
+    sset_init(&types);
+    ofproto_enumerate_types(&types);
+    SSET_FOR_EACH (type, &types) {
+        ofproto_type_run_fast(type);
+    }
+    sset_destroy(&types);
+
     HMAP_FOR_EACH (br, node, &all_bridges) {
         ofproto_run_fast(br->ofproto);
     }
@@ -2091,6 +2100,8 @@ bridge_run(void)
     static const struct ovsrec_open_vswitch null_cfg;
     const struct ovsrec_open_vswitch *cfg;
     struct ovsdb_idl_txn *reconf_txn = NULL;
+    struct sset types;
+    const char *type;
 
     bool vlan_splinters_changed;
     struct bridge *br;
@@ -2124,6 +2135,14 @@ bridge_run(void)
      * returns immediately. */
     bridge_init_ofproto(cfg);
 
+    /* Let each datapath type do the work that it needs to do. */
+    sset_init(&types);
+    ofproto_enumerate_types(&types);
+    SSET_FOR_EACH (type, &types) {
+        ofproto_type_run(type);
+    }
+    sset_destroy(&types);
+
     /* Let each bridge do the work that it needs to do. */
     HMAP_FOR_EACH (br, node, &all_bridges) {
         ofproto_run(br->ofproto);
@@ -2226,12 +2245,22 @@ bridge_run(void)
 void
 bridge_wait(void)
 {
+    struct sset types;
+    const char *type;
+
     ovsdb_idl_wait(idl);
 
     if (reconfiguring) {
         poll_immediate_wake();
     }
 
+    sset_init(&types);
+    ofproto_enumerate_types(&types);
+    SSET_FOR_EACH (type, &types) {
+        ofproto_type_wait(type);
+    }
+    sset_destroy(&types);
+
     if (!hmap_is_empty(&all_bridges)) {
         struct bridge *br;