diff --git a/NEWS b/NEWS index 100cb22d5..c24ec536c 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ Post-v2.13.0 --------------------- + - ovs-vswitchd no longer deletes datapath flows on exit by default. v2.13.0 - xx xxx xxxx diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index cff6d4bf3..483cebb52 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -332,7 +332,7 @@ static size_t recv_upcalls(struct handler *); static int process_upcall(struct udpif *, struct upcall *, struct ofpbuf *odp_actions, struct flow_wildcards *); static void handle_upcalls(struct udpif *, struct upcall *, size_t n_upcalls); -static void udpif_stop_threads(struct udpif *); +static void udpif_stop_threads(struct udpif *, bool delete_flows); static void udpif_start_threads(struct udpif *, size_t n_handlers, size_t n_revalidators); static void udpif_pause_revalidators(struct udpif *); @@ -483,7 +483,7 @@ udpif_run(struct udpif *udpif) void udpif_destroy(struct udpif *udpif) { - udpif_stop_threads(udpif); + udpif_stop_threads(udpif, false); dpif_register_dp_purge_cb(udpif->dpif, NULL, udpif); dpif_register_upcall_cb(udpif->dpif, NULL, udpif); @@ -504,9 +504,15 @@ udpif_destroy(struct udpif *udpif) free(udpif); } -/* Stops the handler and revalidator threads. */ +/* Stops the handler and revalidator threads. + * + * If 'delete_flows' is true, we delete ukeys and delete all flows from the + * datapath. Otherwise, we end up double-counting stats for flows that remain + * in the datapath. If 'delete_flows' is false, we skip this step. This is + * appropriate if OVS is about to exit anyway and it is desirable to let + * existing network connections continue being forwarded afterward. */ static void -udpif_stop_threads(struct udpif *udpif) +udpif_stop_threads(struct udpif *udpif, bool delete_flows) { if (udpif && (udpif->n_handlers != 0 || udpif->n_revalidators != 0)) { size_t i; @@ -526,10 +532,10 @@ udpif_stop_threads(struct udpif *udpif) dpif_disable_upcall(udpif->dpif); ovsrcu_quiesce_end(); - /* Delete ukeys, and delete all flows from the datapath to prevent - * double-counting stats. */ - for (i = 0; i < udpif->n_revalidators; i++) { - revalidator_purge(&udpif->revalidators[i]); + if (delete_flows) { + for (i = 0; i < udpif->n_revalidators; i++) { + revalidator_purge(&udpif->revalidators[i]); + } } latch_poll(&udpif->exit_latch); @@ -627,7 +633,7 @@ udpif_set_threads(struct udpif *udpif, size_t n_handlers_, if (udpif->n_handlers != n_handlers_ || udpif->n_revalidators != n_revalidators_) { - udpif_stop_threads(udpif); + udpif_stop_threads(udpif, true); } if (!udpif->handlers && !udpif->revalidators) { @@ -681,7 +687,7 @@ udpif_flush(struct udpif *udpif) size_t n_handlers_ = udpif->n_handlers; size_t n_revalidators_ = udpif->n_revalidators; - udpif_stop_threads(udpif); + udpif_stop_threads(udpif, true); dpif_flow_flush(udpif->dpif); udpif_start_threads(udpif, n_handlers_, n_revalidators_); } diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 08830d837..5d69a4332 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -1601,13 +1601,13 @@ ofproto_rule_delete(struct ofproto *ofproto, struct rule *rule) } static void -ofproto_flush__(struct ofproto *ofproto) +ofproto_flush__(struct ofproto *ofproto, bool del) OVS_EXCLUDED(ofproto_mutex) { struct oftable *table; /* This will flush all datapath flows. */ - if (ofproto->ofproto_class->flush) { + if (del && ofproto->ofproto_class->flush) { ofproto->ofproto_class->flush(ofproto); } @@ -1710,7 +1710,7 @@ ofproto_destroy(struct ofproto *p, bool del) return; } - ofproto_flush__(p); + ofproto_flush__(p, del); HMAP_FOR_EACH_SAFE (ofport, next_ofport, hmap_node, &p->ports) { ofport_destroy(ofport, del); } @@ -2288,7 +2288,7 @@ void ofproto_flush_flows(struct ofproto *ofproto) { COVERAGE_INC(ofproto_flush); - ofproto_flush__(ofproto); + ofproto_flush__(ofproto, false); connmgr_flushed(ofproto->connmgr); } diff --git a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in index a23477176..ac66ed7bb 100644 --- a/vswitchd/ovs-vswitchd.8.in +++ b/vswitchd/ovs-vswitchd.8.in @@ -107,12 +107,13 @@ how to configure Open vSwitch. .SS "GENERAL COMMANDS" .IP "\fBexit\fR \fI--cleanup\fR" Causes \fBovs\-vswitchd\fR to gracefully terminate. If \fI--cleanup\fR -is specified, release datapath resources configured by \fBovs\-vswitchd\fR. -Otherwise, datapath flows and other resources remains undeleted. -Resources of datapaths that are integrated into \fBovs\-vswitchd\fR (e.g. -the \fBnetdev\fR datapath type) are always released regardless of -\fI--cleanup\fR except for ports with \fBinternal\fR type. Use \fI--cleanup\fR -to release \fBinternal\fR ports too. +is specified, deletes flows from datpaths and releases other datapath +resources configured by \fBovs\-vswitchd\fR. Otherwise, datapath +flows and other resources remains undeleted. Resources of datapaths +that are integrated into \fBovs\-vswitchd\fR (e.g. the \fBnetdev\fR +datapath type) are always released regardless of \fI--cleanup\fR +except for ports with \fBinternal\fR type. Use \fI--cleanup\fR to +release \fBinternal\fR ports too. . .IP "\fBqos/show-types\fR \fIinterface\fR" Queries the interface for a list of Quality of Service types that are