From nobody Tue Sep 15 06:00:35 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) client-ip=38.145.34.151; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1788340777; cv=none; d=zohomail.com; s=zohoarc; b=k1sJK0lIS6lJrsTerwWaoIZAK68NS4SpKImlwr3AQh9tqOQQNqBz2XFZD95obpiFUkEufpOVOtQA5QdJy0llcMBcWIdzV/O7imT9rh6FXTTDpqQnR8H/lUruQvvh8n5SiXxtthraXTXFcJ/B8U+BRwuU543Tnd9WdFvrtrIPiMA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788340777; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=KEGV+wSVn/bj+P4oCfwr5RHpdNxnI408WVuWKYtwO5Y=; b=M6JBI2RxwH6ynSVavp7VJonJr1y7c0GF8A565VmPhP8z+/+XQcEMwrNUkKryXmRan/yrDoSVBtIix6JcuR+gALT4YdSyp5LEQwK20i8UwwsyLtiWE38WH8JCOQmb1Bqtjv0Ds+08K01zrWpGuQ3NQ6CK3gGr26lhVPLCku/2y/8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1788340777616743.0323813022974; Wed, 2 Sep 2026 02:19:37 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 4B0104187B; Wed, 2 Sep 2026 05:19:36 -0400 (EDT) Received: from [172.19.199.13] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id 7ABC941C3B for ; Wed, 2 Sep 2026 05:10:41 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 5EE5E3F383; Mon, 31 Aug 2026 08:02:09 -0400 (EDT) Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 82DBD3F36E for ; Mon, 31 Aug 2026 08:02:07 -0400 (EDT) Received: from pps.filterd (m0360072.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67VBVf0U2141447 for ; Mon, 31 Aug 2026 12:02:06 GMT Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4gbq2t0vc7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 31 Aug 2026 12:02:06 +0000 (GMT) Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 67VBuNDY016421 for ; Mon, 31 Aug 2026 12:02:05 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4gcarjwq00-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 31 Aug 2026 12:02:05 +0000 (GMT) Received: from smtpav03.fra02v.mail.ibm.com (smtpav03.fra02v.mail.ibm.com [10.20.54.102]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 67VC213E34734484 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 31 Aug 2026 12:02:01 GMT Received: from smtpav03.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 700402004F; Mon, 31 Aug 2026 12:02:01 +0000 (GMT) Received: from smtpav03.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4F04D20063; Mon, 31 Aug 2026 12:02:01 +0000 (GMT) Received: from li-d2cd37cc-2ca3-11b2-a85c-84ed3706e5a0.ibm.com (unknown [9.111.4.184]) by smtpav03.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 31 Aug 2026 12:02:01 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=KEGV+wSVn/bj+P4oC fwr5RHpdNxnI408WVuWKYtwO5Y=; b=s48Y19hxzzn5DRa4/cSeWP2wNu0wGO7Fe Sj3f6C6Ddkc9Bc+Ti2b3cC93bcnI0AqlsaSDivzg2OeRekcFByjhDL/b7d3NIzqn 726hzC6ilq6WfpSc7/FXEOYG2E66e8+3LKWZdog5+hspobgZcgRz3SF6lxij2oa4 SmguV8Hk5oxo9S0jFP+izfIFln1tXHPHoKtxE50qxbaY5e2taF0DcLgPK942rP1Z DsdkBDpsfsYEUw7sUq9f861eHb5xOLYeIm9i3a7wNnPdfRB7uj+leXEA9jqEYer3 DnRnR75LJEi0q8zGN4DBWq3O/ml9oGDB+mubMdFXEVM/2EgBtvuZw== From: Ilya Leoshkevich To: devel@lists.libvirt.org Subject: [PATCH 1/2] qemu: Fix hot plugged host CPUs not being used Date: Mon, 31 Aug 2026 13:58:51 +0200 Message-ID: <20260831120150.2827673-2-iii@linux.ibm.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260831120150.2827673-1-iii@linux.ibm.com> References: <20260831120150.2827673-1-iii@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=bc1bluPB c=1 sm=1 tr=0 ts=6a956d3e cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=RzCfie-kr_QcCd8fBx8p:22 a=VnNF1IyMAAAA:8 a=9OmLsDsfnrWc_UdzzREA:9 X-Proofpoint-Spam-Info: AW1haW4tMjYwODMxMDEwNCBTYWx0ZWRfXx0KT7i8Figmm sAZGpxbiOdgentvjrHfc0BE/KAYOQxMfDj+cI/1UIR79682mhOdpD2930fH95hT52LCRAsGs2Vt IWwSFSzlVjAV+aFCAgMKrzXLffrKq0U= X-Proofpoint-ORIG-GUID: ZiLW6iAYYbu7M88fI9VYiPfqNqpgjGkN X-Proofpoint-GUID: ZiLW6iAYYbu7M88fI9VYiPfqNqpgjGkN X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODMxMDEwNCBTYWx0ZWRfX13salKQkIPhc 0kik8rb9XZP6GM7NjzHjAVVmTOzPlcajMLzk/rwWHyYJC7swkSyMzDDkRssQp/P88tJKre3CP7F 6Y7o6nPsdrNwrF14dSKeEJvpCHB0j+03uVyD76ZuPpYq1PzmcQALRASptKng89jzJoSxcXkF2rh eICv6AGN8R00TeP2iKq8ILj1lRD6blD9SENw9+tgvCap+FeNgJzCoNGXRJYrwyJONQ9+0SfitAT sLKTvFRvu8HpO5uXpcKW0ZU85AYx2wURDMy0KD5v/OfrR/tbMMGyQOPiQxtXQAO9KuM/0or/EVw tzxpJYg/onMcQ3iNwh3BZQCC+8YmIdV4AGjaUgBQZwdy9LaDuNbq91f/1pwsVrPShKtgrFR6kX2 USKikM87v5BsLUN26ZKBUbYDaonAnd3q0NgxFlfl1Ni2c+j/km+OymGyJqfCldrRXkDPpJS3H1Q RMAoe1I/kdE75Tx7vRQ== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-31_04,2026-08-27_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 suspectscore=0 adultscore=0 malwarescore=0 spamscore=0 lowpriorityscore=0 phishscore=0 clxscore=1011 priorityscore=1501 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608310104 X-MailFrom: iii@linux.ibm.com X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation Message-ID-Hash: KXF45LQQHBYHI22HGEPE25PJWY3INZXD X-Message-ID-Hash: KXF45LQQHBYHI22HGEPE25PJWY3INZXD X-Mailman-Approved-At: Wed, 02 Sep 2026 09:10:22 +0000 CC: Ilya Leoshkevich X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1788340778481158500 Content-Type: text/plain; charset="utf-8" libvirt assigns affinities to QEMU threads only on domain start, therefore hot plugged host CPUs cannot be used. Restore the logic from commit 283e29043423 ("qemu: Allow use of hot plugged host CPUs if no affinity set"): when the affinity that would be set covers all the online CPUs anyway, do not set it at all. qemuProcessGetAllCpuAffinity() already knows when this is the case, so let it return NULL, which the callers already treat as "leave the affinity alone". Fixes: f136b83139c6 ("qemu: Rework setting process affinity") Signed-off-by: Ilya Leoshkevich Reviewed-by: Boris Fiuczynski Reviewed-by: Michal Privoznik --- src/qemu/qemu_process.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index b2506edce0..413ec0622d 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2567,30 +2567,46 @@ qemuProcessDetectIOThreadPIDs(virDomainObj *vm, } =20 =20 +/** + * qemuProcessGetAllCpuAffinity: + * @cpumapRet: returned CPU affinity map + * + * Sets @cpumapRet to the online CPUs minus the isolated ones. + * + * In case there is nothing to exclude (no isolated CPUs, or no overlap wi= th + * online CPUs), sets @cpumapRet to NULL instead, indicating to the caller= that + * it should not call sched_setaffinity(), which would prevent the usage of + * CPUs that are hot plugged later on. + * + * Returns: 0 on success, -1 on error. + */ static int qemuProcessGetAllCpuAffinity(virBitmap **cpumapRet) { g_autoptr(virBitmap) isolCpus =3D NULL; + g_autoptr(virBitmap) cpumap =3D NULL; =20 *cpumapRet =3D NULL; =20 if (!virHostCPUHasBitmap()) return 0; =20 - if (!(*cpumapRet =3D virHostCPUGetOnlineBitmap())) + if (!(cpumap =3D virHostCPUGetOnlineBitmap())) return -1; =20 if (virHostCPUGetIsolated(&isolCpus) < 0) return -1; =20 - if (isolCpus) { + if (isolCpus && virBitmapOverlaps(cpumap, isolCpus)) { g_autofree char *isolCpusStr =3D virBitmapFormat(isolCpus); - g_autofree char *cpumapRetStr =3D virBitmapFormat(*cpumapRet); + g_autofree char *cpumapRetStr =3D virBitmapFormat(cpumap); =20 VIR_INFO("Subtracting isolated CPUs %1$s from online CPUs %2$s", isolCpusStr, cpumapRetStr); =20 - virBitmapSubtract(*cpumapRet, isolCpus); + virBitmapSubtract(cpumap, isolCpus); + + *cpumapRet =3D g_steal_pointer(&cpumap); } =20 return 0; --=20 2.55.0 From nobody Tue Sep 15 06:00:35 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) client-ip=38.145.34.151; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1788340940; cv=none; d=zohomail.com; s=zohoarc; b=l7t2NFiVbtk8ayaH8DtpAakS40Gpldf0ZnKggCv0/MdXHOcBmQbUGtrFRGeHfHXXjKwzuM8WByteidMw7jEbiLWIOTov0lJ9BlH8NNoi+NSg/rv1f1I3GGAervuEKqmiuYAOp2oQIinQqf8S4/eI96YxdrSB2OYIBYqgg1iQ9gw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788340940; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=CFQP/j3nNGj3tkfdqGvN0WHvTGjG2+NLUBtXiiJwuJk=; b=AdUXO9znoIAfDik7HdxxwhvMn8DoTWLKCSm+dkXHqZnBC0JkXT6sBT5W/1yrLVIu2YW1d08nk+Jd5QHZd5SF7T7NbPacEhxyN5D3ajtJqja7z7Pgq8KmVk+6daDMXLsXr+8jv0L2SV/L/uEOnBJLDmSuUaLDOJN2lB3qp1xOG9w= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1788340940856378.18656910557183; Wed, 2 Sep 2026 02:22:20 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 080623FCA6; Wed, 2 Sep 2026 05:22:19 -0400 (EDT) Received: from [172.19.199.13] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id 4744641D1A for ; Wed, 2 Sep 2026 05:10:52 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 0C9313F2F8; Mon, 31 Aug 2026 08:02:11 -0400 (EDT) Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 6AB933F390 for ; Mon, 31 Aug 2026 08:02:08 -0400 (EDT) Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67VBW7rO212035 for ; Mon, 31 Aug 2026 12:02:07 GMT Received: from ppma22.wdc07v.mail.ibm.com (5c.69.3da9.ip4.static.sl-reverse.com [169.61.105.92]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4gbq3r10w1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 31 Aug 2026 12:02:06 +0000 (GMT) Received: from pps.filterd (ppma22.wdc07v.mail.ibm.com [127.0.0.1]) by ppma22.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 67VBuQMj030063 for ; Mon, 31 Aug 2026 12:02:05 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4gca4vws8j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 31 Aug 2026 12:02:05 +0000 (GMT) Received: from smtpav03.fra02v.mail.ibm.com (smtpav03.fra02v.mail.ibm.com [10.20.54.102]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 67VC21Ca43778416 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 31 Aug 2026 12:02:01 GMT Received: from smtpav03.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A199920043; Mon, 31 Aug 2026 12:02:01 +0000 (GMT) Received: from smtpav03.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7B3D72004D; Mon, 31 Aug 2026 12:02:01 +0000 (GMT) Received: from li-d2cd37cc-2ca3-11b2-a85c-84ed3706e5a0.ibm.com (unknown [9.111.4.184]) by smtpav03.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 31 Aug 2026 12:02:01 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=CFQP/j3nNGj3tkfdq GvN0WHvTGjG2+NLUBtXiiJwuJk=; b=pgp1WI4r5Y7IY/7KBdwl5N9EJDSeiIvg7 d1c6pzmUGxdikaZVfv5W5OAVz2BXv8ZZGkJ0XZQlfkdwBGy5WKablWKqYBtlEmBO RkX8OtYPzblOA0OdMrHlEaXJBwkzszv8wF8XX+iPT9dLIY4E0wFnZqVseCcYc3G4 VLLrWv0D+akHr2kBLD2YEESMvqQb7BrUrUMoZucK1FcGcIXYkF6+3C7FqxsWZ9n8 kEMf/tOHiwWFtRhvbwH9QODRWyey4OrxgQJBpUx8GAfQYMT1SpFhh0ALtspC3NZv MOGfmDeDcHG/J9QFNue8wLDTAu0TiZ/b8Al8afUP/jYkVjQACt/+Q== From: Ilya Leoshkevich To: devel@lists.libvirt.org Subject: [PATCH 2/2] tests: add qemuprocesstest for qemuProcessGetAllCpuAffinity Date: Mon, 31 Aug 2026 13:58:52 +0200 Message-ID: <20260831120150.2827673-3-iii@linux.ibm.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260831120150.2827673-1-iii@linux.ibm.com> References: <20260831120150.2827673-1-iii@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=EIc2FVZC c=1 sm=1 tr=0 ts=6a956d3e cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=mDV3o1hIAAAA:8 a=VnNF1IyMAAAA:8 a=KJ_BLl63m4bjciUBHcMA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODMxMDEwNCBTYWx0ZWRfX5fWOk4z9gnL+ 8PErBwsRj5BJMMkeetJ+Lapk+G+O5RS/cz2CbVBkGDbQnHKMknHbMCjxpaW9FkKejdPAhlc1Uwg MDi9cuhhC1Zl3CZgCvY9dlX3gk+tP2pTMJ6VEx+iO8Jnx6JnTgHs+HJi1YDcUEyySrbceNGmA6R GPnBlg4WZZ5UtCsxTjLsiCAJ93G3mQPJH0V5UUrnELhL9/LLYrbumm5hbCRkx/OCB6arDFYO2x3 oSVyZ3uTY6H6jh0moRxytbqKGtng2rgCrcftwZe90juc3DKpBWFQbK33aXfpqrLv5oQZHK6IST7 C7QF6sLkt46MBdgzP3dv3ZH+7BzWXE7EExJOc2NX4OSfXO/zbrMhwaaeKmjCLqd9qTd3KqKtgdv NuTxKOHRum/76r+7dmqW463gj8ByoYoeBbS1eW6LdnmbqpoEjQv0MZZd8i7Byq0TLD6bLjDYNiS 1xncXdTNRKQpeqXq4NQ== X-Proofpoint-GUID: pnaaKaifwxHqZxbfGZgJ7TWZW_j-R4e0 X-Proofpoint-ORIG-GUID: pnaaKaifwxHqZxbfGZgJ7TWZW_j-R4e0 X-Proofpoint-Spam-Info: AW1haW4tMjYwODMxMDEwNCBTYWx0ZWRfX0lnO7q8SC9tk 4p/89ez3vL41Y+dusoByYFqcCw1AXhkJDJzVROWY3klAvmElTyVOiYH6rSb+K/CsZl+uNXj0aLm 9OYx7MR5LARmnR/BuYn++2OtBu5jbJQ= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-31_04,2026-08-27_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 impostorscore=0 suspectscore=0 priorityscore=1501 clxscore=1011 phishscore=0 spamscore=0 adultscore=0 lowpriorityscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608310104 X-MailFrom: iii@linux.ibm.com X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation Message-ID-Hash: JW2RCQF233RUCZUUXPZN6JRBPW6QIRDF X-Message-ID-Hash: JW2RCQF233RUCZUUXPZN6JRBPW6QIRDF X-Mailman-Approved-At: Wed, 02 Sep 2026 09:10:23 +0000 CC: Boris Fiuczynski X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1788340943440154100 Content-Type: text/plain; charset="utf-8" From: Boris Fiuczynski From: Boris Fiuczynski Add tests covering the three cases of qemuProcessGetAllCpuAffinity(): no isolated CPUs, overlapping isolated CPUs, and isolated CPUs that do not overlap with online CPUs (the hot-plug regression scenario). Promote the function from static to allow direct testing, and provide qemuprocessmock.c to replace the three virHostCPU* calls it depends on. Signed-off-by: Boris Fiuczynski Reviewed-by: Michal Privoznik --- src/qemu/qemu_process.c | 2 +- src/qemu/qemu_process.h | 2 + src/util/virhostcpu.h | 6 +- tests/meson.build | 1 + tests/qemuprocessmock.c | 65 ++++++++++++++++++ tests/qemuprocesstest.c | 144 ++++++++++++++++++++++++++++++++++++++++ tests/qemuprocesstest.h | 25 +++++++ 7 files changed, 241 insertions(+), 4 deletions(-) create mode 100644 tests/qemuprocessmock.c create mode 100644 tests/qemuprocesstest.c create mode 100644 tests/qemuprocesstest.h diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 413ec0622d..aaa9046146 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2580,7 +2580,7 @@ qemuProcessDetectIOThreadPIDs(virDomainObj *vm, * * Returns: 0 on success, -1 on error. */ -static int +int qemuProcessGetAllCpuAffinity(virBitmap **cpumapRet) { g_autoptr(virBitmap) isolCpus =3D NULL; diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 2db5186e08..5d8f1f89d5 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -269,3 +269,5 @@ void qemuProcessHandleNbdkitExit(qemuNbdkitProcess *nbd= kit, int qemuPrepareNVRAM(virQEMUDriver *driver, virDomainDef *def, bool reset_nvram); + +int qemuProcessGetAllCpuAffinity(virBitmap **cpumapRet); diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h index 4df126dcc4..7aa02b35aa 100644 --- a/src/util/virhostcpu.h +++ b/src/util/virhostcpu.h @@ -38,11 +38,11 @@ int virHostCPUGetStats(int cpuNum, virNodeCPUStatsPtr params, int *nparams); =20 -bool virHostCPUHasBitmap(void); +bool virHostCPUHasBitmap(void) ATTRIBUTE_MOCKABLE; virBitmap *virHostCPUGetPresentBitmap(void); -virBitmap *virHostCPUGetOnlineBitmap(void); +virBitmap *virHostCPUGetOnlineBitmap(void) ATTRIBUTE_MOCKABLE; virBitmap *virHostCPUGetAvailableCPUsBitmap(void); -int virHostCPUGetIsolated(virBitmap **isolated); +int virHostCPUGetIsolated(virBitmap **isolated) ATTRIBUTE_MOCKABLE; =20 int virHostCPUGetCount(void); int virHostCPUGetThreadsPerSubcore(virArch arch) ATTRIBUTE_MOCKABLE; diff --git a/tests/meson.build b/tests/meson.build index ea50f89fb5..ddaee05517 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -475,6 +475,7 @@ if conf.has('WITH_QEMU') { 'name': 'qemumigparamstest', 'link_with': [ test_qemu_driver_lib, te= st_utils_qemu_monitor_lib ], 'link_whole': [ test_utils_qemu_lib ] }, { 'name': 'qemumigrationcookiexmltest', 'link_with': [ test_qemu_drive= r_lib, test_utils_qemu_monitor_lib ], 'link_whole': [ test_utils_qemu_lib, = test_file_wrapper_lib ] }, { 'name': 'qemumonitorjsontest', 'link_with': [ test_qemu_driver_lib, = test_utils_qemu_monitor_lib ], 'link_whole': [ test_utils_qemu_lib ] }, + { 'name': 'qemuprocesstest', 'sources': [ 'qemuprocesstest.c', 'qemupr= ocessmock.c' ], 'link_with': [ test_qemu_driver_lib ] }, { 'name': 'qemusecuritytest', 'sources': [ 'qemusecuritytest.c', 'qemu= securitymock.c' ], 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ t= est_utils_qemu_lib ] }, { 'name': 'qemuxmlactivetest', 'link_with': [ test_qemu_driver_lib ], = 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] }, { 'name': 'qemuvhostusertest', 'link_with': [ test_qemu_driver_lib ], = 'link_whole': [ test_file_wrapper_lib ] }, diff --git a/tests/qemuprocessmock.c b/tests/qemuprocessmock.c new file mode 100644 index 0000000000..79c66bab4b --- /dev/null +++ b/tests/qemuprocessmock.c @@ -0,0 +1,65 @@ +/* + * qemuprocessmock.c: mocks for qemuprocesstest + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include "internal.h" +#include "virbitmap.h" +#include "virhostcpu.h" +#include "qemuprocesstest.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +static const char *mock_online_cpus; +static const char *mock_isolated_cpus; +static bool mock_has_bitmap =3D true; + +void +qemuProcessMockSetCpus(const char *online, + const char *isolated, + bool hasBitmap) +{ + mock_online_cpus =3D online; + mock_isolated_cpus =3D isolated; + mock_has_bitmap =3D hasBitmap; +} + +bool +virHostCPUHasBitmap(void) +{ + return mock_has_bitmap; +} + +virBitmap * +virHostCPUGetOnlineBitmap(void) +{ + if (!mock_online_cpus) + return NULL; + return virBitmapParseUnlimited(mock_online_cpus); +} + +int +virHostCPUGetIsolated(virBitmap **isolated) +{ + *isolated =3D NULL; + if (!mock_isolated_cpus) + return 0; + if (!(*isolated =3D virBitmapParseUnlimitedAllowEmpty(mock_isolated_cp= us))) + return -1; + return 0; +} diff --git a/tests/qemuprocesstest.c b/tests/qemuprocesstest.c new file mode 100644 index 0000000000..37ed5756a1 --- /dev/null +++ b/tests/qemuprocesstest.c @@ -0,0 +1,144 @@ +/* + * qemuprocesstest.c: tests for qemu_process.c internals + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include "testutils.h" +#include "virbitmap.h" +#include "qemu/qemu_process.h" +#include "qemuprocesstest.h" + +#define VIR_FROM_THIS VIR_FROM_QEMU + +/* + * Case 1: no isolated CPUs (sysfs file absent). + * + * qemuProcessGetAllCpuAffinity() must return NULL, indicating that + * sched_setaffinity() should NOT be called so that CPUs hot-plugged + * after startup remain usable. + */ +static int +testGetAllCpuAffinityNoIsolated(const void *opaque G_GNUC_UNUSED) +{ + g_autoptr(virBitmap) result =3D NULL; + + qemuProcessMockSetCpus("0-7", NULL, true); + + if (qemuProcessGetAllCpuAffinity(&result) < 0) + return -1; + + if (result) { + g_autofree char *str =3D virBitmapFormat(result); + fprintf(stderr, + "expected NULL (no sched_setaffinity) when no isolated CPU= s, " + "got '%s'\n", str); + return -1; + } + + return 0; +} + + +/* + * Case 2: isolated CPUs that DO overlap with online CPUs. + * + * qemuProcessGetAllCpuAffinity() must return the online set minus the + * isolated set so that QEMU is pinned away from the isolated cores. + */ +static int +testGetAllCpuAffinityOverlapping(const void *opaque G_GNUC_UNUSED) +{ + g_autoptr(virBitmap) result =3D NULL; + g_autofree char *str =3D NULL; + + qemuProcessMockSetCpus("0-7", "6-7", true); + + if (qemuProcessGetAllCpuAffinity(&result) < 0) + return -1; + + if (!result) { + fprintf(stderr, + "expected non-NULL affinity map when isolated CPUs overlap= " + "online CPUs\n"); + return -1; + } + + str =3D virBitmapFormat(result); + if (STRNEQ(str, "0-5")) { + fprintf(stderr, "expected '0-5', got '%s'\n", str); + return -1; + } + + return 0; +} + + +/* + * Case 3: isolated CPUs that do NOT overlap with online CPUs. + * + * This is the hot-plug regression scenario: CPUs 8-9 are listed as + * isolated but are not currently online (online =3D 0-7). Before the + * fix, the function returned the full online bitmap, causing + * sched_setaffinity() to pin QEMU to CPUs 0-7 at startup and thereby + * preventing any subsequently hot-plugged CPU from being used. + * After the fix it must return NULL. + */ +static int +testGetAllCpuAffinityNonOverlapping(const void *opaque G_GNUC_UNUSED) +{ + g_autoptr(virBitmap) result =3D NULL; + + qemuProcessMockSetCpus("0-7", "8-9", true); + + if (qemuProcessGetAllCpuAffinity(&result) < 0) + return -1; + + if (result) { + g_autofree char *str =3D virBitmapFormat(result); + fprintf(stderr, + "expected NULL when isolated CPUs do not overlap online CP= Us " + "(hot-plug regression), got '%s'\n", str); + return -1; + } + + return 0; +} + + +static int +mymain(void) +{ + int ret =3D 0; + +#define DO_TEST(desc, func) \ + do { \ + if (virTestRun(desc, func, NULL) < 0) \ + ret =3D -1; \ + } while (0) + + DO_TEST("GetAllCpuAffinity: no isolated CPUs -> NULL", + testGetAllCpuAffinityNoIsolated); + DO_TEST("GetAllCpuAffinity: overlapping isolated CPUs -> online minus = isolated", + testGetAllCpuAffinityOverlapping); + DO_TEST("GetAllCpuAffinity: non-overlapping isolated CPUs -> NULL (hot= -plug fix)", + testGetAllCpuAffinityNonOverlapping); + + return ret =3D=3D 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIR_TEST_MAIN(mymain) diff --git a/tests/qemuprocesstest.h b/tests/qemuprocesstest.h new file mode 100644 index 0000000000..02af5c0dc5 --- /dev/null +++ b/tests/qemuprocesstest.h @@ -0,0 +1,25 @@ +/* + * qemuprocesstest.h: shared declarations for qemuprocesstest + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#pragma once + +#include "internal.h" + +void qemuProcessMockSetCpus(const char *online, + const char *isolated, + bool hasBitmap) ATTRIBUTE_MOCKABLE; --=20 2.55.0