get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2227838/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2227838,
    "url": "http://patchwork.ozlabs.org/api/patches/2227838/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260424103917.248668-2-den@openvz.org/",
    "project": {
        "id": 14,
        "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api",
        "name": "QEMU Development",
        "link_name": "qemu-devel",
        "list_id": "qemu-devel.nongnu.org",
        "list_email": "qemu-devel@nongnu.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260424103917.248668-2-den@openvz.org>",
    "list_archive_url": null,
    "date": "2026-04-24T10:39:16",
    "name": "[1/2] block/graph-lock: fix missed wakeup in bdrv_graph_co_rdunlock()",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "617a48f0698d527e673602c52a5c88d381586c87",
    "submitter": {
        "id": 71296,
        "url": "http://patchwork.ozlabs.org/api/people/71296/?format=api",
        "name": "Denis V. Lunev\" via qemu development",
        "email": "qemu-devel@nongnu.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260424103917.248668-2-den@openvz.org/mbox/",
    "series": [
        {
            "id": 501343,
            "url": "http://patchwork.ozlabs.org/api/series/501343/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=501343",
            "date": "2026-04-24T10:39:16",
            "name": "block: fix two missed-wakeup hangs on shutdown path",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/501343/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2227838/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2227838/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n secure) header.d=virtuozzo.com header.i=@virtuozzo.com header.a=rsa-sha256\n header.s=relay header.b=SPlzZmOb;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"
        ],
        "Received": [
            "from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g28bh2vqyz1yD5\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 24 Apr 2026 20:39:44 +1000 (AEST)",
            "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wGDwV-0002c7-3N; Fri, 24 Apr 2026 06:39:27 -0400",
            "from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <den@openvz.org>)\n id 1wGDwT-0002ai-Br; Fri, 24 Apr 2026 06:39:25 -0400",
            "from relay.virtuozzo.com ([130.117.225.111])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <den@openvz.org>)\n id 1wGDwR-0001zz-7M; Fri, 24 Apr 2026 06:39:25 -0400",
            "from ch-demo-asa.virtuozzo.com ([130.117.225.8] helo=iris.sw.ru)\n by relay.virtuozzo.com with esmtp (Exim 4.96)\n (envelope-from <den@openvz.org>) id 1wGDtf-00F3Ps-1J;\n Fri, 24 Apr 2026 12:39:15 +0200"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n d=virtuozzo.com; s=relay; h=MIME-Version:Message-ID:Date:Subject:From:\n Content-Type; bh=0rF0i4tPGZ/wx4pJf8mTyDIVzwqbQMZM1Dp9RCapltc=; b=SPlzZmObKbiZ\n gC+fKyfTr2oJ1itRsdCycNSYt+z/wtX0BXG/JkAnJypFbUF2/K4x2POIKP78cqJAjz4f2rafPHa/N\n +ju7yQIrxTPOY+tN9QEgurL9iAvB5A1+Kfu1T4VJxiwN+ckM41VgMhKR5xxAFUsZksoWoOtK8auW0\n dkQAw84bb8GeauihKqhY9Y4TiSEFnQxdjvO6szqhut5t4aJe/sjgM5BTUHemeoorDau9yBiGh8FCc\n e2riJdWT8zUR8F6a0gnQUBuL7HhumiikGNhs4xvH2hvt5CzztDoALlQuJN6hQHhajyRDOSgC+garS\n izQRbNPOQlrwhFuTROSwCg==;",
        "To": "qemu-devel@nongnu.org",
        "Cc": "qemu-block@nongnu.org, qemu-stable@nongnu.org,\n \"Denis V. Lunev\" <den@openvz.org>, Kevin Wolf <kwolf@redhat.com>,\n Hanna Reitz <hreitz@redhat.com>, Stefan Hajnoczi <stefanha@redhat.com>,\n Fiona Ebner <f.ebner@proxmox.com>",
        "Subject": "[PATCH 1/2] block/graph-lock: fix missed wakeup in\n bdrv_graph_co_rdunlock()",
        "Date": "Fri, 24 Apr 2026 12:39:16 +0200",
        "Message-ID": "<20260424103917.248668-2-den@openvz.org>",
        "X-Mailer": "git-send-email 2.51.0",
        "In-Reply-To": "<20260424103917.248668-1-den@openvz.org>",
        "References": "<20260424103917.248668-1-den@openvz.org>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Received-SPF": "softfail client-ip=130.117.225.111;\n envelope-from=den@openvz.org;\n helo=relay.virtuozzo.com",
        "X-Spam_score_int": "-34",
        "X-Spam_score": "-3.5",
        "X-Spam_bar": "---",
        "X-Spam_report": "(-3.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001,\n SPF_SOFTFAIL=0.665 autolearn=ham autolearn_force=no",
        "X-Spam_action": "no action",
        "X-BeenThere": "qemu-devel@nongnu.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "qemu development <qemu-devel.nongnu.org>",
        "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>",
        "List-Post": "<mailto:qemu-devel@nongnu.org>",
        "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>",
        "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>",
        "Reply-to": "\"Denis V. Lunev\" <den@openvz.org>",
        "From": "\"Denis V. Lunev\" via qemu development <qemu-devel@nongnu.org>",
        "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org",
        "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"
    },
    "content": "tests/qemu-iotests/tests/iothreads-create reproduces the hang on\nmaster under `stress-ng --cpu $(nproc) --timeout 0`.  The iotest's\nvm.run_job() times out and qemu stays permanently stuck in\nppoll(timeout=-1) inside bdrv_graph_wrlock_drained -> blk_remove_bs\nduring qemu_cleanup().  The timing window is narrow on modern\nbare-metal hardware and much wider in a VM guest; downstream trees\nthat still use plain bdrv_graph_wrlock() in blk_remove_bs() hit it\non the first iteration under the same stress.\n\nbdrv_graph_wrlock() zeroes has_writer around its AIO_WAIT_WHILE loop\nso that callbacks dispatched by aio_poll() can still take the read\nlock on the fast path.  The rdunlock side, however, only kicks a\nwaiting writer when has_writer is observed set; a reader that drops\nits lock inside the polling window silently returns and nothing ever\nwakes the writer:\n\n  main thread                         iothread0 coroutine\n  -----------                         -------------------\n  bdrv_graph_wrlock:                  rdlock held, reader_count=1\n    bdrv_drain_all_begin_nopoll\n    has_writer = 0\n    AIO_WAIT_WHILE_UNLOCKED(\n        NULL, reader_count >= 1):\n      num_waiters++\n      smp_mb\n      aio_poll(main_ctx, true)   -->  bdrv_graph_co_rdunlock:\n        (ppoll, blocked)                reader_count-- -> 0\n                                        smp_mb\n                                        read has_writer = 0\n                                        skip aio_wait_kick()\n                                      return\n\nreader_count is now 0 and num_waiters is still 1, but no BH, fd or\ntimer on the main AioContext will fire -- the only entity that could\nkick just decided it did not have to.  Main stays in ppoll() holding\nBQL, so RCU, VCPUs and any iothread path that needs BQL stall behind\nit.  The hang is final; no timeout, no forward progress, no recovery\nas there is no other source of wake up inside qemu_cleanup().\n\nbdrv_drain_all_begin() does not close the race on its own: it\nquiesces in-flight I/O, but graph readers also include non-I/O\ncoroutines (block-job cleanup, virtio-scsi polling) that drain does\nnot evict.  The bdrv_graph_wrlock_drained() wrapper narrows the\nwindow but does not eliminate it; every plain bdrv_graph_wrlock()\nsite is exposed on the same basis.\n\nDrop the has_writer check in bdrv_graph_co_rdunlock() and call\naio_wait_kick() unconditionally.  The helper itself loads num_waiters\natomically and only schedules a dummy BH when a waiter exists, so the\nchange is a no-op on the no-writer path and closes the missed-wakeup\non the writer path.\n\nSigned-off-by: Denis V. Lunev <den@openvz.org>\nCc: Kevin Wolf <kwolf@redhat.com>\nCc: Hanna Reitz <hreitz@redhat.com>\nCc: Stefan Hajnoczi <stefanha@redhat.com>\nCc: Fiona Ebner <f.ebner@proxmox.com>\n---\n block/graph-lock.c | 12 +++++-------\n 1 file changed, 5 insertions(+), 7 deletions(-)",
    "diff": "diff --git a/block/graph-lock.c b/block/graph-lock.c\nindex b7319473a1..f2501d75fb 100644\n--- a/block/graph-lock.c\n+++ b/block/graph-lock.c\n@@ -278,14 +278,12 @@ void coroutine_fn bdrv_graph_co_rdunlock(void)\n     smp_mb();\n \n     /*\n-     * has_writer == 0: this means reader will read reader_count decreased\n-     * has_writer == 1: we don't know if writer read reader_count old or\n-     *                  new. Therefore, kick again so on next iteration\n-     *                  writer will for sure read the updated value.\n+     * Always kick: bdrv_graph_wrlock() zeroes has_writer while polling (to\n+     * let callbacks take the reader lock via the fast path), so we cannot\n+     * rely on has_writer to detect a waiting writer. aio_wait_kick() is a\n+     * no-op when no one is waiting, so it is cheap in the common case.\n      */\n-    if (qatomic_read(&has_writer)) {\n-        aio_wait_kick();\n-    }\n+    aio_wait_kick();\n }\n \n void bdrv_graph_rdlock_main_loop(void)\n",
    "prefixes": [
        "1/2"
    ]
}