From: Justin Pettit Date: Fri, 12 Oct 2012 00:17:40 +0000 (-0700) Subject: ofproto: Add type "run", "run_fast", and "wait" provider methods. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=openvswitch;a=commitdiff_plain;h=11a574a737fa506c8e66c7bd42fa3186e70c286f ofproto: Add type "run", "run_fast", and "wait" provider methods. 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 --- diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index a452a378..90cbb412 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -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, diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index 6286d819..4736b440 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -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 ## */ /* ## --------------------------- ## */ diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index cd09bbd1..bf11ab3b 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -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) { diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h index 96dde6a8..20335a2e 100644 --- a/ofproto/ofproto.h +++ b/ofproto/ofproto.h @@ -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 *); diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index f7ed68a6..3356a049 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -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;