From nobody Sat Sep 26 21:37:39 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=bytedance.com ARC-Seal: i=1; a=rsa-sha256; t=1787574472; cv=none; d=zohomail.com; s=zohoarc; b=aAWLuIGbjrBho+OCV1VTS/b3g09Cq+ZtgDM07i9SSyXkLlGx0xBZC+XXfQzGW32YA1Mkw3LojQWmcIpScI8Y359qHxmHMx2Mslr1AaFX3l2AyxTr8HSXkipyZUc0+DssH4h8keFRMCcSkHRovJuNj0vaIGSa+x4bpWaUpB1c+/Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787574472; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=5e28Y5s6epPrp4ARipdNeMVPNC+1pKrudq/1/HJ+wZA=; b=TsB+i7f9/gkx2ZyjgryHn7j1x0XXZeLKdSeNBG14w9oW5j8AzPdq6KpMv5xyhOb/xdPx2J3qlWNPpiYMh52ibYgm4oEPgwF8uJVBdVMYjjZhq5lo7iAMB221susoBj5Sg7wNcqKtcd6gn3tr42SN+RPdLEHzChkScJS9k/f1JPo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787574472325493.2931399421153; Mon, 24 Aug 2026 05:27:52 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wyTm4-00025A-Um; Mon, 24 Aug 2026 08:27:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyTm2-00024Y-2p for qemu-devel@nongnu.org; Mon, 24 Aug 2026 08:27:34 -0400 Received: from va-2-114.ptr.blmpb.com ([209.127.231.114]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wyTly-0007mC-1h for qemu-devel@nongnu.org; Mon, 24 Aug 2026 08:27:33 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=2212171451; d=bytedance.com; t=1787574432; h=from:subject: mime-version:from:date:message-id:subject:to:cc:reply-to:content-type: mime-version:in-reply-to:message-id; bh=5e28Y5s6epPrp4ARipdNeMVPNC+1pKrudq/1/HJ+wZA=; b=encuA2T7hUOGUis2NkaLkdFFevd/4vsSe4UMPnleAWVp1xu7dvOrIWCS+qWZse0pNHSQed NcJId4n4hNJ9u2eB7FrYwR6glbsXn0Hgta1zRM/xictldGGFxndcWY6DZu044sUPI3zzx2 cNR4j8hasxgVdAltJAnz3SwzlHtSDmQBYvh89HqZ5S+5nnKkNQbdDwtTSFQrDAL6qX1uK0 ccYWwzYjLUAQyPR4ODsZBMdzC50gVB77nXBCy2yuZpKEWctkaNC+Tca5r434Bz2MMQe0Tq QGrrUddf06JFyCKHOaAmBmuJkpGLo1q7WJOcxx4RBXADSoWISs5rVbG/ZftiSw== To: Cc: , , , , "hongmianquan" From: "hongmianquan" Mime-Version: 1.0 X-Mailer: git-send-email 2.50.1 Content-Transfer-Encoding: quoted-printable X-Original-From: hongmianquan Date: Mon, 24 Aug 2026 20:26:56 +0800 Message-Id: <20260824122655.63646-2-hongmianquan@bytedance.com> X-Lms-Return-Path: Subject: [RFC v1] migration/postcopy: fix page_requested leak for vhost-user shared pages Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=209.127.231.114; envelope-from=hongmianquan@bytedance.com; helo=va-2-114.ptr.blmpb.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @bytedance.com) X-ZM-MESSAGEID: 1787574473917158500 Content-Type: text/plain; charset="utf-8" With postcopy-preempt enabled, a postcopy migration of a guest with a vhost-user device can hang at the very end on the destination, after all pages are transferred (query-migrate: status=3Dpostcopy-active, remaining= =3D0). Root cause is an add/del key mismatch on mis->page_requested: - add: a backend fault goes through postcopy_request_shared_page() -> postcopy_request_page() -> migrate_send_rp_req_pages(), which inserts the request and bumps page_requested_count keyed by client_addr. - del: qemu_ufd_copy_ioctl() removes the entry and drops the counter keyed by this QEMU process's host address for the page. client_addr is a VA in the external vhost-user backend's address space and never equals QEMU's host address, so the removal misses and the counter leaks. postcopy_ram_incoming_cleanup() then waits for it to reach zero forever, which also stalls the source (it waits for the return path). Racing threads: dst: postcopy_ram_listen_thread -> postcopy_ram_incoming_cleanup -> qemu_cond_wait_impl (waits for page_requested_count=3D= =3D0) (postcopy_preempt_thread already placed/woke the pages) src: migration_thread -> migration_completion -> await_return_path_close_on_source -> qemu_thread_join (source_return_path_thread blocked in recvmsg) The leak is only triggered when the vhost-user backend faults on a page that has not been received yet: only then does the request take the shared-fault slow path and register an entry in page_requested. If that page is subsequently delivered while the request is still outstanding, its entry is never removed. (Pages already present when the backend faults just take the wake path and never register.) So a run may leak only a few entries (9 of ~244k requests in our repro) yet still hang. Fix: key the request with the same host address the removal uses (rb->host + aligned_rbo) instead of client_addr. The backend wake still happens at placement time via postcopy_wake_shared(). Signed-off-by: hongmianquan Reviewed-by: Peter Xu --- migration/postcopy-ram.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c index a3314d3180..98268b3c55 100644 --- a/migration/postcopy-ram.c +++ b/migration/postcopy-ram.c @@ -992,7 +992,20 @@ int postcopy_request_shared_page(struct PostCopyFD *pc= fd, RAMBlock *rb, return postcopy_wake_shared(pcfd, client_addr, rb); } /* TODO: support blocktime tracking */ - postcopy_request_page(mis, rb, aligned_rbo, client_addr, 0); + + /* + * The page will be placed by qemu_ufd_copy_ioctl(), which removes the + * matching entry from mis->page_requested (and drops + * page_requested_count) using this QEMU process's host address for the + * page. Register the request with the same key, rb->host + aligned_rb= o, + * not client_addr: client_addr is a VA in the external vhost-user + * backend's address space and can never equal that host address, so t= he + * removal would miss forever, leaking page_requested_count and hanging + * postcopy teardown. + */ + postcopy_request_page(mis, rb, aligned_rbo, + (uint64_t)(uintptr_t)qemu_ram_get_host_addr(rb) + + aligned_rbo, 0); return 0; } =20 --=20 2.50.1 (Apple Git-155)