]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/.../client_request: work around gcc bz101244 and bz102217
authorSamuel Just <sjust@redhat.com>
Fri, 9 Feb 2024 02:45:43 +0000 (18:45 -0800)
committerMatan Breizman <mbreizma@redhat.com>
Thu, 16 May 2024 11:39:18 +0000 (14:39 +0300)
See included comment for details.

Signed-off-by: Samuel Just <sjust@redhat.com>
(cherry picked from commit 90dcbfa0fa9d8a46f8075a7e6f2329652f0a312f)

src/crimson/osd/osd_operations/client_request.cc

index 22c32dd4e50aee7669b9fb2b8131421057074e45..c48a4cefc999acdc783bdf8251c8f6b5b2fa87db 100644 (file)
@@ -144,8 +144,25 @@ ClientRequest::interruptible_future<> ClientRequest::with_pg_process_interruptib
   DEBUGDPP("{}.{}: pg active, entering process[_pg]_op",
           *pgref, *this, this_instance_id);
 
-  co_await (is_pg_op() ? process_pg_op(pgref) :
-           process_op(ihref, pgref, this_instance_id));
+  {
+    /* The following works around two different gcc bugs:
+     *  1. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101244
+     *     This example isn't preciesly as described in the bug, but it seems
+     *     similar.  It causes the generated code to incorrectly execute
+     *     process_pg_op unconditionally before the predicate.  It seems to be
+     *     fixed in gcc 12.2.1.
+     *  2. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102217
+     *     This one appears to cause the generated code to double-free
+     *     awaiter holding the future.  This one seems to be fixed
+     *     in gcc 13.2.1.
+     *
+     * Assigning the intermediate result and moving it into the co_await
+     * expression bypasses both bugs.
+     */
+    auto fut = (is_pg_op() ? process_pg_op(pgref) :
+               process_op(ihref, pgref, this_instance_id));
+    co_await std::move(fut);
+  }
 
   DEBUGDPP("{}.{}: process[_pg]_op complete, completing handle",
           *pgref, *this, this_instance_id);