From e2d8ae7a5b3d0634e1d686309c00727f7354b31b Mon Sep 17 00:00:00 2001 From: Open vSwitch CI Date: May 31 2022 12:25:45 +0000 Subject: Import openvswitch2.13-2.13.0-185 from Fast DataPath --- diff --git a/SOURCES/openvswitch-2.13.0.patch b/SOURCES/openvswitch-2.13.0.patch index 076eb18..c2e3036 100644 --- a/SOURCES/openvswitch-2.13.0.patch +++ b/SOURCES/openvswitch-2.13.0.patch @@ -86227,7 +86227,7 @@ index 8f2ea34308..8d141b41e3 100644 #endif /* ovs-numa.h */ diff --git a/lib/ovs-rcu.c b/lib/ovs-rcu.c -index ebc8120f0f..cde1e925ba 100644 +index ebc8120f0f..9dfda3f053 100644 --- a/lib/ovs-rcu.c +++ b/lib/ovs-rcu.c @@ -30,6 +30,8 @@ @@ -86281,6 +86281,78 @@ index ebc8120f0f..cde1e925ba 100644 free(cbset); } +@@ -440,3 +447,40 @@ ovsrcu_init_module(void) + ovsthread_once_done(&once); + } + } ++ ++static void ++ovsrcu_barrier_func(void *seq_) ++{ ++ struct seq *seq = (struct seq *) seq_; ++ seq_change(seq); ++} ++ ++/* Similar to the kernel rcu_barrier, ovsrcu_barrier waits for all outstanding ++ * RCU callbacks to complete. However, unlike the kernel rcu_barrier, which ++ * might return immediately if there are no outstanding RCU callbacks, ++ * this API will at least wait for a grace period. ++ * ++ * Another issue the caller might need to know is that the barrier is just ++ * for "one-shot", i.e. if inside some RCU callbacks, another RCU callback is ++ * registered, this API only guarantees the first round of RCU callbacks have ++ * been executed after it returns. ++ */ ++void ++ovsrcu_barrier(void) ++{ ++ struct seq *seq = seq_create(); ++ /* First let all threads flush their cbsets. */ ++ ovsrcu_synchronize(); ++ ++ /* Then register a new cbset, ensure this cbset ++ * is at the tail of the global list. */ ++ uint64_t seqno = seq_read(seq); ++ ovsrcu_postpone__(ovsrcu_barrier_func, (void *) seq); ++ ++ do { ++ seq_wait(seq, seqno); ++ poll_block(); ++ } while (seqno == seq_read(seq)); ++ ++ seq_destroy(seq); ++} +diff --git a/lib/ovs-rcu.h b/lib/ovs-rcu.h +index ecc4c92010..8b397b7fb0 100644 +--- a/lib/ovs-rcu.h ++++ b/lib/ovs-rcu.h +@@ -155,6 +155,19 @@ + * port_delete(id); + * } + * ++ * Use ovsrcu_barrier() to wait for all the outstanding RCU callbacks to ++ * finish. This is useful when you have to destroy some resources however ++ * these resources are referenced in the outstanding RCU callbacks. ++ * ++ * void rcu_cb(void *A) { ++ * do_something(A); ++ * } ++ * ++ * void destroy_A() { ++ * ovsrcu_postpone(rcu_cb, A); // will use A later ++ * ovsrcu_barrier(); // wait for rcu_cb done ++ * do_destroy_A(); // free A ++ * } + */ + + #include "compiler.h" +@@ -310,4 +323,6 @@ void ovsrcu_synchronize(void); + + void ovsrcu_exit(void); + ++void ovsrcu_barrier(void); ++ + #endif /* ovs-rcu.h */ diff --git a/lib/ovs-router.c b/lib/ovs-router.c index bfb2b7071b..09b81c6e5a 100644 --- a/lib/ovs-router.c @@ -89218,7 +89290,7 @@ index 3426a27b2d..e4959ec686 100644 void xlate_bundle_set(struct ofproto_dpif *, struct ofbundle *, const char *name, enum port_vlan_mode, diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c -index d3cb392077..f426ffdc5c 100644 +index d3cb392077..0bf5eeb403 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -215,10 +215,6 @@ struct shash all_dpif_backers = SHASH_INITIALIZER(&all_dpif_backers); @@ -89284,7 +89356,16 @@ index d3cb392077..f426ffdc5c 100644 OFPROTO_FOR_EACH_TABLE (table, &ofproto->up) { CLS_FOR_EACH (rule, up.cr, &table->cls) { -@@ -2298,6 +2308,12 @@ set_ipfix( +@@ -1794,6 +1804,8 @@ destruct(struct ofproto *ofproto_, bool del) + + seq_destroy(ofproto->ams_seq); + ++ /* Wait for all the meter destroy work to finish. */ ++ ovsrcu_barrier(); + close_dpif_backer(ofproto->backer, del); + } + +@@ -2298,6 +2310,12 @@ set_ipfix( dpif_ipfix_unref(di); ofproto->ipfix = NULL; } @@ -89297,7 +89378,7 @@ index d3cb392077..f426ffdc5c 100644 } return 0; -@@ -4376,12 +4392,14 @@ rule_dpif_lookup_from_table(struct ofproto_dpif *ofproto, +@@ -4376,12 +4394,14 @@ rule_dpif_lookup_from_table(struct ofproto_dpif *ofproto, atomic_add_relaxed(&tbl->n_matched, stats->n_packets, &orig); } if (xcache) { @@ -89317,7 +89398,7 @@ index d3cb392077..f426ffdc5c 100644 } return rule; } -@@ -4412,12 +4430,14 @@ rule_dpif_lookup_from_table(struct ofproto_dpif *ofproto, +@@ -4412,12 +4432,14 @@ rule_dpif_lookup_from_table(struct ofproto_dpif *ofproto, stats->n_packets, &orig); } if (xcache) { @@ -89337,7 +89418,7 @@ index d3cb392077..f426ffdc5c 100644 } if (rule) { goto out; /* Match. */ -@@ -5375,6 +5395,8 @@ ct_add_timeout_policy_to_dpif(struct dpif *dpif, +@@ -5375,6 +5397,8 @@ ct_add_timeout_policy_to_dpif(struct dpif *dpif, struct ct_dpif_timeout_policy cdtp; struct simap_node *node; @@ -89346,7 +89427,7 @@ index d3cb392077..f426ffdc5c 100644 cdtp.id = ct_tp->tp_id; SIMAP_FOR_EACH (node, &ct_tp->tp) { ct_dpif_set_timeout_policy_attr_by_name(&cdtp, node->name, node->data); -@@ -5496,6 +5518,7 @@ ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone_id, +@@ -5496,6 +5520,7 @@ ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone_id, ct_timeout_policy_unref(backer, ct_zone->ct_tp); ct_zone->ct_tp = ct_tp; ct_tp->ref_count++; @@ -89354,7 +89435,7 @@ index d3cb392077..f426ffdc5c 100644 } } else { struct ct_zone *new_ct_zone = ct_zone_alloc(zone_id); -@@ -5503,6 +5526,7 @@ ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone_id, +@@ -5503,6 +5528,7 @@ ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone_id, cmap_insert(&backer->ct_zones, &new_ct_zone->node, hash_int(zone_id, 0)); ct_tp->ref_count++; @@ -89362,7 +89443,7 @@ index d3cb392077..f426ffdc5c 100644 } } -@@ -5519,6 +5543,7 @@ ct_del_zone_timeout_policy(const char *datapath_type, uint16_t zone_id) +@@ -5519,6 +5545,7 @@ ct_del_zone_timeout_policy(const char *datapath_type, uint16_t zone_id) if (ct_zone) { ct_timeout_policy_unref(backer, ct_zone->ct_tp); ct_zone_remove_and_destroy(backer, ct_zone); @@ -89370,7 +89451,7 @@ index d3cb392077..f426ffdc5c 100644 } } -@@ -5563,6 +5588,7 @@ get_datapath_cap(const char *datapath_type, struct smap *cap) +@@ -5563,6 +5590,7 @@ get_datapath_cap(const char *datapath_type, struct smap *cap) smap_add(cap, "ct_timeout", s.ct_timeout ? "true" : "false"); smap_add(cap, "explicit_drop_action", s.explicit_drop_action ? "true" :"false"); @@ -89378,7 +89459,7 @@ index d3cb392077..f426ffdc5c 100644 } /* Gets timeout policy name in 'backer' based on 'zone', 'dl_type' and -@@ -5717,15 +5743,7 @@ ofproto_dpif_lookup_by_name(const char *name) +@@ -5717,15 +5745,7 @@ ofproto_dpif_lookup_by_name(const char *name) struct ofproto_dpif * ofproto_dpif_lookup_by_uuid(const struct uuid *uuid) { @@ -89395,7 +89476,7 @@ index d3cb392077..f426ffdc5c 100644 } static void -@@ -6335,6 +6353,7 @@ ofproto_unixctl_dpif_show_dp_features(struct unixctl_conn *conn, +@@ -6335,6 +6355,7 @@ ofproto_unixctl_dpif_show_dp_features(struct unixctl_conn *conn, dpif_show_support(&ofproto->backer->bt_support, &ds); unixctl_command_reply(conn, ds_cstr(&ds)); @@ -92322,7 +92403,7 @@ index bee79fc50f..3ddb612b0c 100644 "columns" : { "name" : { diff --git a/tests/library.at b/tests/library.at -index ac4ea4abf2..1702b7556b 100644 +index ac4ea4abf2..e27d9e8bce 100644 --- a/tests/library.at +++ b/tests/library.at @@ -53,7 +53,8 @@ AT_CHECK([ovstest test-packets]) @@ -92335,6 +92416,15 @@ index ac4ea4abf2..1702b7556b 100644 ]) AT_CLEANUP +@@ -246,7 +247,7 @@ AT_CHECK([ovstest test-ofpbuf], [0], []) + AT_CLEANUP + + AT_SETUP([rcu]) +-AT_CHECK([ovstest test-rcu-quiesce], [0], []) ++AT_CHECK([ovstest test-rcu], [0], []) + AT_CLEANUP + + AT_SETUP([stopwatch module]) diff --git a/tests/odp.at b/tests/odp.at index 3ab9ad62dd..516527f9cc 100644 --- a/tests/odp.at @@ -96888,6 +96978,50 @@ index 1b94b79a07..123f89f081 100644 step += 1 seqno = idl.change_seqno +diff --git a/tests/test-rcu.c b/tests/test-rcu.c +index 965f3c49f3..bb17092bf0 100644 +--- a/tests/test-rcu.c ++++ b/tests/test-rcu.c +@@ -35,7 +35,7 @@ quiescer_main(void *aux OVS_UNUSED) + } + + static void +-test_rcu_quiesce(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) ++test_rcu_quiesce(void) + { + pthread_t quiescer; + +@@ -48,4 +48,29 @@ test_rcu_quiesce(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) + xpthread_join(quiescer, NULL); + } + +-OVSTEST_REGISTER("test-rcu-quiesce", test_rcu_quiesce); ++static void ++add_count(void *_count) ++{ ++ unsigned *count = (unsigned *)_count; ++ (*count) ++; ++} ++ ++static void ++test_rcu_barrier(void) ++{ ++ unsigned count = 0; ++ for (int i = 0; i < 10; i ++) { ++ ovsrcu_postpone(add_count, &count); ++ } ++ ++ ovsrcu_barrier(); ++ ovs_assert(count == 10); ++} ++ ++static void ++test_rcu(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) { ++ test_rcu_quiesce(); ++ test_rcu_barrier(); ++} ++ ++OVSTEST_REGISTER("test-rcu", test_rcu); diff --git a/tests/test-reconnect.c b/tests/test-reconnect.c index 5a14e7fe58..bf0463e25c 100644 --- a/tests/test-reconnect.c diff --git a/SPECS/openvswitch2.13.spec b/SPECS/openvswitch2.13.spec index 4e0c5c3..6bf1195 100644 --- a/SPECS/openvswitch2.13.spec +++ b/SPECS/openvswitch2.13.spec @@ -59,7 +59,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 2.13.0 -Release: 184%{?commit0:.%{date}git%{shortcommit0}}%{?commit1:dpdk%{shortcommit1}}%{?dist} +Release: 185%{?commit0:.%{date}git%{shortcommit0}}%{?commit1:dpdk%{shortcommit1}}%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -715,6 +715,13 @@ exit 0 %endif %changelog +* Tue May 31 2022 Open vSwitch CI - 2.13.0-185 +- Merging upstream branch-2.13 [RH git: 5c18fae8e5] + Commit list: + 89fe949a67 ofproto-dpif: Fix meter use-after-free. + be852fbaf1 ovs-rcu: Add ovsrcu_barrier. + + * Thu May 26 2022 Open vSwitch CI - 2.13.0-184 - Merging upstream branch-2.13 [RH git: 9d3ca376af] Commit list: