The comment could be: +/* Finds a port which needs to flush its own MAC learning table. A NULL > pointer > + * is returned if no port needs to flush its MAC learning table. > + * '*port' needs to be NULL in the first call to start the iteration. If > + * '*port' is passed as non-NULL, it must be the value set by the last > + * invocation of this function. */ > +void * > +rstp_check_and_reset_fdb_flush(struct rstp *rstp, struct rstp_port **port)
Do you have a working copy of this or should I submit a v2? Daniele 2014-11-14 0:54 GMT+01:00 Jarno Rajahalme <jrajaha...@nicira.com>: > Small nits below, otherwise: > > Acked-by: Jarno Rajahalme <jrajaha...@nicira.com> > > On Nov 6, 2014, at 7:31 AM, Daniele Venturino <daniele.ventur...@m3s.it> > wrote: > > > With this commit, RSTP is able to flush from the MAC learning table > > entries pertaining to a single port. Before this commit the whole > table > > was flushed every time a port requested flushing actions. > > Indentation. > > > > > Signed-off-by: Daniele Venturino <daniele.ventur...@m3s.it> > > --- > > lib/rstp.c | 52 > +++++++++++++++++++++++++++++++++----------------- > > lib/rstp.h | 2 +- > > ofproto/ofproto-dpif.c | 18 ++++++++--------- > > 3 files changed, 44 insertions(+), 28 deletions(-) > > > > diff --git a/lib/rstp.c b/lib/rstp.c > > index 55c43c0..1ab4938 100644 > > --- a/lib/rstp.c > > +++ b/lib/rstp.c > > @@ -775,31 +775,49 @@ rstp_get_root_path_cost(const struct rstp *rstp) > > return cost; > > } > > > > -/* Returns true if something has happened to 'rstp' which necessitates > > - * flushing the client's MAC learning table. > > +/* Finds a port which needs to flush its own MAC learning table. A NULL > pointer > > + * is returned if no port needs to flush its MAC learning table. > > Mention that ‘*port’ needs to be NULL in the first call to start the > iteration. > > > */ > > -bool > > -rstp_check_and_reset_fdb_flush(struct rstp *rstp) > > +void * > > +rstp_check_and_reset_fdb_flush(struct rstp *rstp, struct rstp_port > **port) > > OVS_EXCLUDED(rstp_mutex) > > { > > - bool needs_flush; > > - struct rstp_port *p; > > - > > - needs_flush = false; > > + void *aux = NULL; > > > > ovs_mutex_lock(&rstp_mutex); > > - HMAP_FOR_EACH (p, node, &rstp->ports) { > > - if (p->fdb_flush) { > > - needs_flush = true; > > - /* fdb_flush should be reset by the filtering database > > - * once the entries are removed if rstp_version is TRUE, and > > - * immediately if stp_version is TRUE.*/ > > - p->fdb_flush = false; > > + if (*port == NULL) { > > + struct rstp_port *p; > > + > > + HMAP_FOR_EACH (p, node, &rstp->ports) { > > + if (p->fdb_flush) { > > + aux = p->aux; > > + *port = p; > > + goto out; > > + } > > } > > + } else { /* continue */ > > + struct rstp_port *p = *port; > > + > > + HMAP_FOR_EACH_CONTINUE (p, node, &rstp->ports) { > > + if (p->fdb_flush) { > > + aux = p->aux; > > + *port = p; > > + goto out; > > + } > > + } > > + } > > + /* No port needs flushing. */ > > + *port = NULL; > > +out: > > + /* fdb_flush should be reset by the filtering database > > + * once the entries are removed if rstp_version is TRUE, and > > + * immediately if stp_version is TRUE.*/ > > + if (*port != NULL) { > > + (*port)->fdb_flush = false; > > } > > ovs_mutex_unlock(&rstp_mutex); > > - return needs_flush; > > -} > > + return aux; > > + } > > > > /* Finds a port whose state has changed, and returns the aux pointer set > for > > * the port. A NULL pointer is returned when no changed port is found. > On > > diff --git a/lib/rstp.h b/lib/rstp.h > > index b429e35..b05cdf2 100644 > > --- a/lib/rstp.h > > +++ b/lib/rstp.h > > @@ -157,7 +157,7 @@ void rstp_tick_timers(struct rstp *) > > void rstp_port_received_bpdu(struct rstp_port *, const void *bpdu, > > size_t bpdu_size) > > OVS_EXCLUDED(rstp_mutex); > > -bool rstp_check_and_reset_fdb_flush(struct rstp *) > > +void *rstp_check_and_reset_fdb_flush(struct rstp *, struct rstp_port **) > > OVS_EXCLUDED(rstp_mutex); > > void *rstp_get_next_changed_port_aux(struct rstp *, struct rstp_port **) > > OVS_EXCLUDED(rstp_mutex); > > diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c > > index dc0ecdf..2fd9896 100644 > > --- a/ofproto/ofproto-dpif.c > > +++ b/ofproto/ofproto-dpif.c > > @@ -140,6 +140,7 @@ static void bundle_destroy(struct ofbundle *); > > static void bundle_del_port(struct ofport_dpif *); > > static void bundle_run(struct ofbundle *); > > static void bundle_wait(struct ofbundle *); > > +static void bundle_flush_macs(struct ofbundle *, bool); > > > > static void stp_run(struct ofproto_dpif *ofproto); > > static void stp_wait(struct ofproto_dpif *ofproto); > > @@ -2098,9 +2099,9 @@ update_rstp_port_state(struct ofport_dpif *ofport) > > if (rstp_learn_in_state(ofport->rstp_state) > > != rstp_learn_in_state(state)) { > > /* xxx Learning action flows should also be flushed. */ > > - ovs_rwlock_wrlock(&ofproto->ml->rwlock); > > - mac_learning_flush(ofproto->ml); > > - ovs_rwlock_unlock(&ofproto->ml->rwlock); > > + if (ofport->bundle) { > > + bundle_flush_macs(ofport->bundle, false); > > + } > > } > > fwd_change = rstp_forward_in_state(ofport->rstp_state) > > != rstp_forward_in_state(state); > > @@ -2140,16 +2141,13 @@ rstp_run(struct ofproto_dpif *ofproto) > > while ((ofport = rstp_get_next_changed_port_aux(ofproto->rstp, > &rp))) { > > update_rstp_port_state(ofport); > > } > > + rp = NULL; > > + ofport = NULL; > > /* FIXME: This check should be done on-event (i.e., when setting > > * p->fdb_flush) and not periodically. > > */ > > - if (rstp_check_and_reset_fdb_flush(ofproto->rstp)) { > > - ovs_rwlock_wrlock(&ofproto->ml->rwlock); > > - /* FIXME: RSTP should be able to flush the entries > pertaining to a > > - * single port, not the whole table. > > - */ > > - mac_learning_flush(ofproto->ml); > > - ovs_rwlock_unlock(&ofproto->ml->rwlock); > > + while ((ofport = rstp_check_and_reset_fdb_flush(ofproto->rstp, > &rp))) { > > + bundle_flush_macs(ofport->bundle, false); > > } > > } > > } > > -- > > 1.8.1.2 > > > > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev