diff --git a/SOURCES/openvswitch-2.17.0.patch b/SOURCES/openvswitch-2.17.0.patch
index 7697c6c..9e5cb8c 100644
--- a/SOURCES/openvswitch-2.17.0.patch
+++ b/SOURCES/openvswitch-2.17.0.patch
@@ -50767,6 +50767,21 @@ index c4790ee6ba..0a89626cc3 100644
              if (!(cm >= cm_stubs && cm < &cm_stubs[n_cm_stubs])) {
                  free(cm);
              }
+diff --git a/lib/cmap.c b/lib/cmap.c
+index c9eef3f4ae..8ca893b0b2 100644
+--- a/lib/cmap.c
++++ b/lib/cmap.c
+@@ -598,7 +598,9 @@ cmap_set_bucket(struct cmap_bucket *b, int i,
+     uint32_t c;
+ 
+     atomic_read_explicit(&b->counter, &c, memory_order_acquire);
+-    atomic_store_explicit(&b->counter, c + 1, memory_order_release);
++    atomic_store_explicit(&b->counter, c + 1, memory_order_relaxed);
++    /* Need to make sure setting hash is not moved up before counter update. */
++    atomic_thread_fence(memory_order_release);
+     ovsrcu_set(&b->nodes[i].next, node); /* Also atomic. */
+     b->hashes[i] = hash;
+     atomic_store_explicit(&b->counter, c + 2, memory_order_release);
 diff --git a/lib/cmap.h b/lib/cmap.h
 index c502d23112..72e2ec5f71 100644
 --- a/lib/cmap.h
@@ -57002,7 +57017,7 @@ index 114aff8ea3..0fc6d2ea60 100644
      enum xc_type type;
      union {
 diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
-index 578cbfe581..e804c4d887 100644
+index 578cbfe581..ce1d94db34 100644
 --- a/ofproto/ofproto-dpif-xlate.c
 +++ b/ofproto/ofproto-dpif-xlate.c
 @@ -865,7 +865,7 @@ xlate_xbridge_init(struct xlate_cfg *xcfg, struct xbridge *xbridge)
@@ -57106,7 +57121,49 @@ index 578cbfe581..e804c4d887 100644
  static struct xbundle *
  xbundle_lookup(struct xlate_cfg *xcfg, const struct ofbundle *ofbundle)
  {
-@@ -2125,9 +2142,14 @@ mirror_packet(struct xlate_ctx *ctx, struct xbundle *xbundle,
+@@ -1894,8 +1911,8 @@ group_is_alive(const struct xlate_ctx *ctx, uint32_t group_id, int depth)
+ #define MAX_LIVENESS_RECURSION 128 /* Arbitrary limit */
+ 
+ static bool
+-bucket_is_alive(const struct xlate_ctx *ctx,
+-                struct ofputil_bucket *bucket, int depth)
++bucket_is_alive(const struct xlate_ctx *ctx, const struct group_dpif *group,
++                const struct ofputil_bucket *bucket, int depth)
+ {
+     if (depth >= MAX_LIVENESS_RECURSION) {
+         xlate_report_error(ctx, "bucket chaining exceeded %d links",
+@@ -1903,6 +1920,12 @@ bucket_is_alive(const struct xlate_ctx *ctx,
+         return false;
+     }
+ 
++    /* In "select" groups, buckets with weight 0 are not used.
++     * In other kinds of groups, weight does not matter. */
++    if (group->up.type == OFPGT11_SELECT && bucket->weight == 0) {
++        return false;
++    }
++
+     return (!ofputil_bucket_has_liveness(bucket)
+             || (bucket->watch_port != OFPP_ANY
+                && bucket->watch_port != OFPP_CONTROLLER
+@@ -1943,7 +1966,7 @@ group_first_live_bucket(const struct xlate_ctx *ctx,
+ {
+     struct ofputil_bucket *bucket;
+     LIST_FOR_EACH (bucket, list_node, &group->up.buckets) {
+-        if (bucket_is_alive(ctx, bucket, depth)) {
++        if (bucket_is_alive(ctx, group, bucket, depth)) {
+             return bucket;
+         }
+         xlate_report_bucket_not_live(ctx, bucket);
+@@ -1962,7 +1985,7 @@ group_best_live_bucket(const struct xlate_ctx *ctx,
+ 
+     struct ofputil_bucket *bucket;
+     LIST_FOR_EACH (bucket, list_node, &group->up.buckets) {
+-        if (bucket_is_alive(ctx, bucket, 0)) {
++        if (bucket_is_alive(ctx, group, bucket, 0)) {
+             uint32_t score =
+                 (hash_int(bucket->bucket_id, basis) & 0xffff) * bucket->weight;
+             if (score >= best_score) {
+@@ -2125,9 +2148,14 @@ mirror_packet(struct xlate_ctx *ctx, struct xbundle *xbundle,
          int snaplen;
  
          /* Get the details of the mirror represented by the rightmost 1-bit. */
@@ -57124,7 +57181,7 @@ index 578cbfe581..e804c4d887 100644
  
  
          /* If this mirror selects on the basis of VLAN, and it does not select
-@@ -2444,9 +2466,18 @@ output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle,
+@@ -2444,9 +2472,18 @@ output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle,
              /* In case recirculation is not actually in use, 'xr.recirc_id'
               * will be set to '0', since a valid 'recirc_id' can
               * not be zero.  */
@@ -57146,7 +57203,7 @@ index 578cbfe581..e804c4d887 100644
              if (xr.recirc_id) {
                  /* Use recirculation instead of output. */
                  use_recirc = true;
-@@ -3015,7 +3046,7 @@ xlate_normal(struct xlate_ctx *ctx)
+@@ -3015,7 +3052,7 @@ xlate_normal(struct xlate_ctx *ctx)
      bool is_grat_arp = is_gratuitous_arp(flow, wc);
      if (ctx->xin->allow_side_effects
          && flow->packet_type == htonl(PT_ETH)
@@ -57155,7 +57212,7 @@ index 578cbfe581..e804c4d887 100644
      ) {
          update_learning_table(ctx, in_xbundle, flow->dl_src, vlan,
                                is_grat_arp);
-@@ -3024,12 +3055,14 @@ xlate_normal(struct xlate_ctx *ctx)
+@@ -3024,12 +3061,14 @@ xlate_normal(struct xlate_ctx *ctx)
          struct xc_entry *entry;
  
          /* Save just enough info to update mac learning table later. */
@@ -57176,7 +57233,7 @@ index 578cbfe581..e804c4d887 100644
      }
  
      /* Determine output bundle. */
-@@ -3048,7 +3081,6 @@ xlate_normal(struct xlate_ctx *ctx)
+@@ -3048,7 +3087,6 @@ xlate_normal(struct xlate_ctx *ctx)
               */
              ctx->xout->slow |= SLOW_ACTION;
  
@@ -57184,7 +57241,7 @@ index 578cbfe581..e804c4d887 100644
              if (mcast_snooping_is_membership(flow->tp_src) ||
                  mcast_snooping_is_query(flow->tp_src)) {
                  if (ctx->xin->allow_side_effects && ctx->xin->packet) {
-@@ -3523,6 +3555,9 @@ propagate_tunnel_data_to_flow__(struct flow *dst_flow,
+@@ -3523,6 +3561,9 @@ propagate_tunnel_data_to_flow__(struct flow *dst_flow,
      dst_flow->dl_dst = dmac;
      dst_flow->dl_src = smac;
  
@@ -57194,7 +57251,7 @@ index 578cbfe581..e804c4d887 100644
      dst_flow->packet_type = htonl(PT_ETH);
      dst_flow->nw_dst = src_flow->tunnel.ip_dst;
      dst_flow->nw_src = src_flow->tunnel.ip_src;
-@@ -3654,14 +3689,27 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport,
+@@ -3654,14 +3695,27 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport,
  
      err = tnl_neigh_lookup(out_dev->xbridge->name, &d_ip6, &dmac);
      if (err) {
@@ -57224,7 +57281,7 @@ index 578cbfe581..e804c4d887 100644
          }
          return err;
      }
-@@ -4176,6 +4224,10 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
+@@ -4176,6 +4230,10 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
          if (xport->pt_mode == NETDEV_PT_LEGACY_L3) {
              flow->packet_type = PACKET_TYPE_BE(OFPHTN_ETHERTYPE,
                                                 ntohs(flow->dl_type));
@@ -57235,7 +57292,16 @@ index 578cbfe581..e804c4d887 100644
          }
      }
  
-@@ -5622,7 +5674,8 @@ xlate_sample_action(struct xlate_ctx *ctx,
+@@ -4678,7 +4736,7 @@ pick_dp_hash_select_group(struct xlate_ctx *ctx, struct group_dpif *group)
+         for (int i = 0; i <= hash_mask; i++) {
+             struct ofputil_bucket *b =
+                     group->hash_map[(dp_hash + i) & hash_mask];
+-            if (bucket_is_alive(ctx, b, 0)) {
++            if (bucket_is_alive(ctx, group, b, 0)) {
+                 return b;
+             }
+         }
+@@ -5622,7 +5680,8 @@ xlate_sample_action(struct xlate_ctx *ctx,
  
      /* Scale the probability from 16-bit to 32-bit while representing
       * the same percentage. */
@@ -57245,7 +57311,7 @@ index 578cbfe581..e804c4d887 100644
  
      /* If ofp_port in flow sample action is equel to ofp_port,
       * this sample action is a input port action. */
-@@ -7609,6 +7662,10 @@ xlate_wc_finish(struct xlate_ctx *ctx)
+@@ -7609,6 +7668,10 @@ xlate_wc_finish(struct xlate_ctx *ctx)
              ctx->wc->masks.vlans[i].tci = 0;
          }
      }
@@ -57256,7 +57322,7 @@ index 578cbfe581..e804c4d887 100644
  }
  
  /* Translates the flow, actions, or rule in 'xin' into datapath actions in
-@@ -7784,6 +7841,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
+@@ -7784,6 +7847,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
          goto exit;
      }
  
diff --git a/SPECS/openvswitch2.17.spec b/SPECS/openvswitch2.17.spec
index 34d1197..1ef6684 100644
--- a/SPECS/openvswitch2.17.spec
+++ b/SPECS/openvswitch2.17.spec
@@ -57,7 +57,7 @@ Summary: Open vSwitch
 Group: System Environment/Daemons daemon/database/utilities
 URL: http://www.openvswitch.org/
 Version: 2.17.0
-Release: 50%{?dist}
+Release: 51%{?dist}
 
 # Nearly all of openvswitch is ASL 2.0.  The bugtool is LGPLv2+, and the
 # lib/sflow*.[ch] files are SISSL
@@ -748,6 +748,13 @@ exit 0
 %endif
 
 %changelog
+* Tue Oct 18 2022 Open vSwitch CI <ovs-ci@redhat.com> - 2.17.0-51
+- Merging upstream branch-2.17 [RH git: 8ffcf35d65]
+    Commit list:
+    35615cd37a cmap: Add thread fence for slot update.
+    5f8ba216a4 ofproto-dpif-xlate: Do not use zero-weight buckets in select groups.
+
+
 * Thu Oct 13 2022 Open vSwitch CI <ovs-ci@redhat.com> - 2.17.0-50
 - Merging upstream branch-2.17 [RH git: de74ee2fd8]
     Commit list: