diff --git a/SOURCES/openvswitch-2.17.0.patch b/SOURCES/openvswitch-2.17.0.patch index 9e5cb8c..cdebc0b 100644 --- a/SOURCES/openvswitch-2.17.0.patch +++ b/SOURCES/openvswitch-2.17.0.patch @@ -51492,7 +51492,7 @@ index 66016eb099..7425dd44e7 100644 /* Statistics. */ struct dp_netdev_flow_stats stats; diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c -index 9f35713ef5..3d9d8929f7 100644 +index 9f35713ef5..24b64b1686 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -93,7 +93,8 @@ VLOG_DEFINE_THIS_MODULE(dpif_netdev); @@ -51505,7 +51505,15 @@ index 9f35713ef5..3d9d8929f7 100644 #define MIN_TO_MSEC 60000 #define FLOW_DUMP_MAX_BATCH 50 -@@ -1932,13 +1933,13 @@ static void +@@ -430,7 +431,6 @@ struct dp_netdev_rxq { + unsigned intrvl_idx; /* Write index for 'cycles_intrvl'. */ + struct dp_netdev_pmd_thread *pmd; /* pmd thread that polls this queue. */ + bool is_vhost; /* Is rxq of a vhost port. */ +- bool hw_miss_api_supported; /* hw_miss_packet_recover() supported.*/ + + /* Counters of cycles spent successfully polling and processing pkts. */ + atomic_ullong cycles[RXQ_N_CYCLES]; +@@ -1932,13 +1932,13 @@ static void dp_netdev_free(struct dp_netdev *dp) OVS_REQUIRES(dp_netdev_mutex) { @@ -51521,7 +51529,7 @@ index 9f35713ef5..3d9d8929f7 100644 do_del_port(dp, port); } ovs_rwlock_unlock(&dp->port_rwlock); -@@ -3006,7 +3007,7 @@ static void +@@ -3006,7 +3006,7 @@ static void queue_netdev_flow_put(struct dp_netdev_pmd_thread *pmd, struct dp_netdev_flow *flow, struct match *match, const struct nlattr *actions, size_t actions_len, @@ -51530,7 +51538,7 @@ index 9f35713ef5..3d9d8929f7 100644 { struct dp_offload_thread_item *item; struct dp_offload_flow_item *flow_offload; -@@ -3021,7 +3022,7 @@ queue_netdev_flow_put(struct dp_netdev_pmd_thread *pmd, +@@ -3021,7 +3021,7 @@ queue_netdev_flow_put(struct dp_netdev_pmd_thread *pmd, flow_offload->actions = xmalloc(actions_len); memcpy(flow_offload->actions, actions, actions_len); flow_offload->actions_len = actions_len; @@ -51539,7 +51547,7 @@ index 9f35713ef5..3d9d8929f7 100644 item->timestamp = pmd->ctx.now; dp_netdev_offload_flow_enqueue(item); -@@ -4095,6 +4096,7 @@ dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd, +@@ -4095,6 +4095,7 @@ dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd, flow->dead = false; flow->batch = NULL; flow->mark = INVALID_FLOW_MARK; @@ -51547,7 +51555,7 @@ index 9f35713ef5..3d9d8929f7 100644 *CONST_CAST(unsigned *, &flow->pmd_id) = pmd->core_id; *CONST_CAST(struct flow *, &flow->flow) = match->flow; *CONST_CAST(ovs_u128 *, &flow->ufid) = *ufid; -@@ -4129,7 +4131,7 @@ dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd, +@@ -4129,7 +4130,7 @@ dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd, } queue_netdev_flow_put(pmd, flow, match, actions, actions_len, @@ -51556,7 +51564,7 @@ index 9f35713ef5..3d9d8929f7 100644 log_netdev_flow_change(flow, match, NULL, actions, actions_len); return flow; -@@ -4171,7 +4173,7 @@ flow_put_on_pmd(struct dp_netdev_pmd_thread *pmd, +@@ -4171,7 +4172,7 @@ flow_put_on_pmd(struct dp_netdev_pmd_thread *pmd, ovsrcu_set(&netdev_flow->actions, new_actions); queue_netdev_flow_put(pmd, netdev_flow, match, @@ -51565,7 +51573,7 @@ index 9f35713ef5..3d9d8929f7 100644 DP_NETDEV_FLOW_OFFLOAD_OP_MOD); log_netdev_flow_change(netdev_flow, match, old_actions, put->actions, put->actions_len); -@@ -4778,8 +4780,8 @@ dpif_netdev_set_config(struct dpif *dpif, const struct smap *other_config) +@@ -4778,8 +4779,8 @@ dpif_netdev_set_config(struct dpif *dpif, const struct smap *other_config) uint32_t insert_min, cur_min; uint32_t tx_flush_interval, cur_tx_flush_interval; uint64_t rebalance_intvl; @@ -51576,7 +51584,7 @@ index 9f35713ef5..3d9d8929f7 100644 bool log_autolb = false; enum sched_assignment_type pmd_rxq_assign_type; -@@ -4880,8 +4882,12 @@ dpif_netdev_set_config(struct dpif *dpif, const struct smap *other_config) +@@ -4880,8 +4881,12 @@ dpif_netdev_set_config(struct dpif *dpif, const struct smap *other_config) struct pmd_auto_lb *pmd_alb = &dp->pmd_alb; @@ -51591,7 +51599,7 @@ index 9f35713ef5..3d9d8929f7 100644 /* Input is in min, convert it to msec. */ rebalance_intvl = -@@ -4894,21 +4900,21 @@ dpif_netdev_set_config(struct dpif *dpif, const struct smap *other_config) +@@ -4894,21 +4899,21 @@ dpif_netdev_set_config(struct dpif *dpif, const struct smap *other_config) log_autolb = true; } @@ -51619,7 +51627,7 @@ index 9f35713ef5..3d9d8929f7 100644 if (rebalance_load > 100) { rebalance_load = ALB_LOAD_THRESHOLD; } -@@ -4916,7 +4922,7 @@ dpif_netdev_set_config(struct dpif *dpif, const struct smap *other_config) +@@ -4916,7 +4921,7 @@ dpif_netdev_set_config(struct dpif *dpif, const struct smap *other_config) if (rebalance_load != cur_rebalance_load) { atomic_store_relaxed(&pmd_alb->rebalance_load_thresh, rebalance_load); @@ -51628,7 +51636,15 @@ index 9f35713ef5..3d9d8929f7 100644 rebalance_load); log_autolb = true; } -@@ -5684,23 +5690,28 @@ sched_numa_list_put_in_place(struct sched_numa_list *numa_list) +@@ -5425,7 +5430,6 @@ port_reconfigure(struct dp_netdev_port *port) + + port->rxqs[i].port = port; + port->rxqs[i].is_vhost = !strncmp(port->type, "dpdkvhost", 9); +- port->rxqs[i].hw_miss_api_supported = true; + + err = netdev_rxq_open(netdev, &port->rxqs[i].rx, i); + if (err) { +@@ -5684,23 +5688,28 @@ sched_numa_list_put_in_place(struct sched_numa_list *numa_list) } } @@ -51662,7 +51678,7 @@ index 9f35713ef5..3d9d8929f7 100644 rxq->pmd->numa_id != netdev_get_numa_id(rxq->port->netdev)) { return true; -@@ -6000,10 +6011,10 @@ sched_numa_list_schedule(struct sched_numa_list *numa_list, +@@ -6000,10 +6009,10 @@ sched_numa_list_schedule(struct sched_numa_list *numa_list, /* Find any numa with available PMDs. */ for (int j = 0; j < n_numa; j++) { numa = sched_numa_list_next(numa_list, last_cross_numa); @@ -51674,7 +51690,7 @@ index 9f35713ef5..3d9d8929f7 100644 numa = NULL; } } -@@ -6111,7 +6122,7 @@ sched_numa_list_variance(struct sched_numa_list *numa_list) +@@ -6111,7 +6120,7 @@ sched_numa_list_variance(struct sched_numa_list *numa_list) * pmd_rebalance_dry_run() can be avoided when it is not needed. */ static bool @@ -51683,7 +51699,7 @@ index 9f35713ef5..3d9d8929f7 100644 OVS_REQ_RDLOCK(dp->port_rwlock) { struct dp_netdev_pmd_thread *pmd; -@@ -6342,11 +6353,11 @@ pmd_remove_stale_ports(struct dp_netdev *dp, +@@ -6342,11 +6351,11 @@ pmd_remove_stale_ports(struct dp_netdev *dp, OVS_EXCLUDED(pmd->port_mutex) OVS_REQ_RDLOCK(dp->port_rwlock) { @@ -51698,7 +51714,7 @@ index 9f35713ef5..3d9d8929f7 100644 struct dp_netdev_port *port = poll->rxq->port; if (port->need_reconfigure -@@ -6354,7 +6365,7 @@ pmd_remove_stale_ports(struct dp_netdev *dp, +@@ -6354,7 +6363,7 @@ pmd_remove_stale_ports(struct dp_netdev *dp, dp_netdev_del_rxq_from_pmd(pmd, poll); } } @@ -51707,7 +51723,7 @@ index 9f35713ef5..3d9d8929f7 100644 struct dp_netdev_port *port = tx->port; if (port->need_reconfigure -@@ -6430,8 +6441,7 @@ reconfigure_datapath(struct dp_netdev *dp) +@@ -6430,8 +6439,7 @@ reconfigure_datapath(struct dp_netdev *dp) /* We only reconfigure the ports that we determined above, because they're * not being used by any pmd thread at the moment. If a port fails to * reconfigure we remove it from the datapath. */ @@ -51717,7 +51733,7 @@ index 9f35713ef5..3d9d8929f7 100644 int err; if (!port->need_reconfigure) { -@@ -6487,10 +6497,10 @@ reconfigure_datapath(struct dp_netdev *dp) +@@ -6487,10 +6495,10 @@ reconfigure_datapath(struct dp_netdev *dp) } CMAP_FOR_EACH (pmd, node, &dp->poll_threads) { @@ -51730,7 +51746,7 @@ index 9f35713ef5..3d9d8929f7 100644 if (poll->rxq->pmd != pmd) { dp_netdev_del_rxq_from_pmd(pmd, poll); -@@ -6682,7 +6692,7 @@ dpif_netdev_run(struct dpif *dpif) +@@ -6682,7 +6690,7 @@ dpif_netdev_run(struct dpif *dpif) if (pmd_rebalance && !dp_netdev_is_reconf_required(dp) && !ports_require_restart(dp) && @@ -51739,7 +51755,7 @@ index 9f35713ef5..3d9d8929f7 100644 pmd_rebalance_dry_run(dp)) { VLOG_INFO("PMD auto load balance dry run. " "Requesting datapath reconfigure."); -@@ -7364,15 +7374,15 @@ static struct dp_netdev_pmd_thread * +@@ -7364,15 +7372,15 @@ static struct dp_netdev_pmd_thread * dp_netdev_get_pmd(struct dp_netdev *dp, unsigned core_id) { struct dp_netdev_pmd_thread *pmd; @@ -51761,7 +51777,7 @@ index 9f35713ef5..3d9d8929f7 100644 } /* Sets the 'struct dp_netdev_pmd_thread' for non-pmd threads. */ -@@ -7505,6 +7515,7 @@ dp_netdev_destroy_pmd(struct dp_netdev_pmd_thread *pmd) +@@ -7505,6 +7513,7 @@ dp_netdev_destroy_pmd(struct dp_netdev_pmd_thread *pmd) seq_destroy(pmd->reload_seq); ovs_mutex_destroy(&pmd->port_mutex); ovs_mutex_destroy(&pmd->bond_mutex); @@ -51769,6 +51785,31 @@ index 9f35713ef5..3d9d8929f7 100644 free(pmd); } +@@ -8020,17 +8029,15 @@ dp_netdev_hw_flow(const struct dp_netdev_pmd_thread *pmd, + #ifdef ALLOW_EXPERIMENTAL_API /* Packet restoration API required. */ + /* Restore the packet if HW processing was terminated before completion. */ + struct dp_netdev_rxq *rxq = pmd->ctx.last_rxq; ++ bool miss_api_supported; + +- if (rxq->hw_miss_api_supported) { ++ atomic_read_relaxed(&rxq->port->netdev->hw_info.miss_api_supported, ++ &miss_api_supported); ++ if (miss_api_supported) { + int err = netdev_hw_miss_packet_recover(rxq->port->netdev, packet); +- if (err) { +- if (err != EOPNOTSUPP) { +- COVERAGE_INC(datapath_drop_hw_miss_recover); +- return -1; +- } else { +- /* API unsupported by the port; avoid subsequent calls. */ +- rxq->hw_miss_api_supported = false; +- } ++ if (err && err != EOPNOTSUPP) { ++ COVERAGE_INC(datapath_drop_hw_miss_recover); ++ return -1; + } + } + #endif diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index 71e35ccdda..484545cfb8 100644 --- a/lib/dpif-netlink.c @@ -53747,11 +53788,81 @@ index 9845e8d3fe..93321989a9 100644 } } +diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c +index fb108c0d50..eea8fadc0e 100644 +--- a/lib/netdev-offload.c ++++ b/lib/netdev-offload.c +@@ -182,6 +182,7 @@ netdev_assign_flow_api(struct netdev *netdev) + CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) { + if (!rfa->flow_api->init_flow_api(netdev)) { + ovs_refcount_ref(&rfa->refcnt); ++ atomic_store_relaxed(&netdev->hw_info.miss_api_supported, true); + ovsrcu_set(&netdev->flow_api, rfa->flow_api); + VLOG_INFO("%s: Assigned flow API '%s'.", + netdev_get_name(netdev), rfa->flow_api->type); +@@ -190,6 +191,7 @@ netdev_assign_flow_api(struct netdev *netdev) + VLOG_DBG("%s: flow API '%s' is not suitable.", + netdev_get_name(netdev), rfa->flow_api->type); + } ++ atomic_store_relaxed(&netdev->hw_info.miss_api_supported, false); + VLOG_INFO("%s: No suitable flow API found.", netdev_get_name(netdev)); + + return -1; +@@ -263,12 +265,28 @@ int + netdev_hw_miss_packet_recover(struct netdev *netdev, + struct dp_packet *packet) + { +- const struct netdev_flow_api *flow_api = +- ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); ++ const struct netdev_flow_api *flow_api; ++ bool miss_api_supported; ++ int rv; ++ ++ atomic_read_relaxed(&netdev->hw_info.miss_api_supported, ++ &miss_api_supported); ++ if (!miss_api_supported) { ++ return EOPNOTSUPP; ++ } ++ ++ flow_api = ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); ++ if (!flow_api || !flow_api->hw_miss_packet_recover) { ++ return EOPNOTSUPP; ++ } ++ ++ rv = flow_api->hw_miss_packet_recover(netdev, packet); ++ if (rv == EOPNOTSUPP) { ++ /* API unsupported by the port; avoid subsequent calls. */ ++ atomic_store_relaxed(&netdev->hw_info.miss_api_supported, false); ++ } + +- return (flow_api && flow_api->hw_miss_packet_recover) +- ? flow_api->hw_miss_packet_recover(netdev, packet) +- : EOPNOTSUPP; ++ return rv; + } + + int diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h -index 8237a85ddb..93eb2df48b 100644 +index 8237a85ddb..13ab06d116 100644 --- a/lib/netdev-offload.h +++ b/lib/netdev-offload.h -@@ -65,9 +65,6 @@ struct netdev_flow_dump { +@@ -20,6 +20,7 @@ + + #include "openvswitch/netdev.h" + #include "openvswitch/types.h" ++#include "ovs-atomic.h" + #include "ovs-rcu.h" + #include "ovs-thread.h" + #include "packets.h" +@@ -45,6 +46,7 @@ struct ovs_action_push_tnl; + /* Offload-capable (HW) netdev information */ + struct netdev_hw_info { + bool oor; /* Out of Offload Resources ? */ ++ atomic_bool miss_api_supported; /* hw_miss_packet_recover() supported.*/ + int offload_count; /* Pending (non-offloaded) flow count */ + int pending_count; /* Offloaded flow count */ + OVSRCU_TYPE(void *) offload_data; /* Offload metadata. */ +@@ -65,9 +67,6 @@ struct netdev_flow_dump { /* Flow offloading. */ struct offload_info { @@ -53762,7 +53873,7 @@ index 8237a85ddb..93eb2df48b 100644 * sync with datapath recirc ids. */ diff --git a/lib/netdev.c b/lib/netdev.c -index 8305f6c427..ce0d4117ac 100644 +index 8305f6c427..c797783782 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -387,25 +387,30 @@ netdev_open(const char *name, const char *type, struct netdev **netdevp) @@ -53814,6 +53925,14 @@ index 8305f6c427..ce0d4117ac 100644 } } +@@ -426,6 +431,7 @@ netdev_open(const char *name, const char *type, struct netdev **netdevp) + seq_read(netdev->reconfigure_seq); + ovsrcu_set(&netdev->flow_api, NULL); + netdev->hw_info.oor = false; ++ atomic_init(&netdev->hw_info.miss_api_supported, false); + netdev->node = shash_add(&netdev_shash, name, netdev); + + /* By default enable one tx and rx queue per netdev. */ diff --git a/lib/odp-util.c b/lib/odp-util.c index 9a705cffa3..2d2a6893c6 100644 --- a/lib/odp-util.c @@ -56224,6 +56343,44 @@ index 58269d3b16..050eafa6b8 100644 char dev_name[IFNAMSIZ]; if (ip_dev->change_seq == netdev_get_change_seq(ip_dev->dev)) { +diff --git a/lib/unaligned.h b/lib/unaligned.h +index f40e4e10df..15334e3c76 100644 +--- a/lib/unaligned.h ++++ b/lib/unaligned.h +@@ -95,7 +95,7 @@ GCC_UNALIGNED_ACCESSORS(ovs_be64, be64); + static inline uint16_t get_unaligned_u16(const uint16_t *p_) + { + const uint8_t *p = (const uint8_t *) p_; +- return ntohs((p[0] << 8) | p[1]); ++ return ntohs(((uint16_t) p[0] << 8) | (uint16_t) p[1]); + } + + static inline void put_unaligned_u16(uint16_t *p_, uint16_t x_) +@@ -110,7 +110,8 @@ static inline void put_unaligned_u16(uint16_t *p_, uint16_t x_) + static inline uint32_t get_unaligned_u32(const uint32_t *p_) + { + const uint8_t *p = (const uint8_t *) p_; +- return ntohl((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); ++ return ntohl(((uint32_t) p[0] << 24) | ((uint32_t) p[1] << 16) | ++ ((uint32_t) p[2] << 8) | (uint32_t) p[3]); + } + + static inline void put_unaligned_u32(uint32_t *p_, uint32_t x_) +@@ -131,10 +132,10 @@ static inline uint64_t get_unaligned_u64__(const uint64_t *p_) + | ((uint64_t) p[1] << 48) + | ((uint64_t) p[2] << 40) + | ((uint64_t) p[3] << 32) +- | (p[4] << 24) +- | (p[5] << 16) +- | (p[6] << 8) +- | p[7]); ++ | ((uint64_t) p[4] << 24) ++ | ((uint64_t) p[5] << 16) ++ | ((uint64_t) p[6] << 8) ++ | (uint64_t) p[7]); + } + + static inline void put_unaligned_u64__(uint64_t *p_, uint64_t x_) diff --git a/lib/unixctl.c b/lib/unixctl.c index 69aed6722c..103357ee91 100644 --- a/lib/unixctl.c @@ -60515,9 +60672,47 @@ index 00e3a46b8b..b6155af253 100644 AT_CLEANUP diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at -index a79ebdb618..3179e1645d 100644 +index a79ebdb618..6aff1eda7b 100644 --- a/tests/dpif-netdev.at +++ b/tests/dpif-netdev.at +@@ -6,8 +6,8 @@ m4_divert_push([PREPARE_TESTS]) + # that vary from one run to another (e.g., timing and bond actions). + strip_timers () { + sed ' +- s/duration:[0-9]*\.[0-9]*/duration:0.0/ +- s/used:[0-9]*\.[0-9]*/used:0.0/ ++ s/duration:[0-9\.][0-9\.]*/duration:0.0/ ++ s/used:[0-9\.][0-9\.]*/used:0.0/ + ' + } + +@@ -15,7 +15,7 @@ strip_xout () { + sed ' + s/mega_ufid:[-0-9a-f]* // + s/ufid:[-0-9a-f]* // +- s/used:[0-9]*\.[0-9]*/used:0.0/ ++ s/used:[0-9\.][0-9\.]*/used:0.0/ + s/actions:.*/actions: / + s/packets:[0-9]*/packets:0/ + s/bytes:[0-9]*/bytes:0/ +@@ -26,7 +26,7 @@ strip_xout_keep_actions () { + sed ' + s/mega_ufid:[-0-9a-f]* // + s/ufid:[-0-9a-f]* // +- s/used:[0-9]*\.[0-9]*/used:0.0/ ++ s/used:[0-9\.][0-9\.]*/used:0.0/ + s/packets:[0-9]*/packets:0/ + s/bytes:[0-9]*/bytes:0/ + ' | sort +@@ -51,7 +51,7 @@ filter_hw_packet_netdev_dummy () { + filter_flow_dump () { + grep 'flow_dump ' | sed ' + s/.*flow_dump // +- s/used:[0-9]*\.[0-9]*/used:0.0/ ++ s/used:[0-9\.][0-9\.]*/used:0.0/ + ' | sort | uniq + } + @@ -439,7 +439,7 @@ recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), a # Check for succesfull packet matching with installed offloaded flow. @@ -63660,6 +63855,19 @@ index 0f74709f5a..5bca84351c 100644 run should send probe in IDLE for 0 ms (1000 ms backoff) +diff --git a/tests/stp.at b/tests/stp.at +index 7ddacfc3a0..69475843e5 100644 +--- a/tests/stp.at ++++ b/tests/stp.at +@@ -368,7 +368,7 @@ AT_CLEANUP + # Strips out uninteresting parts of flow output, as well as parts + # that vary from one run to another (e.g., timing and bond actions). + m4_define([STRIP_USED], [[sed ' +- s/used:[0-9]*\.[0-9]*/used:0.0/ ++ s/used:[0-9\.][0-9\.]*/used:0.0/ + s/duration=[0-9.]*s*/duration=Xs/ + s/idle_age=[0-9]*,/idle_age=X,/ + ']]) diff --git a/tests/system-common-macros.at b/tests/system-common-macros.at index 19a0b125b9..8b9f5c7525 100644 --- a/tests/system-common-macros.at diff --git a/SPECS/openvswitch2.17.spec b/SPECS/openvswitch2.17.spec index 1ef6684..4a48628 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: 51%{?dist} +Release: 52%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -748,6 +748,14 @@ exit 0 %endif %changelog +* Wed Oct 26 2022 Open vSwitch CI - 2.17.0-52 +- Merging upstream branch-2.17 [RH git: 2e56cd8bfd] + Commit list: + d0276481a1 unaligned: Correct the stats of packet_count and byte_count on Windows. + 71401199ff tests: Fix filtering of whole-second durations. + 3c1c034e58 netdev-offload: Set 'miss_api_supported' to be under netdev. + + * Tue Oct 18 2022 Open vSwitch CI - 2.17.0-51 - Merging upstream branch-2.17 [RH git: 8ffcf35d65] Commit list: