From nobody Fri Dec 19 22:07:44 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1754387609; cv=none; d=zohomail.com; s=zohoarc; b=YkQFiajFSAGAqtZlhBqpX+VBL+gY37rZAQ5Mf37yuJ4HdPokm6DaoGckh6Xq8fwD9NsROvM/ObBPcecX2VdBmTdnCHKeAEvgzOBs69UeOs3VrEpNyOl+J5H9KUyN6hYpJJYMdhvX97oZAEXIxwwBgatkG2hEz+uD73kwwUXwBDs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1754387609; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=YlJ4EVtQhQPCSTEsURZWjPcV24GHkW+OWqt8tBVq6Ws=; b=h3UvSo6DOdwV+JK526cVVcs1WsonpoU7Abxi1Na+iTS5bZUKj7PW83OBdLTEO/fvOXii07XjqdyP/Sum7O894Z/71l19wSbqVVRoYwfwEjOkpr5BBuL70l4avJTOQvsemU8DYtFKJ7kieHqcjuEox67YQPpXcapz8G7T3giV+aU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1754387609007233.9516500216747; Tue, 5 Aug 2025 02:53:29 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1070224.1433876 (Exim 4.92) (envelope-from ) id 1ujEM7-0002Dq-BW; Tue, 05 Aug 2025 09:53:15 +0000 Received: by outflank-mailman (output) from mailman id 1070224.1433876; Tue, 05 Aug 2025 09:53:15 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEM7-0002Dj-8U; Tue, 05 Aug 2025 09:53:15 +0000 Received: by outflank-mailman (input) for mailman id 1070224; Tue, 05 Aug 2025 09:53:13 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEM5-00026G-NW for xen-devel@lists.xenproject.org; Tue, 05 Aug 2025 09:53:13 +0000 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [2a00:1450:4864:20::430]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id ff884533-71e1-11f0-b898-0df219b8e170; Tue, 05 Aug 2025 11:53:11 +0200 (CEST) Received: by mail-wr1-x430.google.com with SMTP id ffacd0b85a97d-3b78a034f17so3680053f8f.2 for ; Tue, 05 Aug 2025 02:53:11 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id ffacd0b85a97d-3b79c4a2848sm18386766f8f.71.2025.08.05.02.53.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Aug 2025 02:53:10 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: ff884533-71e1-11f0-b898-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1754387591; x=1754992391; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=YlJ4EVtQhQPCSTEsURZWjPcV24GHkW+OWqt8tBVq6Ws=; b=Bqb0zdIl5Ehg6S4t4fbcZePweha19gznJngnQBceOvschwUHsqRaHKur5R+hsJYkFc SVfUK/NILHjcZfDbGu/mS35UforuNBcGGiphku7UZPdA0vNxx+vyDfALeqwdyFkcuzOP WX5YONmJuPBuA4K7ZKJpSt7XM5D0UJDfcNWB8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754387591; x=1754992391; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YlJ4EVtQhQPCSTEsURZWjPcV24GHkW+OWqt8tBVq6Ws=; b=MjDfJ0Mnykz83zQhrrob+juCkCf07zEf4sJibNtEHco41uMLvePFvo2boQ9jBiTk43 cTOt96d40Eca0sNXawul4Op6yUgGorOgA2fEl2gX1pBtSVK2gW/7jDY6s3EQpxcZCbcA r6tvnj9s01ywkftVFgmOJNY5ngWzqw/MqCgMQDSqfSVm1P6FPnWDKFq1aGqIDuzRCqDO dfRq+jDVtOGM0S9/mL9vyOhR2tTpMzxaLXeLO3o1N0uiK74lUpCWQpKbOMGWOe52BMug 20MTPQeHBK1Xa/rTHZdVF5wXgeByhd89LsdgHuvyMIYbc1Ql19NkkCZgSEkMElmVXu17 IKng== X-Gm-Message-State: AOJu0Yzo+mxDvc1YaFbXwPKSgjz/nbtG6Zc5YqNqr5DZKJ9zE/mM3QKP pvQhXs7B13Rq35dp4MmDWj4iuIoDOQIQFrKBi3NomokOatZjxLrOm+4/2RjoI5p7ia5bXESYBuc vYBkj X-Gm-Gg: ASbGnct+uaUa2jTRRQLmco4RKtM1sX80+ZUlfKjv5g53Ob3zKOkDbeHHSpSOvYSFchY Wwyrj5dEaFqfra0ArO8+vrtfmoRalBP72pmGTcEc77Yt+mjpYTGG/ZHdqBjibjNkF+vkBOha8GP 2j8G0Ic+zaoTkQzkHsux5dptJq1aXQmNBYBQwVn1KlLUwmkXSm+DBeZhONu1iaKUlniAocaepol tsQWiTdoP4JHnjqXfpC2+w5K4CHn3k3zn3RhYHkGlv+pM0GQAcYUAIlpZX3ZpWU0+YuHq/gOR1F Q5M3wwGvsG6nAkKE8rjzKNCL7n2JUwFC+jVijDkW/LgzVlQaDsaD62naunooALvGlxneudOvkgs eV6VxjpWhZL8HKtp6PK2b/EplT2Q2riJd3DK1Wn8f0p6/HAqPyEn4aK68wZjt1NtfrLwXyBcJcM /E X-Google-Smtp-Source: AGHT+IFwRXAghNgrt0pR2SwJ3D/h7HW/dZTVNoThRWg/S/KXqaZhSjs7CWT+IBx1cibnmwzVpiCsHg== X-Received: by 2002:a05:6000:220b:b0:3b7:792c:e8be with SMTP id ffacd0b85a97d-3b8d946c468mr8387219f8f.8.1754387590874; Tue, 05 Aug 2025 02:53:10 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Andrew Cooper , Anthony PERARD , Jan Beulich Subject: [PATCH v4 1/8] kconfig: turn PDX compression into a choice Date: Tue, 5 Aug 2025 11:52:50 +0200 Message-ID: <20250805095257.74975-2-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250805095257.74975-1-roger.pau@citrix.com> References: <20250805095257.74975-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1754387611979124100 Rename the current CONFIG_PDX_COMPRESSION to CONFIG_PDX_MASK_COMPRESSION, and make it part of the PDX compression choice block, in preparation for adding further PDX compression algorithms. The PDX compression defaults should still be the same for all architectures, however the choice block cannot be protected under EXPERT and still have a default choice being unconditionally selected. As a result, the new "PDX (Page inDeX) compression" item will be unconditionally visible in Kconfig, even on architectures like x86 that previously had no way to enable PDX compression. As part of this preparation work to introduce new PDX compressions, adjust some of the comments on pdx.h to note they apply to a specific PDX compression. Also shuffle function prototypes and dummy implementations around to make it easier to introduce a new PDX compression. Note all PDX compression implementations are expected to provide a pdx_is_region_compressible() that takes the same set of arguments. Signed-off-by: Roger Pau Monn=C3=A9 Acked-by: Jan Beulich Acked-by: Julien Grall --- xen/arch/arm/setup.c | 2 +- xen/common/Kconfig | 18 +++++++++++++++--- xen/common/pdx.c | 4 ++-- xen/include/xen/pdx.h | 32 +++++++++++++++++++------------- 4 files changed, 37 insertions(+), 19 deletions(-) diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index bb35afe56cec..a77b31071ed8 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -258,7 +258,7 @@ void __init init_pdx(void) paddr_t bank_start, bank_size, bank_end, ram_end =3D 0; int bank; =20 -#ifdef CONFIG_PDX_COMPRESSION +#ifndef CONFIG_PDX_NONE /* * Arm does not have any restrictions on the bits to compress. Pass 0 = to * let the common code further restrict the mask. diff --git a/xen/common/Kconfig b/xen/common/Kconfig index 16936418a6e6..8dad0c923a9d 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -57,9 +57,10 @@ config EVTCHN_FIFO =20 If unsure, say Y. =20 -config PDX_COMPRESSION - bool "PDX (Page inDeX) compression" if EXPERT && !X86 && !RISCV - default ARM || PPC +choice + prompt "PDX (Page inDeX) compression" + default PDX_MASK_COMPRESSION if !X86 && !RISCV + default PDX_NONE help PDX compression is a technique designed to reduce the memory overhead of physical memory management on platforms with sparse RAM @@ -72,6 +73,17 @@ config PDX_COMPRESSION If your platform does not have sparse RAM banks, do not enable PDX compression. =20 +config PDX_MASK_COMPRESSION + bool "Mask compression" + help + Compression relying on all RAM addresses sharing a zeroed bit region. + +config PDX_NONE + bool "None" + help + No compression +endchoice + config ALTERNATIVE_CALL bool =20 diff --git a/xen/common/pdx.c b/xen/common/pdx.c index b8384e6189df..00aa7e43006d 100644 --- a/xen/common/pdx.c +++ b/xen/common/pdx.c @@ -34,7 +34,7 @@ bool __mfn_valid(unsigned long mfn) { bool invalid =3D mfn >=3D max_page; =20 -#ifdef CONFIG_PDX_COMPRESSION +#ifdef CONFIG_PDX_MASK_COMPRESSION invalid |=3D mfn & pfn_hole_mask; #endif =20 @@ -55,7 +55,7 @@ void set_pdx_range(unsigned long smfn, unsigned long emfn) __set_bit(idx, pdx_group_valid); } =20 -#ifdef CONFIG_PDX_COMPRESSION +#ifdef CONFIG_PDX_MASK_COMPRESSION =20 /* * Diagram to make sense of the following variables. The masks and shifts diff --git a/xen/include/xen/pdx.h b/xen/include/xen/pdx.h index c1423d64a95b..8e373cac8b87 100644 --- a/xen/include/xen/pdx.h +++ b/xen/include/xen/pdx.h @@ -25,7 +25,7 @@ * this by keeping a bitmap of the ranges in the frame table containing * invalid entries and not allocating backing memory for them. * - * ## PDX compression + * ## PDX mask compression * * This is a technique to avoid wasting memory on machines known to have * split their machine address space in several big discontinuous and high= ly @@ -101,22 +101,13 @@ bool __mfn_valid(unsigned long mfn); #define paddr_to_pdx(pa) pfn_to_pdx(paddr_to_pfn(pa)) #define pdx_to_paddr(px) pfn_to_paddr(pdx_to_pfn(px)) =20 -#ifdef CONFIG_PDX_COMPRESSION +#ifdef CONFIG_PDX_MASK_COMPRESSION =20 extern unsigned long pfn_pdx_bottom_mask, ma_va_bottom_mask; extern unsigned int pfn_pdx_hole_shift; extern unsigned long pfn_hole_mask; extern unsigned long pfn_top_mask, ma_top_mask; =20 -/** - * Validate a region's compatibility with the current compression runtime - * - * @param base Base address of the region - * @param npages Number of PAGE_SIZE-sized pages in the region - * @return True iff the region can be used with the current compression - */ -bool pdx_is_region_compressible(paddr_t base, unsigned long npages); - /** * Calculates a mask covering "moving" bits of all addresses of a region * @@ -209,7 +200,9 @@ static inline paddr_t directmapoff_to_maddr(unsigned lo= ng offset) */ void pfn_pdx_hole_setup(unsigned long mask); =20 -#else /* !CONFIG_PDX_COMPRESSION */ +#endif /* CONFIG_PDX_MASK_COMPRESSION */ + +#ifdef CONFIG_PDX_NONE =20 /* Without PDX compression we can skip some computations */ =20 @@ -241,7 +234,20 @@ static inline void pfn_pdx_hole_setup(unsigned long ma= sk) { } =20 -#endif /* CONFIG_PDX_COMPRESSION */ +#else /* !CONFIG_PDX_NONE */ + +/* Shared functions implemented by all PDX compressions. */ + +/** + * Validate a region's compatibility with the current compression runtime + * + * @param base Base address of the region + * @param npages Number of PAGE_SIZE-sized pages in the region + * @return True iff the region can be used with the current compression + */ +bool pdx_is_region_compressible(paddr_t base, unsigned long npages); + +#endif /* !CONFIG_PDX_NONE */ #endif /* __XEN_PDX_H__ */ =20 /* --=20 2.49.0 From nobody Fri Dec 19 22:07:44 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1754387613; cv=none; d=zohomail.com; s=zohoarc; b=LierA797FFVC+nRR+AqlQsHOdgFrUXbtuUn49Y4z4vmlkH1mtFl5B8wBFZ/0Ts9O/nrDt+kq38cJtc9rElk7XcLXlRJhsBbR06ed7xj+6yDAuk6KatCPsdZi3qZPp9jDFEMx0b+5WjG1Af/kKImZcmMqlqpmxKeLNV5u3o78T40= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1754387613; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=vsHoH88Bq1GawZ6maquU1VqYJOWUKfDJ8Tpkog2WGL4=; b=YYO8CLn/yyj7VVyZ5qVNM1dsnE5mkJtoxyp/1ifnDrJrk9J+k2JvMETI9neVAd1PPXOFITMqwK3R+UKBuKKwZXXcOa009JCp//Kghw1fVFxxRk38pjI9aVXbjtr5QMjEas1GP1c/idD8j4X0qYYJfCpHopCPzUr3LZ5LnXhTs1U= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1754387613590744.9502726960708; Tue, 5 Aug 2025 02:53:33 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1070226.1433897 (Exim 4.92) (envelope-from ) id 1ujEM8-0002gx-TV; Tue, 05 Aug 2025 09:53:16 +0000 Received: by outflank-mailman (output) from mailman id 1070226.1433897; Tue, 05 Aug 2025 09:53:16 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEM8-0002g8-Nu; Tue, 05 Aug 2025 09:53:16 +0000 Received: by outflank-mailman (input) for mailman id 1070226; Tue, 05 Aug 2025 09:53:15 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEM7-00026G-61 for xen-devel@lists.xenproject.org; Tue, 05 Aug 2025 09:53:15 +0000 Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com [2a00:1450:4864:20::32c]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 00800a5b-71e2-11f0-b898-0df219b8e170; Tue, 05 Aug 2025 11:53:13 +0200 (CEST) Received: by mail-wm1-x32c.google.com with SMTP id 5b1f17b1804b1-459e39ee7ccso2003675e9.2 for ; Tue, 05 Aug 2025 02:53:13 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id 5b1f17b1804b1-458f713eb44sm104033275e9.14.2025.08.05.02.53.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Aug 2025 02:53:11 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 00800a5b-71e2-11f0-b898-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1754387592; x=1754992392; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=vsHoH88Bq1GawZ6maquU1VqYJOWUKfDJ8Tpkog2WGL4=; b=mzdWx2O/lD84MrDcO+0WpXXyTYnJxi12qxaNuB5dYjjD+JrarMO3EE6ZdCA56hXEcH aftY6E+50Q333rRBfvUeLXMyPBdigtvAxvUocEOA4NYTeelMPNAb7DUTk7zJa9V/xGgh u1JTcmIOTxuEaid2ViYUYleRH+O020abq2mrg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754387592; x=1754992392; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vsHoH88Bq1GawZ6maquU1VqYJOWUKfDJ8Tpkog2WGL4=; b=i37j8RcRSskP8JM7XmYuG2qYXdpg0Eyt2vNXuVx7KHy+6SWiHWbKvX8p11FA6wg1Ws li8pV9NXEXeklzeIKpa/nN8P/qhOq/qjfWlSTeOpq4uj1P5tmQKFdZvaSbvSaPloAh3c 8JPQXd2yCmSYYT5JsfQ6NYVU/iztcrQFpBYL4gOjZPq+pVnZD/JQIf3wJeTdVWYbW5wu 0v6MlWXmdndDEs7LZjSG/Rf0w/0z2KHKd9Dc0ZjIVeiwii437YgaRUEq3LhDfxNd+OSB UsUOBpkiSShVPZpXm+KjxnEzPMuIUdt7Jq8aYCusIQhrWTksvVaR9YkWNIj8h0KNC4ah ZLWQ== X-Gm-Message-State: AOJu0YzPjG5JfQOgMlJux5SI30qbWt8DjPRaaSzOYPjZQEGb0QjLiBal zsnrxRgIzehUXS8zYPT49wx1/R+KTpt+T2EdeotFJzWSHpQ0mRFwo1CUsNtviMdfzNj4V/XWR/l 3uvZX X-Gm-Gg: ASbGnctL2SaReDRMbduPIYC6IDOxTRs0xskvd+lrAAJDSxn6OJsk7Yb2YuHSsHUnei5 10ilmxrDFwragg9I+Vxi2Hu7JwuzntjVegHQiwuYIxuZSCdQDEJhz+yZVt9C6CZDTXV190NpGJG y6EJ7ZpTNxnWbut/tpDzu+60cQBLNT1wV5CXjlvf6PHhdpaGBCDfaMxHJY5ihQUIweXM2mAtnva ZrftDBtfV8sXjNisQpJ02O9ECFV32BrqK59rFhzaScS2k2mKEfERwrl56kM798xhyH7/v3U2fv3 4vCt/7qWE+3e7HQ8KUs44d39UOdmBRuvA0arIDpgv46DxInjEeKi1zyx2/IGQxBM5RSrepdddBr l8LPVINqzY5QhKI3wW+gI2p1Jrrd2o3LJ+xvAXuj5ca7ZeSif68w7oWkfzxf/e5wMaA== X-Google-Smtp-Source: AGHT+IFxvIar0IThaZT++liEgv3hQugAJuhVSOQvcs5FezgqdkMBUhbPoarb4rJsxvS11/W+diaoFA== X-Received: by 2002:a05:600c:3b9c:b0:459:d3d0:650e with SMTP id 5b1f17b1804b1-459d3d065f9mr68179545e9.13.1754387592065; Tue, 05 Aug 2025 02:53:12 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Andrew Cooper , Anthony PERARD , Jan Beulich Subject: [PATCH v4 2/8] pdx: provide a unified set of unit functions Date: Tue, 5 Aug 2025 11:52:51 +0200 Message-ID: <20250805095257.74975-3-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250805095257.74975-1-roger.pau@citrix.com> References: <20250805095257.74975-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1754387615275116600 The current setup (pdx_init_mask() and pdx_region_mask()) and init (pfn_pdx_hole_setup()) PDX compression functions are tailored to the existing PDX compression algorithm. In preparation for introducing a new compression algorithm convert the setup and init functions to more generic interfaces that aren't tied to the compression in-use. To accomplish this introduce a function that registers all the PFN RAM ranges, plus an init function. This has the downside of requiring a static array to store such ranges ahead of being processed by the setup function, however it's the only way to pass all the possible information to the different compression setup functions without using per-compression specific setup functions. Per-arch compression setup also need to be adjusted to use the new interface. There's a slight ordering adjustment, in that after PDX compression setup the caller will check whether all the RAM regions are properly covered by the newly setup compression, otherwise compression is disabled by resetting to the initial values. No functional change intended in the resulting PDX compression values. Signed-off-by: Roger Pau Monn=C3=A9 Acked-by: Jan Beulich Acked-by: Julien Grall # ARM --- Changes since v3: - Rename base to base_pfn and size to pages. Changes since v2: - Fix indentation. Changes since v1: - s/nr/nr_ranges/ --- xen/arch/arm/setup.c | 34 ++++++------ xen/arch/x86/srat.c | 28 ++++++---- xen/common/pdx.c | 122 ++++++++++++++++++++++++++++++++++++------ xen/include/xen/pdx.h | 73 +++++++++---------------- 4 files changed, 166 insertions(+), 91 deletions(-) diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index a77b31071ed8..ba35bf1fe3bb 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -256,9 +256,11 @@ void __init init_pdx(void) { const struct membanks *mem =3D bootinfo_get_mem(); paddr_t bank_start, bank_size, bank_end, ram_end =3D 0; - int bank; + unsigned int bank; =20 #ifndef CONFIG_PDX_NONE + for ( bank =3D 0 ; bank < mem->nr_banks; bank++ ) + pfn_pdx_add_region(mem->bank[bank].start, mem->bank[bank].size); /* * Arm does not have any restrictions on the bits to compress. Pass 0 = to * let the common code further restrict the mask. @@ -266,26 +268,24 @@ void __init init_pdx(void) * If the logic changes in pfn_pdx_hole_setup we might have to * update this function too. */ - uint64_t mask =3D pdx_init_mask(0x0); - - for ( bank =3D 0 ; bank < mem->nr_banks; bank++ ) - { - bank_start =3D mem->bank[bank].start; - bank_size =3D mem->bank[bank].size; - - mask |=3D bank_start | pdx_region_mask(bank_start, bank_size); - } + pfn_pdx_compression_setup(0); =20 for ( bank =3D 0 ; bank < mem->nr_banks; bank++ ) { - bank_start =3D mem->bank[bank].start; - bank_size =3D mem->bank[bank].size; - - if (~mask & pdx_region_mask(bank_start, bank_size)) - mask =3D 0; + if ( !pdx_is_region_compressible( + mem->bank[bank].start, + PFN_UP(mem->bank[bank].start + mem->bank[bank].size) - + PFN_DOWN(mem->bank[bank].start)) ) + { + pfn_pdx_compression_reset(); + printk(XENLOG_WARNING + "PFN compression disabled, RAM region [%#" PRIpaddr ", = %#" + PRIpaddr "] not covered\n", + mem->bank[bank].start, + mem->bank[bank].start + mem->bank[bank].size - 1); + break; + } } - - pfn_pdx_hole_setup(mask >> PAGE_SHIFT); #endif =20 for ( bank =3D 0 ; bank < mem->nr_banks; bank++ ) diff --git a/xen/arch/x86/srat.c b/xen/arch/x86/srat.c index 688f410287d4..747607439fb4 100644 --- a/xen/arch/x86/srat.c +++ b/xen/arch/x86/srat.c @@ -261,8 +261,6 @@ acpi_numa_memory_affinity_init(const struct acpi_srat_m= em_affinity *ma) =20 void __init acpi_numa_arch_fixup(void) {} =20 -static uint64_t __initdata srat_region_mask; - static int __init cf_check srat_parse_region( struct acpi_subtable_header *header, const unsigned long end) { @@ -282,15 +280,13 @@ static int __init cf_check srat_parse_region( printk(KERN_INFO "SRAT: %013"PRIx64"-%013"PRIx64"\n", ma->base_address, ma->base_address + ma->length - 1); =20 - srat_region_mask |=3D ma->base_address | - pdx_region_mask(ma->base_address, ma->length); + pfn_pdx_add_region(ma->base_address, ma->length); =20 return 0; } =20 void __init srat_parse_regions(paddr_t addr) { - u64 mask; unsigned int i; =20 if (acpi_disabled || acpi_numa < 0 || @@ -299,19 +295,29 @@ void __init srat_parse_regions(paddr_t addr) =20 /* Set "PXM" as early as feasible. */ numa_fw_nid_name =3D "PXM"; - srat_region_mask =3D pdx_init_mask(addr); acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, srat_parse_region, 0); =20 - for (mask =3D srat_region_mask, i =3D 0; mask && i < e820.nr_map; i++) { + pfn_pdx_compression_setup(addr); + + /* Ensure all RAM ranges in the e820 are covered. */ + for (i =3D 0; i < e820.nr_map; i++) { if (e820.map[i].type !=3D E820_RAM) continue; =20 - if (~mask & pdx_region_mask(e820.map[i].addr, e820.map[i].size)) - mask =3D 0; + if (!pdx_is_region_compressible( + e820.map[i].addr, + PFN_UP(e820.map[i].addr + e820.map[i].size) - + PFN_DOWN(e820.map[i].addr))) { + pfn_pdx_compression_reset(); + printk(XENLOG_WARNING + "PFN compression disabled, RAM region [%#" PRIx64 + ", %#" PRIx64 "] not covered\n", + e820.map[i].addr, + e820.map[i].addr + e820.map[i].size - 1); + return; + } } - - pfn_pdx_hole_setup(mask >> PAGE_SHIFT); } =20 unsigned int numa_node_to_arch_nid(nodeid_t n) diff --git a/xen/common/pdx.c b/xen/common/pdx.c index 00aa7e43006d..c5ea58873c0e 100644 --- a/xen/common/pdx.c +++ b/xen/common/pdx.c @@ -19,6 +19,7 @@ #include #include #include +#include #include =20 /** @@ -55,6 +56,44 @@ void set_pdx_range(unsigned long smfn, unsigned long emf= n) __set_bit(idx, pdx_group_valid); } =20 +#ifndef CONFIG_PDX_NONE + +#ifdef CONFIG_X86 +# include +# define MAX_PFN_RANGES E820MAX +#elif defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY) +# include +# define MAX_PFN_RANGES NR_MEM_BANKS +#endif + +#ifndef MAX_PFN_RANGES +# error "Missing architecture maximum number of RAM ranges" +#endif + +/* Generic PFN compression helpers. */ +static struct pfn_range { + unsigned long base_pfn, pages; +} ranges[MAX_PFN_RANGES] __initdata; +static unsigned int __initdata nr_ranges; + +void __init pfn_pdx_add_region(paddr_t base, paddr_t size) +{ + if ( !size ) + return; + + if ( nr_ranges >=3D ARRAY_SIZE(ranges) ) + { + ASSERT((nr_ranges + 1) > nr_ranges); + nr_ranges++; + return; + } + + ranges[nr_ranges].base_pfn =3D PFN_DOWN(base); + ranges[nr_ranges++].pages =3D PFN_UP(base + size) - PFN_DOWN(base); +} + +#endif /* !CONFIG_PDX_NONE */ + #ifdef CONFIG_PDX_MASK_COMPRESSION =20 /* @@ -115,20 +154,25 @@ static uint64_t fill_mask(uint64_t mask) return mask; } =20 -bool pdx_is_region_compressible(paddr_t base, unsigned long npages) -{ - return !(paddr_to_pfn(base) & pfn_hole_mask) && - !(pdx_region_mask(base, npages * PAGE_SIZE) & ~ma_va_bottom_mas= k); -} - -/* We don't want to compress the low MAX_ORDER bits of the addresses. */ -uint64_t __init pdx_init_mask(uint64_t base_addr) -{ - return fill_mask(max(base_addr, - (uint64_t)1 << (MAX_ORDER + PAGE_SHIFT)) - 1); -} - -uint64_t pdx_region_mask(uint64_t base, uint64_t len) +/** + * Calculates a mask covering "moving" bits of all addresses of a region + * + * The i-th bit of the mask must be set if there's 2 different addresses + * in the region that have different j-th bits. where j >=3D i. + * + * e.g: + * base=3D0x1B00000000 + * len+base=3D0x1B00042000 + * + * ought to return 0x000007FFFF, which implies that every bit position + * with a zero in the mask remains unchanged in every address of the + * region. + * + * @param base Base address of the region + * @param len Size in octets of the region + * @return Mask of moving bits at the bottom of all the region addresses + */ +static uint64_t pdx_region_mask(uint64_t base, uint64_t len) { /* * We say a bit "moves" in a range if there exist 2 addresses in that @@ -143,9 +187,45 @@ uint64_t pdx_region_mask(uint64_t base, uint64_t len) return fill_mask(base ^ (base + len - 1)); } =20 -void __init pfn_pdx_hole_setup(unsigned long mask) +bool pdx_is_region_compressible(paddr_t base, unsigned long npages) +{ + return !(paddr_to_pfn(base) & pfn_hole_mask) && + !(pdx_region_mask(base, npages * PAGE_SIZE) & ~ma_va_bottom_mas= k); +} + +/** + * Creates the mask to start from when calculating non-compressible bits + * + * This function is intimately related to pdx_region_mask(), and together + * they are meant to calculate the mask of non-compressible bits given the + * current memory map. + * + * @param base_addr Address of the first maddr in the system + * @return An integer of the form 2^n - 1 + */ +static uint64_t __init pdx_init_mask(uint64_t base_addr) +{ + return fill_mask(max(base_addr, + /* Don't compress the low MAX_ORDER bits. */ + (uint64_t)1 << (MAX_ORDER + PAGE_SHIFT)) - 1); +} + +void __init pfn_pdx_compression_setup(paddr_t base) { unsigned int i, j, bottom_shift =3D 0, hole_shift =3D 0; + unsigned long mask =3D pdx_init_mask(base) >> PAGE_SHIFT; + + if ( nr_ranges > ARRAY_SIZE(ranges) ) + { + printk(XENLOG_WARNING + "Too many PFN ranges (%u > %zu), not attempting PFN compres= sion\n", + nr_ranges, ARRAY_SIZE(ranges)); + return; + } + + for ( i =3D 0; i < nr_ranges; i++ ) + mask |=3D ranges[i].base_pfn | + pdx_region_mask(ranges[i].base_pfn, ranges[i].pages); =20 /* * We skip the first MAX_ORDER bits, as we never want to compress them. @@ -184,6 +264,18 @@ void __init pfn_pdx_hole_setup(unsigned long mask) ma_top_mask =3D pfn_top_mask << PAGE_SHIFT; } =20 +void __init pfn_pdx_compression_reset(void) +{ + pfn_pdx_bottom_mask =3D ~0UL; + ma_va_bottom_mask =3D ~0UL; + pfn_top_mask =3D 0; + ma_top_mask =3D 0; + pfn_hole_mask =3D 0; + pfn_pdx_hole_shift =3D 0; + + nr_ranges =3D 0; +} + #endif /* CONFIG_PDX_COMPRESSION */ =20 /* diff --git a/xen/include/xen/pdx.h b/xen/include/xen/pdx.h index 8e373cac8b87..10153da98bf1 100644 --- a/xen/include/xen/pdx.h +++ b/xen/include/xen/pdx.h @@ -108,38 +108,6 @@ extern unsigned int pfn_pdx_hole_shift; extern unsigned long pfn_hole_mask; extern unsigned long pfn_top_mask, ma_top_mask; =20 -/** - * Calculates a mask covering "moving" bits of all addresses of a region - * - * The i-th bit of the mask must be set if there's 2 different addresses - * in the region that have different j-th bits. where j >=3D i. - * - * e.g: - * base=3D0x1B00000000 - * len+base=3D0x1B00042000 - * - * ought to return 0x000007FFFF, which implies that every bit position - * with a zero in the mask remains unchanged in every address of the - * region. - * - * @param base Base address of the region - * @param len Size in octets of the region - * @return Mask of moving bits at the bottom of all the region addresses - */ -uint64_t pdx_region_mask(uint64_t base, uint64_t len); - -/** - * Creates the mask to start from when calculating non-compressible bits - * - * This function is intimately related to pdx_region_mask(), and together - * they are meant to calculate the mask of non-compressible bits given the - * current memory map. - * - * @param base_addr Address of the first maddr in the system - * @return An integer of the form 2^n - 1 - */ -uint64_t pdx_init_mask(uint64_t base_addr); - /** * Map pfn to its corresponding pdx * @@ -189,17 +157,6 @@ static inline paddr_t directmapoff_to_maddr(unsigned l= ong offset) (offset & ma_va_bottom_mask)); } =20 -/** - * Initializes global variables with information about the compressible - * range of the current memory regions. - * - * @param mask This mask is the biggest pdx_mask of every region in the - * system ORed with all base addresses of every region in the - * system. This results in a mask where every zero in a bit - * position marks a potentially compressible bit. - */ -void pfn_pdx_hole_setup(unsigned long mask); - #endif /* CONFIG_PDX_MASK_COMPRESSION */ =20 #ifdef CONFIG_PDX_NONE @@ -220,17 +177,15 @@ static inline bool pdx_is_region_compressible(paddr_t= base, return true; } =20 -static inline uint64_t pdx_init_mask(uint64_t base_addr) +static inline void pfn_pdx_add_region(paddr_t base, paddr_t size) { - return 0; } =20 -static inline uint64_t pdx_region_mask(uint64_t base, uint64_t len) +static inline void pfn_pdx_compression_setup(paddr_t base) { - return 0; } =20 -static inline void pfn_pdx_hole_setup(unsigned long mask) +static inline void pfn_pdx_compression_reset(void) { } =20 @@ -247,6 +202,28 @@ static inline void pfn_pdx_hole_setup(unsigned long ma= sk) */ bool pdx_is_region_compressible(paddr_t base, unsigned long npages); =20 +/** + * Register a RAM region with the PFN compression logic. + * + * @param base Start of the region in bytes. + * @param size Length of the region in bytes. + */ +void pfn_pdx_add_region(paddr_t base, paddr_t size); + +/** + * Initializes global variables with information about the compressible + * range of the current memory regions. + * + * @param base address to start compression from. + */ +void pfn_pdx_compression_setup(paddr_t base); + +/** + * Reset the global variables to it's default values, thus disabling PFN + * compression. + */ +void pfn_pdx_compression_reset(void); + #endif /* !CONFIG_PDX_NONE */ #endif /* __XEN_PDX_H__ */ =20 --=20 2.49.0 From nobody Fri Dec 19 22:07:44 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1754387608; cv=none; d=zohomail.com; s=zohoarc; b=TkVuydCkWHiDR6lCGrUg+hCqNWBmEbTEmhOd6g++W3jy9zAE9rKCdJ2CjIH0CK56MY10BAslvN6GhXx+iSZOkTfg+6knkM/PDvI5HwHL68hmc+pzIKPnjPOUxiRCgnaFLEYadzq+D5j5Gh5Zme9MV6PyH0ccop1oqxy6ttU3g/g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1754387608; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=FsP/JixQiAB6kfYYFbr7LCCHkXcXLGwU+Dyro6/r2kA=; b=dZgggOj18mxrzp1Ff87d9TWG6r3L/6my1JFTJSfQzs8tLZSgU9IBLCyXF2anXuDTQBFIFJfub4rF1MM45oFes2vRZK0cMoakaFh5W8ld6eSPxWNl/sHCMpdzmsWE6YgS1flCLHW+9EI+UjUJsMlS7XcDnnc4ZeRf7NxvV0vX6+A= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1754387608853413.31086337420936; Tue, 5 Aug 2025 02:53:28 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1070225.1433880 (Exim 4.92) (envelope-from ) id 1ujEM7-0002GL-Kh; Tue, 05 Aug 2025 09:53:15 +0000 Received: by outflank-mailman (output) from mailman id 1070225.1433880; Tue, 05 Aug 2025 09:53:15 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEM7-0002Fc-Gq; Tue, 05 Aug 2025 09:53:15 +0000 Received: by outflank-mailman (input) for mailman id 1070225; Tue, 05 Aug 2025 09:53:14 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEM6-0001yh-UM for xen-devel@lists.xenproject.org; Tue, 05 Aug 2025 09:53:14 +0000 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [2a00:1450:4864:20::42c]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 012038fb-71e2-11f0-a321-13f23c93f187; Tue, 05 Aug 2025 11:53:14 +0200 (CEST) Received: by mail-wr1-x42c.google.com with SMTP id ffacd0b85a97d-3b78127c5d1so3045203f8f.3 for ; Tue, 05 Aug 2025 02:53:14 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id 5b1f17b1804b1-459d7d722dcsm81726915e9.24.2025.08.05.02.53.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Aug 2025 02:53:12 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 012038fb-71e2-11f0-a321-13f23c93f187 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1754387593; x=1754992393; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=FsP/JixQiAB6kfYYFbr7LCCHkXcXLGwU+Dyro6/r2kA=; b=Fz2ZanIxm2Y9ptFvTfaScOuxYCz2uUB2o45RmGWaC87T14ES7aYQTpob2AU7NLcvVh D2yImYzyyyIwq7jUkGxXwKaWTcfgKxymlave90bBthssmAhyGD+/gA+irSj4YcI1lVsN /L1LxvzkAO1xLqsauQ7gdSV/aDw3aPoKlwp0g= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754387593; x=1754992393; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FsP/JixQiAB6kfYYFbr7LCCHkXcXLGwU+Dyro6/r2kA=; b=xH04WBomTLqzJ1xfDrA214dtBnd5ypv8eOi2M9SWeW1hqPTyurL/9ymZ3QrsQquyKR o19WiU2+3e1i6Jacxot4q6m2kgfrmlPKQZ9lNmzkoqL23GB8qcVmFciX8m/1QE9zjca6 JsMxQRNu/4BINHyOrp++rMS1Nb/JWn2vO0hivJEjN6VvoIropDh8hr4A0qnDBCRx0zun dWPLnFoePEcWBTPL9gkIZHhAF36bZ8Rtj2TDso7P9G/fyTBhLVALEUMyyyZZUSYDjrMr 39G1+6cCPWSrCsuZcZHuC0cmbQgXOBpW/LMb+5s7ucn7flPCsZUoOzOOqRSre5QZRqOD GFhA== X-Gm-Message-State: AOJu0YzckIbQa3OW1AFpqgDLVbtKipqWjPDqLwO1GGag9DxKxKISrf8p IROsTB+7glh7NenISfoU/TX0xg+mNWpMhMNxqP9IvzfhCABHyGXyEvw4GGYvWZav1TDMtlyBWzK 6AQJO X-Gm-Gg: ASbGncvaWy6xRBACltW2ucE7WpNbaSKwrmtnCF+R0eeCDtgMwHHGs7V1bwoGT1qNi0A b+h+13K+bSQhf71ohVi2v5h+BHHdjBd4q4EBOMPvlYUCM9onBtR+iaWTsJE9Ve0UfdHHdwm5J4S 5W4nvNx0UssxkkoXBnnDBhuPe055NYQNlIKebtqcQbFjw0NOLKYsHdq/kRVQiDO+Uy2dLgEnWA5 Px9lW58yG8me8be6q52BRUoBCqLY4edtuNjA2/a4r9BdNXkRg6/t5RYihEa+iLC4/K6u66YQGff 6DjD2H5XXbc4NNrsJVEsy0PK8CnspSX8ACMeEck/dySTMFiYzTKLljF3WWUJjRGnaLS5AU3Ws/P KYZVo/KeOyGRDfPplGBX0m5YBYncM2z1ySgaPNym4/GcPLv7MvsIrSsdSFPAg0y4AIQ== X-Google-Smtp-Source: AGHT+IH49zUlNPTt/qK45COiRhwo0/cwFIVsqcrvnCBiw9Pq26t9NZrr2MBWRQ3DVFuB+RVdrt8m8w== X-Received: by 2002:a05:6000:2584:b0:3a5:3b93:be4b with SMTP id ffacd0b85a97d-3b8d94817camr9322675f8f.25.1754387593511; Tue, 05 Aug 2025 02:53:13 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , Stefano Stabellini , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH v4 3/8] pdx: introduce command line compression toggle Date: Tue, 5 Aug 2025 11:52:52 +0200 Message-ID: <20250805095257.74975-4-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250805095257.74975-1-roger.pau@citrix.com> References: <20250805095257.74975-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1754387611134116600 Introduce a command line option to allow disabling PDX compression. The disabling is done by turning pfn_pdx_add_region() into a no-op, so when attempting to initialize the selected compression algorithm the array of ranges to compress is empty. Signed-off-by: Roger Pau Monn=C3=A9 Reviewed-by: Jan Beulich --- Changes since v1: - New in this version. --- docs/misc/xen-command-line.pandoc | 9 +++++++++ xen/common/pdx.c | 14 +++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line= .pandoc index 6865a61220ca..5dd2ab82b7aa 100644 --- a/docs/misc/xen-command-line.pandoc +++ b/docs/misc/xen-command-line.pandoc @@ -2072,6 +2072,15 @@ for all of them (`true`), only for those subject to = XPTI (`xpti`) or for those not subject to XPTI (`no-xpti`). The feature is used only in case INVPCID is supported and not disabled via `invpcid=3Dfalse`. =20 +###=C2=A0pdx-compress +> `=3D ` + +> Default: `true` if CONFIG_PDX_NONE is unset + +Only relevant when the hypervisor is build with PFN PDX compression. Contr= ols +whether Xen will engage in PFN compression. The algorithm used for PFN +compression is selected at build time from Kconfig. + ### ple_gap > `=3D ` =20 diff --git a/xen/common/pdx.c b/xen/common/pdx.c index c5ea58873c0e..f4a3dcf6cb60 100644 --- a/xen/common/pdx.c +++ b/xen/common/pdx.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include =20 @@ -76,9 +77,13 @@ static struct pfn_range { } ranges[MAX_PFN_RANGES] __initdata; static unsigned int __initdata nr_ranges; =20 +static bool __initdata pdx_compress =3D true; +boolean_param("pdx-compress", pdx_compress); + void __init pfn_pdx_add_region(paddr_t base, paddr_t size) { - if ( !size ) + /* Without ranges there's no PFN compression. */ + if ( !size || !pdx_compress ) return; =20 if ( nr_ranges >=3D ARRAY_SIZE(ranges) ) @@ -215,6 +220,13 @@ void __init pfn_pdx_compression_setup(paddr_t base) unsigned int i, j, bottom_shift =3D 0, hole_shift =3D 0; unsigned long mask =3D pdx_init_mask(base) >> PAGE_SHIFT; =20 + if ( !nr_ranges ) + { + printk(XENLOG_DEBUG "PFN compression disabled%s\n", + pdx_compress ? ": no ranges provided" : ""); + return; + } + if ( nr_ranges > ARRAY_SIZE(ranges) ) { printk(XENLOG_WARNING --=20 2.49.0 From nobody Fri Dec 19 22:07:44 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1754387612; cv=none; d=zohomail.com; s=zohoarc; b=aR6E7BmfqxY/VaRuMRgXnH0ZNRcVByy4WP1COj/7Yv4FF2H9XAiRPjuOjXzXHYaPrR1NAoWxK2cRLYUl1N3kGpX58Zbl1+/l8KLEH5YCfUVq/rcHuoOH1dYak0G/VMIAETRMJ9z7o7wMAfL7or8aTc3rI7wi40A3JccHxBmzdz0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1754387612; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=f1xBFAQp2tU3X5eYxoTRxXwfOAwjqwHWw59TnMhPZ9E=; b=VPLRXLk/TF9L6W3+Z7ryQC9YjvCOdzc94I5d4VV3HLObhCyIjvjSCCCwLCYnlpjGHwBh5iaJYHYxtFx59P1DZWl4o4ChJoZr1sKVQ0ONbf2cayjbQMdPOZja2UEf2FHS2b9CABG6dmILUWOMBFNwjL0SHeIFRAMHOFWgDohvzc0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1754387612760316.59396916840467; Tue, 5 Aug 2025 02:53:32 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1070228.1433910 (Exim 4.92) (envelope-from ) id 1ujEMB-000323-IN; Tue, 05 Aug 2025 09:53:19 +0000 Received: by outflank-mailman (output) from mailman id 1070228.1433910; Tue, 05 Aug 2025 09:53:19 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEMB-00031U-DS; Tue, 05 Aug 2025 09:53:19 +0000 Received: by outflank-mailman (input) for mailman id 1070228; Tue, 05 Aug 2025 09:53:17 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEM9-00026G-RI for xen-devel@lists.xenproject.org; Tue, 05 Aug 2025 09:53:17 +0000 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [2a00:1450:4864:20::42d]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 02297962-71e2-11f0-b898-0df219b8e170; Tue, 05 Aug 2025 11:53:16 +0200 (CEST) Received: by mail-wr1-x42d.google.com with SMTP id ffacd0b85a97d-3b7886bee77so4477966f8f.0 for ; Tue, 05 Aug 2025 02:53:16 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id ffacd0b85a97d-3b79c3b95f4sm18447847f8f.23.2025.08.05.02.53.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Aug 2025 02:53:14 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 02297962-71e2-11f0-b898-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1754387595; x=1754992395; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=f1xBFAQp2tU3X5eYxoTRxXwfOAwjqwHWw59TnMhPZ9E=; b=c7MBeCHiCF/1qUpO+iiwYHbrHY9wcB+QuR2xazxnaFp4qjTLqPTR2LtDv1utuNCBgH mLqLd13md5+PXbvXvf5bT98cPORVCM3tjny5EmoK7y9f5IzxPWFN8J+NOpjGRt48AAWZ DZOJZltmaspumcZLHnl0fAzNrQTVbm/IDn6cQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754387595; x=1754992395; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=f1xBFAQp2tU3X5eYxoTRxXwfOAwjqwHWw59TnMhPZ9E=; b=GLtiPxzGsu4E6tKIYRXwTdjyD5BpFILq3EvgkcOKkYbldps8Dr4O7AtanZ63rFjK1E EKnoV+X2kCLy3UIOwma26MjqkJgomBEpcJct1OpG2ic85e005oc+1Cb/6BJO1vH2dcYn IDmPvDXFZ1UsAFQTFrLzNJE4ZNTAwn8nkKe23cu8CVvtG4lscqQT4fGrgRKGZ53HA38A TCTAEVEaUQX8ofqL+aX5KRDEelW8NVvdgfmOY3bl1ycKHNlRNPDtF/8Qqxj8HxkgMG9v xy+O7z5ctFbyaO1ZPZ0hqo56XyyZVHCJvGatEz6uCoJoGKVdd9LRiEU3il4+EbE1af+F mcKg== X-Gm-Message-State: AOJu0YzdMR7yG4bRWb5amUVeQOkD7ISxBhBgMTC6gEYD2JdSebsEUj08 3c1EzmdvAau7dEurca9jkEAViWDtpu7yx6eIyGLvrPc4YC2j9zprL9a4jJ3JKpz0pPGXs6N9UjC 8nzNq X-Gm-Gg: ASbGncvzxsNC7HZPe1VJkJ5G1Ny1JYdVfnePHfFmxd9HEr0XETfY/v33Y4swDQtErJp OBca8ZsUaCYKRWbEJAbt1rZTjI/WUOTJlR6uxjsQO4fc7aejhN5Z/DqJcXCpsbW2sXHl/lCf5FB qiUxjVYqRmuDCvYcLJz3oGu52LlleCE0xz9AN+/ZTWJnXrw5hX9DotlOlV9n6aEmI1v/Cj1NIF+ rOjVJtwwiFM8ntV9uVi26C3IEcrcX8yxXrUiG6QMK9rFwRk74hsuCYrpYq+RWun27H5gl/GIDoi nySQEaSo4ic+EDZj4XDnsblvuQnQz1azqu9HS8OUZgLdBt2BeBRSZtGHzvRKI7kGVPboLmlbk99 zxUFQLSZVvPeO1P/JezYC5sO5805y6/cVl+UhZ2em1l5iN0qTskJHcOwnEIWHlT5idg== X-Google-Smtp-Source: AGHT+IFHLgGTaQ6E5u7Plz8Q4Qef8ivTkL1ylGSdq7BstwwYvvUspsHFDN/BNElPxIzFK+sVHrumXg== X-Received: by 2002:a5d:588a:0:b0:3b7:e3c3:fbb6 with SMTP id ffacd0b85a97d-3b8d94ba9aemr9316236f8f.31.1754387594710; Tue, 05 Aug 2025 02:53:14 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Jan Beulich , Andrew Cooper , Anthony PERARD , Michal Orzel , Julien Grall , Stefano Stabellini Subject: [PATCH v4 4/8] pdx: allow per-arch optimization of PDX conversion helpers Date: Tue, 5 Aug 2025 11:52:53 +0200 Message-ID: <20250805095257.74975-5-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250805095257.74975-1-roger.pau@citrix.com> References: <20250805095257.74975-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1754387613849124100 There are four performance critical PDX conversion helpers that do the PFN to/from PDX and the physical addresses to/from directmap offsets translations. In the absence of an active PDX compression, those functions would still do the calculations needed, just to return the same input value as no translation is in place and hence PFN and PDX spaces are identity mapped. To reduce the overhead of having to do the pointless calculations allow architectures to implement the translation helpers in a per-arch header. Rename the existing conversion functions to add a trailing _xlate suffix, so that the per-arch headers can define the non suffixed versions. Currently only x86 implements meaningful custom handlers to short circuit the translation when not active, using asm goto. Other architectures use generic macros that map the non-xlate to the xlate variants to keep the previous behavior. Signed-off-by: Roger Pau Monn=C3=A9 Reviewed-by: Jan Beulich --- Changes since v3: - Use has_include. Changes since v2: - Consume the skip label as parameter in the PDX optimize macro. Changes since v1: - Pull return out of OPTIMIZE_PDX macro. - undef OPTIMIZE_PDX. --- Would it make sense to move the x86 implementation to the common pdx.h header and let architectures define PDX_ASM_GOTO_SKIP instead? --- xen/arch/x86/include/asm/cpufeatures.h | 1 + xen/arch/x86/include/asm/pdx.h | 71 ++++++++++++++++++++++++++ xen/arch/x86/srat.c | 6 ++- xen/common/pdx.c | 10 ++-- xen/include/xen/pdx.h | 29 ++++++++--- 5 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 xen/arch/x86/include/asm/pdx.h diff --git a/xen/arch/x86/include/asm/cpufeatures.h b/xen/arch/x86/include/= asm/cpufeatures.h index bc108c3819e8..71308d9dafc8 100644 --- a/xen/arch/x86/include/asm/cpufeatures.h +++ b/xen/arch/x86/include/asm/cpufeatures.h @@ -42,6 +42,7 @@ XEN_CPUFEATURE(XEN_IBT, X86_SYNTH(27)) /* Xen u= ses CET Indirect Branch XEN_CPUFEATURE(IBPB_ENTRY_PV, X86_SYNTH(28)) /* MSR_PRED_CMD used by X= en for PV */ XEN_CPUFEATURE(IBPB_ENTRY_HVM, X86_SYNTH(29)) /* MSR_PRED_CMD used by X= en for HVM */ XEN_CPUFEATURE(USE_VMCALL, X86_SYNTH(30)) /* Use VMCALL instead of = VMMCALL */ +XEN_CPUFEATURE(PDX_COMPRESSION, X86_SYNTH(31)) /* PDX compression */ =20 /* Bug words follow the synthetic words. */ #define X86_NR_BUG 1 diff --git a/xen/arch/x86/include/asm/pdx.h b/xen/arch/x86/include/asm/pdx.h new file mode 100644 index 000000000000..6be7e1185eb1 --- /dev/null +++ b/xen/arch/x86/include/asm/pdx.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef X86_PDX_H +#define X86_PDX_H + +#include + +/* + * Introduce a macro to avoid repeating the same asm goto block in each he= lper. + * Note the macro is strictly tied to the code in the helpers. + */ +#define PDX_ASM_GOTO(label) \ + asm_inline goto ( \ + ALTERNATIVE( \ + "", \ + "jmp %l0", \ + ALT_NOT(X86_FEATURE_PDX_COMPRESSION)) \ + : : : : label ) + +static inline unsigned long pfn_to_pdx(unsigned long pfn) +{ + PDX_ASM_GOTO(skip); + + return pfn_to_pdx_xlate(pfn); + + skip: + return pfn; +} + +static inline unsigned long pdx_to_pfn(unsigned long pdx) +{ + PDX_ASM_GOTO(skip); + + return pdx_to_pfn_xlate(pdx); + + skip: + return pdx; +} + +static inline unsigned long maddr_to_directmapoff(paddr_t ma) +{ + PDX_ASM_GOTO(skip); + + return maddr_to_directmapoff_xlate(ma); + + skip: + return ma; +} + +static inline paddr_t directmapoff_to_maddr(unsigned long offset) +{ + PDX_ASM_GOTO(skip); + + return directmapoff_to_maddr_xlate(offset); + + skip: + return offset; +} + +#undef PDX_ASM_GOTO_SKIP + +#endif /* X86_PDX_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/x86/srat.c b/xen/arch/x86/srat.c index 747607439fb4..42ccb0c0f3ae 100644 --- a/xen/arch/x86/srat.c +++ b/xen/arch/x86/srat.c @@ -298,7 +298,8 @@ void __init srat_parse_regions(paddr_t addr) acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, srat_parse_region, 0); =20 - pfn_pdx_compression_setup(addr); + if (!pfn_pdx_compression_setup(addr)) + return; =20 /* Ensure all RAM ranges in the e820 are covered. */ for (i =3D 0; i < e820.nr_map; i++) { @@ -318,6 +319,9 @@ void __init srat_parse_regions(paddr_t addr) return; } } + + /* If we got this far compression is working as expected. */ + setup_force_cpu_cap(X86_FEATURE_PDX_COMPRESSION); } =20 unsigned int numa_node_to_arch_nid(nodeid_t n) diff --git a/xen/common/pdx.c b/xen/common/pdx.c index f4a3dcf6cb60..c9ec86729151 100644 --- a/xen/common/pdx.c +++ b/xen/common/pdx.c @@ -215,7 +215,7 @@ static uint64_t __init pdx_init_mask(uint64_t base_addr) (uint64_t)1 << (MAX_ORDER + PAGE_SHIFT)) - 1); } =20 -void __init pfn_pdx_compression_setup(paddr_t base) +bool __init pfn_pdx_compression_setup(paddr_t base) { unsigned int i, j, bottom_shift =3D 0, hole_shift =3D 0; unsigned long mask =3D pdx_init_mask(base) >> PAGE_SHIFT; @@ -224,7 +224,7 @@ void __init pfn_pdx_compression_setup(paddr_t base) { printk(XENLOG_DEBUG "PFN compression disabled%s\n", pdx_compress ? ": no ranges provided" : ""); - return; + return false; } =20 if ( nr_ranges > ARRAY_SIZE(ranges) ) @@ -232,7 +232,7 @@ void __init pfn_pdx_compression_setup(paddr_t base) printk(XENLOG_WARNING "Too many PFN ranges (%u > %zu), not attempting PFN compres= sion\n", nr_ranges, ARRAY_SIZE(ranges)); - return; + return false; } =20 for ( i =3D 0; i < nr_ranges; i++ ) @@ -263,7 +263,7 @@ void __init pfn_pdx_compression_setup(paddr_t base) } } if ( !hole_shift ) - return; + return false; =20 printk(KERN_INFO "PFN compression on bits %u...%u\n", bottom_shift, bottom_shift + hole_shift - 1); @@ -274,6 +274,8 @@ void __init pfn_pdx_compression_setup(paddr_t base) pfn_hole_mask =3D ((1UL << hole_shift) - 1) << bottom_shift; pfn_top_mask =3D ~(pfn_pdx_bottom_mask | pfn_hole_mask); ma_top_mask =3D pfn_top_mask << PAGE_SHIFT; + + return true; } =20 void __init pfn_pdx_compression_reset(void) diff --git a/xen/include/xen/pdx.h b/xen/include/xen/pdx.h index 10153da98bf1..425d45e9f08e 100644 --- a/xen/include/xen/pdx.h +++ b/xen/include/xen/pdx.h @@ -114,7 +114,7 @@ extern unsigned long pfn_top_mask, ma_top_mask; * @param pfn Frame number * @return Obtained pdx after compressing the pfn */ -static inline unsigned long pfn_to_pdx(unsigned long pfn) +static inline unsigned long pfn_to_pdx_xlate(unsigned long pfn) { return (pfn & pfn_pdx_bottom_mask) | ((pfn & pfn_top_mask) >> pfn_pdx_hole_shift); @@ -126,7 +126,7 @@ static inline unsigned long pfn_to_pdx(unsigned long pf= n) * @param pdx Page index * @return Obtained pfn after decompressing the pdx */ -static inline unsigned long pdx_to_pfn(unsigned long pdx) +static inline unsigned long pdx_to_pfn_xlate(unsigned long pdx) { return (pdx & pfn_pdx_bottom_mask) | ((pdx << pfn_pdx_hole_shift) & pfn_top_mask); @@ -139,7 +139,7 @@ static inline unsigned long pdx_to_pfn(unsigned long pd= x) * @return Offset on the direct map where that * machine address can be accessed */ -static inline unsigned long maddr_to_directmapoff(paddr_t ma) +static inline unsigned long maddr_to_directmapoff_xlate(paddr_t ma) { return (((ma & ma_top_mask) >> pfn_pdx_hole_shift) | (ma & ma_va_bottom_mask)); @@ -151,7 +151,7 @@ static inline unsigned long maddr_to_directmapoff(paddr= _t ma) * @param offset Offset into the direct map * @return Corresponding machine address of that virtual location */ -static inline paddr_t directmapoff_to_maddr(unsigned long offset) +static inline paddr_t directmapoff_to_maddr_xlate(unsigned long offset) { return ((((paddr_t)offset << pfn_pdx_hole_shift) & ma_top_mask) | (offset & ma_va_bottom_mask)); @@ -181,8 +181,9 @@ static inline void pfn_pdx_add_region(paddr_t base, pad= dr_t size) { } =20 -static inline void pfn_pdx_compression_setup(paddr_t base) +static inline bool pfn_pdx_compression_setup(paddr_t base) { + return false; } =20 static inline void pfn_pdx_compression_reset(void) @@ -191,6 +192,21 @@ static inline void pfn_pdx_compression_reset(void) =20 #else /* !CONFIG_PDX_NONE */ =20 +/* + * Allow each architecture to define its (possibly optimized) versions of = the + * translation functions. + * + * Do not use _xlate suffixed functions, always use the non _xlate variant= s. + */ +#if __has_include() +# include +#else +# define pdx_to_pfn pdx_to_pfn_xlate +# define pfn_to_pdx pfn_to_pdx_xlate +# define maddr_to_directmapoff maddr_to_directmapoff_xlate +# define directmapoff_to_maddr directmapoff_to_maddr_xlate +#endif + /* Shared functions implemented by all PDX compressions. */ =20 /** @@ -215,8 +231,9 @@ void pfn_pdx_add_region(paddr_t base, paddr_t size); * range of the current memory regions. * * @param base address to start compression from. + * @return True if PDX compression has been enabled. */ -void pfn_pdx_compression_setup(paddr_t base); +bool pfn_pdx_compression_setup(paddr_t base); =20 /** * Reset the global variables to it's default values, thus disabling PFN --=20 2.49.0 From nobody Fri Dec 19 22:07:44 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1754387622; cv=none; d=zohomail.com; s=zohoarc; b=aDy4u9ZebL7c0Qt28pS3EDnTU4TDW/lNrjuOqcLlOfRy5EjxJiQLARe5GUM5mho7wQ2Qvdg1SUekja0XuwLTezKfsTaEUiDbLk1pYFr+rWaNY/joJT8AkP5CefWTNxCKJNT474/YI2+X8oN798q0aqSx21tv/OopmnDmG8Ebhg8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1754387622; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=GhNVb0ZBMkEpsnDvzYh3YmEGHHdUK0KvBkXDeBZiN3g=; b=BfCOHHf9v4dJdaaRYXIdowxN2rLolbgAE25l52wJRnV5wObjvPUmMHAvn0Gw/oip83pK0p4/+6gfP2N8f2DyY5RDVBWUD/AuNEUK3GOTmCvLec3QWtFzpgL9KYgJ3+N8be2H/X2/goCTpaN7FtnaHaTnKkqZSfknv0a56CZkO6k= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1754387622382404.58222370766885; Tue, 5 Aug 2025 02:53:42 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1070227.1433906 (Exim 4.92) (envelope-from ) id 1ujEMB-0002zW-8x; Tue, 05 Aug 2025 09:53:19 +0000 Received: by outflank-mailman (output) from mailman id 1070227.1433906; Tue, 05 Aug 2025 09:53:19 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEMB-0002zG-52; Tue, 05 Aug 2025 09:53:19 +0000 Received: by outflank-mailman (input) for mailman id 1070227; Tue, 05 Aug 2025 09:53:17 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEM9-0001yh-Bl for xen-devel@lists.xenproject.org; Tue, 05 Aug 2025 09:53:17 +0000 Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [2a00:1450:4864:20::329]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 028c75f3-71e2-11f0-a321-13f23c93f187; Tue, 05 Aug 2025 11:53:16 +0200 (CEST) Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-458bc3ce3beso17623665e9.1 for ; Tue, 05 Aug 2025 02:53:16 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id ffacd0b85a97d-3b79c3ac115sm18611197f8f.12.2025.08.05.02.53.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Aug 2025 02:53:15 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 028c75f3-71e2-11f0-a321-13f23c93f187 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1754387596; x=1754992396; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GhNVb0ZBMkEpsnDvzYh3YmEGHHdUK0KvBkXDeBZiN3g=; b=akO85gkBD+r0K5/Y7o4s68DoH8pGUy5Tze4ruo/N6qqTfZhD+f7BjUpNpQhZ56Y05V ZJxUwTp7Bq4NsYjiQN12GmXFL99TajTUEcNzzOKJ3pgxU9huIers7PzzMAkVO3WGBrOW W/r4vADg35aUrjZYBBiAtqhiIc2wgecAckStY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754387596; x=1754992396; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GhNVb0ZBMkEpsnDvzYh3YmEGHHdUK0KvBkXDeBZiN3g=; b=EGfW684fxW0M5OpvKlH3l+yzZK51BCkD+b9iUl55qvu10e1Yfhf3Ndv/VOlXXyQAj1 nLoaqhrJh49qe4GV9khvG6JzDKo+FC+seHz7gshZ9vNjg1ET0zQvUB8y59cASjSWJLM8 x/QCVVNA21f7yos3ntPr88LxYIHsY6eT7KKHCPQtfNjjanMvJbzA+n8lUEJvtHgW3W2t 3k3Xh7vWjq/myEqIoecw8XhUFev9IijmfNGeZWmmK/UFyOnO0UlWwqUmR0y8XNtwWL7o d9OWCiD6O7Kkgy6OlvypXnsTN7jLPDWE2K8iDyoYoKmbX0oUaaZT8W6Y0r+tRv7JNHsO OKFQ== X-Gm-Message-State: AOJu0YxJ+r+/+AQhRTN7b3ngXZ175xiSSSIUh90y+PRq4+CW2bq7d4Kg YqpNQSc/ZdO1gR+2ij/Hgp0xAMeAxEbisY5p8G35QLqavXjAJz4mQ3ai5fhv7MiCikmR05ugfdy Ou91M X-Gm-Gg: ASbGncsd7g8Sj61aEk9+o5PiqRI7aoiW2znZGTjpS1GA6qaTQGT7/xSYMVxrHsM8WrR oh3lamArNWax1+8TTlxPdLkvBSG41x0v8qQX0Iff6+Qo9e1BZOW8fl+W+i7ymI5S0eEiR3pu5wW Net4dMJZkxVrd0m/7S7Ct5NRE+HYnDmQZqTZBPzSJBumcvk7OvJzUaZ1qu7/npfgFHzlVsMb+WM d0vXcHSzcoSv/l09RbtYp2gv6n8UHmMGlEknFibJwzOMCXdZig8+eVKDnlH7iORTjPBHc/gJbQ7 8ygFeZ4V02RsYLx2DXyH1w/sATmpx7S8E84rHVYPOuMT64WKSRHIedIiS2NNAJvjximoKdsMCKb oGHV0RNHtikr7uLR2ljX8h5UG80YM5NnIzb1poKylVHNZOFjbgU+d6ko/Txu1GMDjXA== X-Google-Smtp-Source: AGHT+IF8Hlz1NANF27jwxjR7WhHDaJIu9qeg8DsnUouM8UGa3gJLwXNf3/SypT85GbgbUedpf/x+lw== X-Received: by 2002:a05:600c:4752:b0:456:25aa:e9c0 with SMTP id 5b1f17b1804b1-458b69e3710mr115207405e9.14.1754387595822; Tue, 05 Aug 2025 02:53:15 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Anthony PERARD , Andrew Cooper , Michal Orzel , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v4 5/8] test/pdx: add PDX compression unit tests Date: Tue, 5 Aug 2025 11:52:54 +0200 Message-ID: <20250805095257.74975-6-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250805095257.74975-1-roger.pau@citrix.com> References: <20250805095257.74975-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1754387623334116600 Introduce a set of unit tests for PDX compression. The unit tests contains both real and crafted memory maps that are then compressed using the selected PDX algorithm. Note the build system for the unit tests has been done in a way to support adding new compression algorithms easily. That requires generating a new test-pdx- executable that's build with the selected PDX compression enabled. Currently the only generated executable is test-pdx-mask that tests PDX mask compression. Signed-off-by: Roger Pau Monn=C3=A9 Reviewed-by: Anthony PERARD --- Changes since v2: - Use set -e when running the tests. - Drop stray removal of pdx.c. - Use * instead of ? for header blank space capture. - Add some more memory maps. Changes since v1: - New in this version (partially pulled out from a different patch). --- tools/tests/Makefile | 1 + tools/tests/pdx/.gitignore | 2 + tools/tests/pdx/Makefile | 49 +++++++ tools/tests/pdx/harness.h | 84 ++++++++++++ tools/tests/pdx/test-pdx.c | 267 +++++++++++++++++++++++++++++++++++++ xen/common/pdx.c | 4 + 6 files changed, 407 insertions(+) create mode 100644 tools/tests/pdx/.gitignore create mode 100644 tools/tests/pdx/Makefile create mode 100644 tools/tests/pdx/harness.h create mode 100644 tools/tests/pdx/test-pdx.c diff --git a/tools/tests/Makefile b/tools/tests/Makefile index 36928676a666..97ba2a13894d 100644 --- a/tools/tests/Makefile +++ b/tools/tests/Makefile @@ -9,6 +9,7 @@ ifneq ($(clang),y) SUBDIRS-$(CONFIG_X86) +=3D x86_emulator endif SUBDIRS-y +=3D xenstore +SUBDIRS-y +=3D pdx SUBDIRS-y +=3D rangeset SUBDIRS-y +=3D vpci SUBDIRS-y +=3D paging-mempool diff --git a/tools/tests/pdx/.gitignore b/tools/tests/pdx/.gitignore new file mode 100644 index 000000000000..a32c7db4de79 --- /dev/null +++ b/tools/tests/pdx/.gitignore @@ -0,0 +1,2 @@ +/pdx.h +/test-pdx-mask diff --git a/tools/tests/pdx/Makefile b/tools/tests/pdx/Makefile new file mode 100644 index 000000000000..b3734afde686 --- /dev/null +++ b/tools/tests/pdx/Makefile @@ -0,0 +1,49 @@ +XEN_ROOT=3D$(CURDIR)/../../.. +include $(XEN_ROOT)/tools/Rules.mk + +TARGETS :=3D test-pdx-mask + +.PHONY: all +all: $(TARGETS) + +.PHONY: run +run: $(TARGETS) +ifeq ($(CC),$(HOSTCC)) + set -e; \ + for test in $? ; do \ + ./$$test ; \ + done +else + $(warning HOSTCC !=3D CC, will not run test) +endif + +.PHONY: clean +clean: + $(RM) -- *.o $(TARGETS) $(DEPS_RM) pdx.h + +.PHONY: distclean +distclean: clean + $(RM) -- *~ + +.PHONY: install +install: all + $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC)/tests + $(INSTALL_PROG) $(TARGETS) $(DESTDIR)$(LIBEXEC)/tests + +.PHONY: uninstall +uninstall: + $(RM) -- $(patsubst %,$(DESTDIR)$(LIBEXEC)/tests/%,$(TARGETS)) + +pdx.h: $(XEN_ROOT)/xen/include/xen/pdx.h + sed -E -e '/^#[[:space:]]*include/d' <$< >$@ + +CFLAGS +=3D -D__XEN_TOOLS__ +CFLAGS +=3D $(APPEND_CFLAGS) +CFLAGS +=3D $(CFLAGS_xeninclude) + +test-pdx-mask: CFLAGS +=3D -DCONFIG_PDX_MASK_COMPRESSION + +test-pdx-%: test-pdx.c pdx.h + $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_$*.o) -o $@ $< $(APPEND_CFLAGS) + +-include $(DEPS_INCLUDE) diff --git a/tools/tests/pdx/harness.h b/tools/tests/pdx/harness.h new file mode 100644 index 000000000000..5bef7df650d2 --- /dev/null +++ b/tools/tests/pdx/harness.h @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Unit tests for PDX compression. + * + * Copyright (C) 2025 Cloud Software Group + */ + +#ifndef _TEST_HARNESS_ +#define _TEST_HARNESS_ + +#include +#include +#include +#include +#include +#include + +#include + +#define __init +#define __initdata +#define __ro_after_init +#define cf_check + +#define printk printf +#define XENLOG_INFO +#define XENLOG_DEBUG +#define XENLOG_WARNING +#define KERN_INFO + +#define BITS_PER_LONG (unsigned int)(sizeof(unsigned long) * 8) + +#define PAGE_SHIFT 12 +/* Some libcs define PAGE_SIZE in limits.h. */ +#undef PAGE_SIZE +#define PAGE_SIZE (1 << PAGE_SHIFT) +#define MAX_ORDER 18 /* 2 * PAGETABLE_ORDER (9) */ + +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) + +#define pfn_to_paddr(pfn) ((paddr_t)(pfn) << PAGE_SHIFT) +#define paddr_to_pfn(pa) ((unsigned long)((pa) >> PAGE_SHIFT)) + +#define MAX_RANGES 16 +#define MAX_PFN_RANGES MAX_RANGES + +#define ASSERT assert + +#define CONFIG_DEBUG + +static inline unsigned int find_next( + const unsigned long *addr, unsigned int size, unsigned int off, bool v= alue) +{ + unsigned int i; + + ASSERT(size <=3D BITS_PER_LONG); + + for ( i =3D off; i < size; i++ ) + if ( !!(*addr & (1UL << i)) =3D=3D value ) + return i; + + return size; +} + +#define find_next_zero_bit(a, s, o) find_next(a, s, o, false) +#define find_next_bit(a, s, o) find_next(a, s, o, true) + +#define boolean_param(name, func) + +typedef uint64_t paddr_t; + +#include "pdx.h" + +#endif + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/tests/pdx/test-pdx.c b/tools/tests/pdx/test-pdx.c new file mode 100644 index 000000000000..0798ccee359b --- /dev/null +++ b/tools/tests/pdx/test-pdx.c @@ -0,0 +1,267 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Unit tests for PDX compression. + * + * Copyright (C) 2025 Cloud Software Group + */ + +#include "harness.h" + +#include "../../xen/common/pdx.c" + +struct range { + /* Ranges are defined as [start, end). */ + unsigned long start, end; +}; + +static void print_ranges(const struct range *r) +{ + unsigned int i; + + printf("Ranges:\n"); + + for ( i =3D 0; i < MAX_RANGES; i++ ) + { + if ( !r[i].start && !r[i].end ) + break; + + printf(" %013lx-%013lx\n", r[i].start, r[i].end); + } +} + +int main(int argc, char **argv) +{ + static const struct { + struct range ranges[MAX_RANGES]; + bool compress; + } tests[] =3D { +#ifdef __LP64__ + /* + * Only for targets where unsigned long is 64bits, otherwise compi= ler + * will complain about truncation from 'long long' -> 'long' conve= rsion. + * + * Real memory map from a 4s Intel GNR. Not compressible using PDX + * mask compression. + */ + { + .ranges =3D { + { .start =3D 0, .end =3D 0x80000UL }, + { .start =3D 0x0100000UL, .end =3D 0x8080000UL }, + { .start =3D 0x63e80000UL, .end =3D 0x6be80000UL }, + { .start =3D 0xc7e80000UL, .end =3D 0xcfe80000UL }, + { .start =3D 0x12be80000UL, .end =3D 0x133e80000UL }, + }, + .compress =3D false, + }, + /* Simple hole. */ + { + .ranges =3D { + { .start =3D = 0, + .end =3D (1UL << MAX_ORDER)= * 1 }, + { .start =3D (1UL << (MAX_ORDER * 2)) | = 0, + .end =3D (1UL << (MAX_ORDER * 2)) | (1UL << MAX_ORDER)= * 1 }, + }, + .compress =3D true, + }, + /* Simple hole, unsorted ranges. */ + { + .ranges =3D { + { .start =3D (1UL << (MAX_ORDER * 2)) | = 0, + .end =3D (1UL << (MAX_ORDER * 2)) | (1UL << MAX_ORDER)= * 1 }, + { .start =3D = 0, + .end =3D (1UL << MAX_ORDER)= * 1 }, + }, + .compress =3D true, + }, + /* PDX compression, 2 ranges covered by the lower mask. */ + { + .ranges =3D { + { .start =3D 0, + .end =3D (1 << MAX_ORDER) * 1 }, + { .start =3D (1 << MAX_ORDER) * 2, + .end =3D (1 << MAX_ORDER) * 3 }, + { .start =3D (1 << MAX_ORDER) * 20, + .end =3D (1 << MAX_ORDER) * 22 }, + }, + .compress =3D true, + }, + /* Single range not starting at 0. */ + { + .ranges =3D { + { .start =3D (1 << MAX_ORDER) * 10, + .end =3D (1 << MAX_ORDER) * 11 }, + }, + .compress =3D true, + }, + /* Resulting PDX region size leads to no compression. */ + { + .ranges =3D { + { .start =3D 0, + .end =3D (1 << MAX_ORDER) * 1 }, + { .start =3D (1 << MAX_ORDER) * 2, + .end =3D (1 << MAX_ORDER) * 3 }, + { .start =3D (1 << MAX_ORDER) * 4, + .end =3D (1 << MAX_ORDER) * 7 }, + { .start =3D (1 << MAX_ORDER) * 8, + .end =3D (1 << MAX_ORDER) * 12 }, + }, + .compress =3D false, + }, + /* AMD Versal Gen 2 ARM board. */ + { + .ranges =3D { + { .start =3D 0, .end =3D 0x80000UL }, + { .start =3D 0x800000UL, .end =3D 0x880000UL }, + { .start =3D 0x50000000UL, .end =3D 0x50080000UL }, + { .start =3D 0x60000000UL, .end =3D 0x60080000UL }, + { .start =3D 0x70000000UL, .end =3D 0x70080000UL }, + }, + .compress =3D true, + }, + /* Unsorted ranges, lower one not starting at 0. */ + { + .ranges =3D { + { .start =3D (1UL << (35 - PAGE_SHIFT)) + (1 << MAX_ORDER)= * 2, + .end =3D (1UL << (35 - PAGE_SHIFT)) + (1 << MAX_ORDER)= * 3 }, + { .start =3D (1 << MAX_ORDER) * 2, + .end =3D (1 << MAX_ORDER) * 3 }, + }, + .compress =3D true, + }, + /* Two ranges with the same high bit set. */ + { + .ranges =3D { + { .start =3D (1UL << (51 - PAGE_SHIFT)) + (1 << MAX_ORDER)= * 0, + .end =3D (1UL << (51 - PAGE_SHIFT)) + (1 << MAX_ORDER)= * 1 }, + { .start =3D (1UL << (51 - PAGE_SHIFT)) + (1 << MAX_ORDER)= * 3, + .end =3D (1UL << (51 - PAGE_SHIFT)) + (1 << MAX_ORDER)= * 4 }, + }, + .compress =3D true, + }, +#endif + /* AMD Naples Epyc 7281 2 sockets, 8 NUMA nodes. */ + { + .ranges =3D { + { .start =3D 0, .end =3D 0xa0UL }, + { .start =3D 0x100UL, .end =3D 0xb0000UL }, + { .start =3D 0x100000UL, .end =3D 0x430000UL }, + { .start =3D 0x430000UL, .end =3D 0x830000UL }, + { .start =3D 0x830000UL, .end =3D 0xc30000UL }, + { .start =3D 0xc30000UL, .end =3D 0x1030000UL }, + { .start =3D 0x1030000UL, .end =3D 0x1430000UL }, + { .start =3D 0x1430000UL, .end =3D 0x1830000UL }, + { .start =3D 0x1830000UL, .end =3D 0x1c30000UL }, + { .start =3D 0x1c30000UL, .end =3D 0x2030000UL }, + }, + .compress =3D false, + }, + /* 2-node 2GB per-node QEMU layout. */ + { + .ranges =3D { + { .start =3D 0, .end =3D 0x80000UL }, + { .start =3D 0x100000UL, .end =3D 0x180000UL }, + }, + .compress =3D true, + }, + /* Not compressible, smaller than MAX_ORDER. */ + { + .ranges =3D { + { .start =3D 0, .end =3D 1 }, + { .start =3D 0x100UL, .end =3D 0x101UL }, + }, + .compress =3D false, + }, + /* Compressible, requires adjusting size to (1 << MAX_ORDER). */ + { + .ranges =3D { + { .start =3D 0, .end =3D 1 }, + { .start =3D 0x100000UL, .end =3D 0x100001UL }, + }, + .compress =3D true, + }, + /* 2s Intel CLX with contiguous ranges, no compression. */ + { + .ranges =3D { + { .start =3D 0 , .end =3D 0x180000UL }, + { .start =3D 0x180000UL, .end =3D 0x3040000UL }, + }, + .compress =3D false, + }, + }; + int ret_code =3D EXIT_SUCCESS; + + for ( unsigned int i =3D 0 ; i < ARRAY_SIZE(tests); i++ ) + { + unsigned int j; + + pfn_pdx_compression_reset(); + + for ( j =3D 0; j < ARRAY_SIZE(tests[i].ranges); j++ ) + { + unsigned long size =3D tests[i].ranges[j].end - + tests[i].ranges[j].start; + + if ( !tests[i].ranges[j].start && !tests[i].ranges[j].end ) + break; + + pfn_pdx_add_region(tests[i].ranges[j].start << PAGE_SHIFT, + size << PAGE_SHIFT); + } + + if ( pfn_pdx_compression_setup(0) !=3D tests[i].compress ) + { + printf("PFN compression diverge, expected %scompressible\n", + tests[i].compress ? "" : "un"); + print_ranges(tests[i].ranges); + + ret_code =3D EXIT_FAILURE; + continue; + } + + if ( !tests[i].compress ) + continue; + + for ( j =3D 0; j < ARRAY_SIZE(tests[i].ranges); j++ ) + { + unsigned long start =3D tests[i].ranges[j].start; + unsigned long end =3D tests[i].ranges[j].end; + + if ( !start && !end ) + break; + + if ( !pdx_is_region_compressible(start << PAGE_SHIFT, 1) || + !pdx_is_region_compressible((end - 1) << PAGE_SHIFT, 1) ) + { + printf( + "PFN compression invalid, pages %#lx and %#lx should be compressible\n= ", + start, end - 1); + print_ranges(tests[i].ranges); + ret_code =3D EXIT_FAILURE; + } + + if ( start !=3D pdx_to_pfn(pfn_to_pdx(start)) || + end - 1 !=3D pdx_to_pfn(pfn_to_pdx(end - 1)) ) + { + printf("Compression is not bi-directional:\n"); + printf(" PFN %#lx -> PDX %#lx -> PFN %#lx\n", + start, pfn_to_pdx(start), pdx_to_pfn(pfn_to_pdx(sta= rt))); + printf(" PFN %#lx -> PDX %#lx -> PFN %#lx\n", + end - 1, pfn_to_pdx(end - 1), + pdx_to_pfn(pfn_to_pdx(end - 1))); + print_ranges(tests[i].ranges); + ret_code =3D EXIT_FAILURE; + } + } + } + + return ret_code; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/pdx.c b/xen/common/pdx.c index c9ec86729151..cd8a9e75a836 100644 --- a/xen/common/pdx.c +++ b/xen/common/pdx.c @@ -15,6 +15,8 @@ * along with this program; If not, see . */ =20 +/* Trim content when built for the test harness. */ +#ifdef __XEN__ #include #include #include @@ -57,6 +59,8 @@ void set_pdx_range(unsigned long smfn, unsigned long emfn) __set_bit(idx, pdx_group_valid); } =20 +#endif /* __XEN__ */ + #ifndef CONFIG_PDX_NONE =20 #ifdef CONFIG_X86 --=20 2.49.0 From nobody Fri Dec 19 22:07:44 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1754387620; cv=none; d=zohomail.com; s=zohoarc; b=RS6YGC++HfKv1SPxzIulug7XuORnEW7vkrzvbVqwm367uH3GvfmpPwJulzFTWHWPqly+G0Q6aSr5o21F9T65TL6MCwdHHmRBcqHIR9DLQVUmLZSHAlfIgQFrXFw+bFBBYgFMi+Vr1fdKHZm+bhNY9aCUkwMsqbwLYbHoB+wxlHY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1754387620; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=BIUHqA/h/ktsRl4yIry3KtJQ7f0Vu1M/mNLqlvipLX4=; b=fFDeupOK+eEPreoqFG/58IgUa4dKmkFU+rLrM2ejXBsTMkzW9l+gl8nsrpxdZMoxEd+YA6GqmLzjHivQ6xi8PxIRzrZ7xanIMqS3Lh8aDfUpEYoDMoZ+fai57HwWKhHmOe6KTnwmigFmE9SmBZPweiFVBp36LbcrG9C9iexlhN0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1754387620336966.5204925754798; Tue, 5 Aug 2025 02:53:40 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1070229.1433925 (Exim 4.92) (envelope-from ) id 1ujEMD-0003VO-9Q; Tue, 05 Aug 2025 09:53:21 +0000 Received: by outflank-mailman (output) from mailman id 1070229.1433925; Tue, 05 Aug 2025 09:53:21 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEMD-0003Ui-5u; Tue, 05 Aug 2025 09:53:21 +0000 Received: by outflank-mailman (input) for mailman id 1070229; Tue, 05 Aug 2025 09:53:19 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEMB-00026G-PR for xen-devel@lists.xenproject.org; Tue, 05 Aug 2025 09:53:19 +0000 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [2a00:1450:4864:20::336]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 035cd8f9-71e2-11f0-b898-0df219b8e170; Tue, 05 Aug 2025 11:53:18 +0200 (CEST) Received: by mail-wm1-x336.google.com with SMTP id 5b1f17b1804b1-459d4d7c745so22109505e9.1 for ; Tue, 05 Aug 2025 02:53:18 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id 5b1f17b1804b1-458953cfd10sm255425705e9.21.2025.08.05.02.53.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Aug 2025 02:53:16 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 035cd8f9-71e2-11f0-b898-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1754387597; x=1754992397; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=BIUHqA/h/ktsRl4yIry3KtJQ7f0Vu1M/mNLqlvipLX4=; b=YgQDBAuKlAE1S16nQXiUdFHQOZyCw4qhwW0CvaDy1vrADiULBoUWFNsRmxJbvNTd2V AP3VvswndmKS9NyOFNnJ56h0XB6MFRIDZSXzo/0PkoRdbRaSl2XaDX4M/j1xsPx8LuD5 LDFBV+TVbxK7Ff2jGtwnvdcPYRkvDVZR/LSDk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754387597; x=1754992397; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BIUHqA/h/ktsRl4yIry3KtJQ7f0Vu1M/mNLqlvipLX4=; b=Ba7wEKT3nhP9LoxtPwlWvu4qZdVxeoSkPfCJY+smCo4Dp77FpODcYs5vVE42+/WAnU As5k+I8gWx9rZTdTJAeCbCy/Qm+/hPL3ribpMSIEYjuV5nHySvFTzAuItQIUYa+Wao7S uo9boSM+OLr6VSEQfig4MATY/yZBmiqrkhXTOY0Rp0rRsHWNtO6MvtCZhYizlJ6OGgM3 hL6FzVXh/3MamLcq7zD1kgHGwP5c5WEcCauF0H/+hcmRJNEPOe/l/hxKc1LMzGUv+l3X aFT1uTO+RUL6d3hLJyI0w1rjVK0NmLnyEPaPpkr+KI7cIquLlITjOjhN2Rd/5Y71W3ox dLhQ== X-Gm-Message-State: AOJu0YzFAu4s8GtqOlfbvus7zFlPyalYzVzVklHBxN/zVZBH+Wh9R8vf 1cos8UjuLwRtx9D40uLBSpe/VqrPmV8u971SPgf4Yb84ZUhMuztBsPpejid6cQOYkvXwB6y2w29 YiJ53 X-Gm-Gg: ASbGnctHkQeVV1kV/3ZmRCh7bNKqhBw0FNG7Z6uucxnFRAeGmjI4FbaddREQqv3/F2L yOJR6Y/LfvJTEMs3rZ9KI+xn8vtZXqHWG1h9W/VHo8AhH2ZPG43wa/4jQ81cgrXvFENKhM2qAFq ckxqSk+d4S3OB2F9YCpXLitIov6kB9t9VeY0CvPf01fAvgfcA8NclpThdLvyorIODb+Hjk5tV2k sMToyOpxEp3gcy5Mkw4XTY1iysGd8YT+rXeVg9qsmkRkaIZ0s8W+naZ6XCPlO/9uV2tRIXrinSD hYzLnjDvsUstN8mnAOUVfdlwyHEXoVJYnODwNXPiDnGNeipwflpTGLf0442GvxwexaoQ5JIrmBa gRNBW9cINKIwX2GvpiKz5UJhvXkSKiDrsO2P2jcxcMt6CDWjQrH6GQrEk8lq/KW938Q== X-Google-Smtp-Source: AGHT+IE2J0BDPufSmO58HpIuQ3aPUlb0K+Jt1ytMIamwsoqTSYW+X3Pl5Ll9HKwfzZwopPVwdfj53w== X-Received: by 2002:a05:600c:1f13:b0:459:e3f8:9308 with SMTP id 5b1f17b1804b1-459e4387c2fmr5121505e9.11.1754387597275; Tue, 05 Aug 2025 02:53:17 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v4 6/8] pdx: move some helpers in preparation for new compression Date: Tue, 5 Aug 2025 11:52:55 +0200 Message-ID: <20250805095257.74975-7-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250805095257.74975-1-roger.pau@citrix.com> References: <20250805095257.74975-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1754387621356116600 Move fill_mask(), pdx_region_mask() and pdx_init_mask() to the !CONFIG_PDX_NONE section in preparation of them also being used by a newly added PDX compression. No functional change intended. Signed-off-by: Roger Pau Monn=C3=A9 Acked-by: Jan Beulich --- git is not very helpful when generating the diff here, and it ends up moving everything around the functions instead of the functions themselves. --- xen/common/pdx.c | 118 +++++++++++++++++++++++------------------------ 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/xen/common/pdx.c b/xen/common/pdx.c index cd8a9e75a836..9e6b36086fbd 100644 --- a/xen/common/pdx.c +++ b/xen/common/pdx.c @@ -101,59 +101,6 @@ void __init pfn_pdx_add_region(paddr_t base, paddr_t s= ize) ranges[nr_ranges++].pages =3D PFN_UP(base + size) - PFN_DOWN(base); } =20 -#endif /* !CONFIG_PDX_NONE */ - -#ifdef CONFIG_PDX_MASK_COMPRESSION - -/* - * Diagram to make sense of the following variables. The masks and shifts - * are done on mfn values in order to convert to/from pdx: - * - * pfn_hole_mask - * pfn_pdx_hole_shift (mask bitsize) - * | - * |---------| - * | | - * V V - * -------------------------- - * |HHHHHHH|000000000|LLLLLL| <--- mfn - * -------------------------- - * ^ ^ ^ ^ - * | | |------| - * | | | - * | | pfn_pdx_bottom_mask - * | | - * |-------| - * | - * pfn_top_mask - * - * ma_{top,va_bottom}_mask is simply a shifted pfn_{top,pdx_bottom}_mask, - * where ma_top_mask has zeroes shifted in while ma_va_bottom_mask has - * ones. - */ - -/** Mask for the lower non-compressible bits of an mfn */ -unsigned long __ro_after_init pfn_pdx_bottom_mask =3D ~0UL; - -/** Mask for the lower non-compressible bits of an maddr or vaddr */ -unsigned long __ro_after_init ma_va_bottom_mask =3D ~0UL; - -/** Mask for the higher non-compressible bits of an mfn */ -unsigned long __ro_after_init pfn_top_mask =3D 0; - -/** Mask for the higher non-compressible bits of an maddr or vaddr */ -unsigned long __ro_after_init ma_top_mask =3D 0; - -/** - * Mask for a pdx compression bit slice. - * - * Invariant: valid(mfn) implies (mfn & pfn_hole_mask) =3D=3D 0 - */ -unsigned long __ro_after_init pfn_hole_mask =3D 0; - -/** Number of bits of the "compressible" bit slice of an mfn */ -unsigned int __ro_after_init pfn_pdx_hole_shift =3D 0; - /* Sets all bits from the most-significant 1-bit down to the LSB */ static uint64_t fill_mask(uint64_t mask) { @@ -196,12 +143,6 @@ static uint64_t pdx_region_mask(uint64_t base, uint64_= t len) return fill_mask(base ^ (base + len - 1)); } =20 -bool pdx_is_region_compressible(paddr_t base, unsigned long npages) -{ - return !(paddr_to_pfn(base) & pfn_hole_mask) && - !(pdx_region_mask(base, npages * PAGE_SIZE) & ~ma_va_bottom_mas= k); -} - /** * Creates the mask to start from when calculating non-compressible bits * @@ -219,6 +160,65 @@ static uint64_t __init pdx_init_mask(uint64_t base_add= r) (uint64_t)1 << (MAX_ORDER + PAGE_SHIFT)) - 1); } =20 +#endif /* !CONFIG_PDX_NONE */ + +#ifdef CONFIG_PDX_MASK_COMPRESSION + +/* + * Diagram to make sense of the following variables. The masks and shifts + * are done on mfn values in order to convert to/from pdx: + * + * pfn_hole_mask + * pfn_pdx_hole_shift (mask bitsize) + * | + * |---------| + * | | + * V V + * -------------------------- + * |HHHHHHH|000000000|LLLLLL| <--- mfn + * -------------------------- + * ^ ^ ^ ^ + * | | |------| + * | | | + * | | pfn_pdx_bottom_mask + * | | + * |-------| + * | + * pfn_top_mask + * + * ma_{top,va_bottom}_mask is simply a shifted pfn_{top,pdx_bottom}_mask, + * where ma_top_mask has zeroes shifted in while ma_va_bottom_mask has + * ones. + */ + +/** Mask for the lower non-compressible bits of an mfn */ +unsigned long __ro_after_init pfn_pdx_bottom_mask =3D ~0UL; + +/** Mask for the lower non-compressible bits of an maddr or vaddr */ +unsigned long __ro_after_init ma_va_bottom_mask =3D ~0UL; + +/** Mask for the higher non-compressible bits of an mfn */ +unsigned long __ro_after_init pfn_top_mask =3D 0; + +/** Mask for the higher non-compressible bits of an maddr or vaddr */ +unsigned long __ro_after_init ma_top_mask =3D 0; + +/** + * Mask for a pdx compression bit slice. + * + * Invariant: valid(mfn) implies (mfn & pfn_hole_mask) =3D=3D 0 + */ +unsigned long __ro_after_init pfn_hole_mask =3D 0; + +/** Number of bits of the "compressible" bit slice of an mfn */ +unsigned int __ro_after_init pfn_pdx_hole_shift =3D 0; + +bool pdx_is_region_compressible(paddr_t base, unsigned long npages) +{ + return !(paddr_to_pfn(base) & pfn_hole_mask) && + !(pdx_region_mask(base, npages * PAGE_SIZE) & ~ma_va_bottom_mas= k); +} + bool __init pfn_pdx_compression_setup(paddr_t base) { unsigned int i, j, bottom_shift =3D 0, hole_shift =3D 0; --=20 2.49.0 From nobody Fri Dec 19 22:07:44 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1754387621; cv=none; d=zohomail.com; s=zohoarc; b=nZGStkYZu7BU+cMdJWnLJrvBuD3hzaQ2UxciiSa8tyJyYwX0yP1cXidxqK9Xuw5uPOyFwSOpsqlBgcZXJLqkpDgM6x7oTVWwvCqZjK3ajPA2Qxhasw2VohIn+SpUT6HrXwUT9wPS9qIDEQF5w0VaDQ16gnwdlJR9Bq2qhsn9aqo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1754387621; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=dkHB+363YxhGHGsW0WbfTknTo2Qh5BFaLJhNwQ63/RY=; b=OrAlGhtLY16pV7FibP/XuW7sSCEWOtOIlPPQSB/wnlFAP41scnISBmtZkVnNAGxaC/7G74dNf11HRB2Yw4hHIQonMyR0dWh/EmpCN94A1U/gdR3WaWxAKDpAcwzoVd6dApbM36v1z0ZN1E7N8rsIFQZ+vwMu4XQ3qDeztYvlCNM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1754387620823706.0661337971916; Tue, 5 Aug 2025 02:53:40 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1070232.1433936 (Exim 4.92) (envelope-from ) id 1ujEMF-0003rF-Ia; Tue, 05 Aug 2025 09:53:23 +0000 Received: by outflank-mailman (output) from mailman id 1070232.1433936; Tue, 05 Aug 2025 09:53:23 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEMF-0003qd-E4; Tue, 05 Aug 2025 09:53:23 +0000 Received: by outflank-mailman (input) for mailman id 1070232; Tue, 05 Aug 2025 09:53:21 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEMD-00026G-Gp for xen-devel@lists.xenproject.org; Tue, 05 Aug 2025 09:53:21 +0000 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [2a00:1450:4864:20::435]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 0434faa8-71e2-11f0-b898-0df219b8e170; Tue, 05 Aug 2025 11:53:19 +0200 (CEST) Received: by mail-wr1-x435.google.com with SMTP id ffacd0b85a97d-3b7825e2775so4558658f8f.2 for ; Tue, 05 Aug 2025 02:53:19 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id ffacd0b85a97d-3b79c3c4d02sm18194279f8f.33.2025.08.05.02.53.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Aug 2025 02:53:18 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 0434faa8-71e2-11f0-b898-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1754387599; x=1754992399; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=dkHB+363YxhGHGsW0WbfTknTo2Qh5BFaLJhNwQ63/RY=; b=e2GS6ptta+XjgaIwe0WSAhoZfF4F33zaRzFnROFi2PGW6DwqJXHDn9LTvqYR8PYlj4 Jg+6gl8sg6kHaMpjrF4Fs+pGOV9HivGy20k4t7ig+LlJ0gJ1loiFKDiduhVBmMnfGlnu N6h6qrGQSR9kbKSa2UGQqlscifSuxWrEUcbPE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754387599; x=1754992399; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dkHB+363YxhGHGsW0WbfTknTo2Qh5BFaLJhNwQ63/RY=; b=k9QNHk9nhkIrGdrWja2myzeBtJ+ob0QFUNHwvTgjYs5Ux1kD2FFFDG9a6PCL1vZmYX UTnR+2+/CxZEohPKSe9cpNQxrzE6zeZ5napyiafkJknNoPdFSITF7G76wu4oY7vYK0Rc g/q6t1StZW/Cixvs9fKjB01ZpfcRrdVqKnM1xjajWwdq5H8Xf0RVPb6mzZ7y4BCvRvvq rUtExtKBfnYvcrTeCVy3X0+YGAQKAgtiQxUpmLVeJLLPcm1uhSPkGibCPAUtsjvI4l0b 53lIfflluLktFLE9DrToCapIALDtMqpgYitfp3YWqLs2RKUvs+M7KvKljJ4AF8Q3nZrC PIUA== X-Gm-Message-State: AOJu0Yy3sxYmfIYilSuHUQgOERvjN25PKTygW4EnI2i1THNhYOUXNBts G9b4G5OSUWWlWA6Q/76IAN4WJpCDGWYDgP41EN51qGsiRyFW3Ra5+iM/ADISd9cwfWEpm9iY+AM h30pA X-Gm-Gg: ASbGncvmnxlUvVWK0dKfIKQTk7V5NR/bnxYtSQctgZZs9yRHmpVWbZ67hNdXLvsLdCB LCfT+bZ6CAFZxk5U/b3GidGMk4/7SQmam7oUa4qMb4KLM6UD5Y7Z7au0cOVok7QHSmm0CfaZad5 CtIT1KwT9ADE193i/gyPVPTAj7HYl3cv6iB4nU6eFDAA76L2gFoEXyqgvnRXq/qBHExQTfTacAo lod4vDBSufxV6KvhXEwFiY4escPnUj7WEGvtwdhGeE/K+W53uVb4ENyXzCBbDPz+/v7jm2FGANR Rcm3Vn4nwVHOgCctoiZPbCwzbIRtlYdGEeKwsIze0HT0g3pL5TsM96oSvQhEmRq6ek7PqFfNPBb c5CuyV3OB4b+mNQnxkWU0/V0Ng0TkdBblOT39yP/OdhJ0o8gT1D5SXevnwMvi4vNJUw== X-Google-Smtp-Source: AGHT+IErhUju3M5UYg5smm6FdBrFeXFJHpWvobhJlu/JUk/uNlqrhtdZJmPqgM3IR95GIBDLPmU7Lg== X-Received: by 2002:a05:6000:2007:b0:3b7:8b64:3107 with SMTP id ffacd0b85a97d-3b8d948647fmr9664503f8f.26.1754387598519; Tue, 05 Aug 2025 02:53:18 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Oleksii Kurochko , Community Manager , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v4 7/8] pdx: introduce a new compression algorithm based on region offsets Date: Tue, 5 Aug 2025 11:52:56 +0200 Message-ID: <20250805095257.74975-8-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250805095257.74975-1-roger.pau@citrix.com> References: <20250805095257.74975-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1754387621941124100 With the appearance of Intel Sierra Forest and Granite Rapids it's now possible to get a production x86 host with the following memory map: SRAT: Node 0 PXM 0 [0000000000000000, 000000007fffffff] SRAT: Node 0 PXM 0 [0000000100000000, 000000807fffffff] SRAT: Node 1 PXM 1 [0000063e80000000, 000006be7fffffff] SRAT: Node 2 PXM 2 [00000c7e80000000, 00000cfe7fffffff] SRAT: Node 3 PXM 3 [000012be80000000, 0000133e7fffffff] This is from a four socket Granite Rapids system, with each node having 512GB of memory. The total amount of RAM on the system is 2TB, but without enabling CONFIG_BIGMEM the last range is not accessible, as it's above the 16TB boundary covered by the frame table. Sierra Forest and Granite Rapids are socket compatible, however Sierra Forest only supports 2 socket configurations, while Granite Rapids can go up to 8 sockets. Note that while the memory map is very sparse, it couldn't be compressed using the current PDX_MASK compression algorithm, which relies on all ranges having a shared zeroed region of bits that can be removed. The memory map presented above has the property of all regions being similarly spaced between each other, and all having also a similar size. Use a lookup table to store the offsets to translate from/to PFN and PDX spaces. Such table is indexed based on the input PFN or PDX to translated. The example PFN layout about would get compressed using the following: PFN compression using PFN lookup table shift 29 and PDX region size 0x10000= 000 range 0 [0000000000000, 0x0000807ffff] PFN IDX 0 : 0000000000000 range 1 [0x00063e80000, 0x0006be7ffff] PFN IDX 3 : 0x00053e80000 range 2 [0x000c7e80000, 0x000cfe7ffff] PFN IDX 6 : 0x000a7e80000 range 3 [0x0012be80000, 0x00133e7ffff] PFN IDX 9 : 0x000fbe80000 Note how the tow ranges belonging to node 0 get merged into a single PDX region by the compression algorithm. The default size of lookup tables currently set in Kconfig is 64 entries, and the example memory map consumes 10 entries. Such memory map is from a 4 socket Granite Rapids host, which in theory supports up to 8 sockets according to Intel documentation. Assuming the layout of a 8 socket system is similar to the 4 socket one, it would require 21 lookup table entries to support it, way below the current default of 64 entries. The valid range of lookup table size is currently restricted from 1 to 512 elements in Kconfig. An extra array is used to keep track of the base PFN for each translated range. Non used slots are set to ~0UL, so that in mfn_valid() the mfn < base check always fails, thus reporting the mfn as invalid. Introduce __init_or_pdx_mask and use it on some shared functions between PDX mask and offset compression, as otherwise some code becomes unreachable after boot if PDX offset compression is used. Mark the code as __init in that case, so it's pruned after boot. Signed-off-by: Roger Pau Monn=C3=A9 --- Changes since v3: - Rename __init_or_pdx_mask. - Reorder logic in pfn_offset_sanitize_ranges() to reduce code. - Print a message if the table index is truncated from what would be required to represent all input ranges independently. - Cast size to paddr_t for pdx_init_mask() call. Changes since v2: - s/PDX_OFFSET_TLB_ORDER/PDX_OFFSET_TBL_ORDER/. - Fix changelog mention of Sapphire Rapids. - Misc fixes in the test harness. - Use SWAP() macro. - Introduce an extra table to keep the bases of the valid ranges. Changes since v1: - Use a lookup table with the offsets. - Split the adding of the test to a pre-patch. - Amend diagram to also show possible padding after compression. --- CHANGELOG.md | 3 + tools/tests/pdx/.gitignore | 1 + tools/tests/pdx/Makefile | 3 +- tools/tests/pdx/harness.h | 14 ++ tools/tests/pdx/test-pdx.c | 4 + xen/common/Kconfig | 21 ++- xen/common/pdx.c | 258 ++++++++++++++++++++++++++++++++++++- xen/include/xen/pdx.h | 87 ++++++++++++- 8 files changed, 385 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f31ca08fe3f..f9ef893f4851 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ The format is based on [Keep a Changelog](https://keepach= angelog.com/en/1.0.0/) grant table or foreign memory. =20 ### Added + - Introduce new PDX compression algorithm to cope with Intel Sierra Fores= t and + Granite Rapids having sparse memory maps. + - On x86: - Option to attempt to fixup p2m page-faults on PVH dom0. - Resizable BARs is supported for PVH dom0. diff --git a/tools/tests/pdx/.gitignore b/tools/tests/pdx/.gitignore index a32c7db4de79..1202a531a7fd 100644 --- a/tools/tests/pdx/.gitignore +++ b/tools/tests/pdx/.gitignore @@ -1,2 +1,3 @@ /pdx.h /test-pdx-mask +/test-pdx-offset diff --git a/tools/tests/pdx/Makefile b/tools/tests/pdx/Makefile index b3734afde686..10b354f0cefd 100644 --- a/tools/tests/pdx/Makefile +++ b/tools/tests/pdx/Makefile @@ -1,7 +1,7 @@ XEN_ROOT=3D$(CURDIR)/../../.. include $(XEN_ROOT)/tools/Rules.mk =20 -TARGETS :=3D test-pdx-mask +TARGETS :=3D test-pdx-mask test-pdx-offset =20 .PHONY: all all: $(TARGETS) @@ -42,6 +42,7 @@ CFLAGS +=3D $(APPEND_CFLAGS) CFLAGS +=3D $(CFLAGS_xeninclude) =20 test-pdx-mask: CFLAGS +=3D -DCONFIG_PDX_MASK_COMPRESSION +test-pdx-offset: CFLAGS +=3D -DCONFIG_PDX_OFFSET_COMPRESSION =20 test-pdx-%: test-pdx.c pdx.h $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_$*.o) -o $@ $< $(APPEND_CFLAGS) diff --git a/tools/tests/pdx/harness.h b/tools/tests/pdx/harness.h index 5bef7df650d2..7c1c5a246868 100644 --- a/tools/tests/pdx/harness.h +++ b/tools/tests/pdx/harness.h @@ -44,8 +44,10 @@ =20 #define MAX_RANGES 16 #define MAX_PFN_RANGES MAX_RANGES +#define CONFIG_PDX_OFFSET_TBL_ORDER 6 =20 #define ASSERT assert +#define ASSERT_UNREACHABLE() assert(0) =20 #define CONFIG_DEBUG =20 @@ -66,10 +68,22 @@ static inline unsigned int find_next( #define find_next_zero_bit(a, s, o) find_next(a, s, o, false) #define find_next_bit(a, s, o) find_next(a, s, o, true) =20 +#define flsl(x) ((x) ? BITS_PER_LONG - __builtin_clzl(x) : 0) +#define ffsl(x) __builtin_ffsl(x) + #define boolean_param(name, func) =20 typedef uint64_t paddr_t; =20 +#define SWAP(a, b) \ + do { typeof(a) t_ =3D (a); (a) =3D (b); (b) =3D t_; } while ( 0 ) + +#define sort(elem, nr, size, cmp, swp) ({ \ + /* Consume swp() so compiler doesn't complain it's unused. */ \ + (void)swp; \ + qsort(elem, nr, size, cmp); \ +}) + #include "pdx.h" =20 #endif diff --git a/tools/tests/pdx/test-pdx.c b/tools/tests/pdx/test-pdx.c index 0798ccee359b..eefd54c76815 100644 --- a/tools/tests/pdx/test-pdx.c +++ b/tools/tests/pdx/test-pdx.c @@ -51,7 +51,11 @@ int main(int argc, char **argv) { .start =3D 0xc7e80000UL, .end =3D 0xcfe80000UL }, { .start =3D 0x12be80000UL, .end =3D 0x133e80000UL }, }, +#ifdef CONFIG_PDX_OFFSET_COMPRESSION + .compress =3D true, +#else .compress =3D false, +#endif }, /* Simple hole. */ { diff --git a/xen/common/Kconfig b/xen/common/Kconfig index 8dad0c923a9d..76f9ce705f7a 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -59,7 +59,8 @@ config EVTCHN_FIFO =20 choice prompt "PDX (Page inDeX) compression" - default PDX_MASK_COMPRESSION if !X86 && !RISCV + default PDX_OFFSET_COMPRESSION if X86 + default PDX_MASK_COMPRESSION if !RISCV default PDX_NONE help PDX compression is a technique designed to reduce the memory @@ -78,12 +79,30 @@ config PDX_MASK_COMPRESSION help Compression relying on all RAM addresses sharing a zeroed bit region. =20 +config PDX_OFFSET_COMPRESSION + bool "Offset compression" + help + Compression relying on size and distance between RAM regions being + compressible using an offset lookup table. + config PDX_NONE bool "None" help No compression endchoice =20 +config PDX_OFFSET_TBL_ORDER + int "PDX offset compression lookup table order" if EXPERT + depends on PDX_OFFSET_COMPRESSION + default 6 + range 0 9 + help + Order of the PFN to PDX and PDX to PFN translation lookup tables. + Number of table entries is calculated as 2^N. + + Size of the tables can be adjusted from 1 entry (order 0) to 512 + entries (order 9). + config ALTERNATIVE_CALL bool =20 diff --git a/xen/common/pdx.c b/xen/common/pdx.c index 9e6b36086fbd..d29582234bfd 100644 --- a/xen/common/pdx.c +++ b/xen/common/pdx.c @@ -24,6 +24,7 @@ #include #include #include +#include =20 /** * Maximum (non-inclusive) usable pdx. Must be @@ -40,6 +41,12 @@ bool __mfn_valid(unsigned long mfn) =20 #ifdef CONFIG_PDX_MASK_COMPRESSION invalid |=3D mfn & pfn_hole_mask; +#elif defined(CONFIG_PDX_OFFSET_COMPRESSION) +{ + unsigned long base =3D pfn_bases[PFN_TBL_IDX(mfn)]; + + invalid |=3D mfn < base || mfn >=3D base + pdx_region_size; +} #endif =20 if ( unlikely(evaluate_nospec(invalid)) ) @@ -75,6 +82,13 @@ void set_pdx_range(unsigned long smfn, unsigned long emf= n) # error "Missing architecture maximum number of RAM ranges" #endif =20 +/* Some functions should be init when not using PDX mask compression. */ +#ifndef CONFIG_PDX_MASK_COMPRESSION +# define __init_or_mask_compr __init +#else +# define __init_or_mask_compr +#endif + /* Generic PFN compression helpers. */ static struct pfn_range { unsigned long base_pfn, pages; @@ -102,7 +116,7 @@ void __init pfn_pdx_add_region(paddr_t base, paddr_t si= ze) } =20 /* Sets all bits from the most-significant 1-bit down to the LSB */ -static uint64_t fill_mask(uint64_t mask) +static uint64_t __init_or_mask_compr fill_mask(uint64_t mask) { while (mask & (mask + 1)) mask |=3D mask + 1; @@ -128,7 +142,7 @@ static uint64_t fill_mask(uint64_t mask) * @param len Size in octets of the region * @return Mask of moving bits at the bottom of all the region addresses */ -static uint64_t pdx_region_mask(uint64_t base, uint64_t len) +static uint64_t __init_or_mask_compr pdx_region_mask(uint64_t base, uint64= _t len) { /* * We say a bit "moves" in a range if there exist 2 addresses in that @@ -294,7 +308,245 @@ void __init pfn_pdx_compression_reset(void) nr_ranges =3D 0; } =20 -#endif /* CONFIG_PDX_COMPRESSION */ +#elif defined(CONFIG_PDX_OFFSET_COMPRESSION) /* CONFIG_PDX_MASK_COMPRESSIO= N */ + +unsigned int __ro_after_init pfn_index_shift; +unsigned int __ro_after_init pdx_index_shift; + +unsigned long __ro_after_init pfn_pdx_lookup[CONFIG_PDX_NR_LOOKUP]; +unsigned long __ro_after_init pdx_pfn_lookup[CONFIG_PDX_NR_LOOKUP]; +unsigned long __ro_after_init pfn_bases[CONFIG_PDX_NR_LOOKUP]; +unsigned long __ro_after_init pdx_region_size =3D ~0UL; + +bool pdx_is_region_compressible(paddr_t base, unsigned long npages) +{ + unsigned long pfn =3D PFN_DOWN(base); + unsigned long pfn_base =3D pfn_bases[PFN_TBL_IDX(pfn)]; + + return pfn >=3D pfn_base && + pfn + npages <=3D pfn_base + pdx_region_size; +} + +static int __init cf_check cmp_node(const void *a, const void *b) +{ + const struct pfn_range *l =3D a; + const struct pfn_range *r =3D b; + + if ( l->base_pfn > r->base_pfn ) + return 1; + if ( l->base_pfn < r->base_pfn ) + return -1; + + return 0; +} + +static void __init cf_check swp_node(void *a, void *b) +{ + SWAP(a, b); +} + +static bool __init pfn_offset_sanitize_ranges(void) +{ + unsigned int i =3D 0; + + if ( PFN_TBL_IDX(ranges[0].base_pfn) !=3D + PFN_TBL_IDX(ranges[0].base_pfn + ranges[0].pages - 1) ) + { + ASSERT_UNREACHABLE(); + return false; + } + + while ( i + 1 < nr_ranges ) + { + /* + * Ensure ranges [start, end] use the same offset table index. Sh= ould + * be guaranteed by the logic that calculates the pfn shift. + */ + if ( PFN_TBL_IDX(ranges[i + 1].base_pfn) !=3D + PFN_TBL_IDX(ranges[i + 1].base_pfn + ranges[i + 1].pages - 1)= ) + { + ASSERT_UNREACHABLE(); + return false; + } + + if ( PFN_TBL_IDX(ranges[i].base_pfn) !=3D + PFN_TBL_IDX(ranges[i + 1].base_pfn) ) + { + i++; + continue; + } + + /* Merge ranges with the same table index. */ + ranges[i].pages =3D ranges[i + 1].base_pfn + ranges[i + 1].pages - + ranges[i].base_pfn; + memmove(&ranges[i + 1], &ranges[i + 2], + (nr_ranges - (i + 2)) * sizeof(ranges[0])); + nr_ranges--; + } + + return true; +} + +bool __init pfn_pdx_compression_setup(paddr_t base) +{ + unsigned long mask =3D PFN_DOWN(pdx_init_mask(base)), idx_mask =3D 0; + unsigned long pages =3D 0; + unsigned int i; + + if ( !nr_ranges ) + { + printk(XENLOG_DEBUG "PFN compression disabled%s\n", + pdx_compress ? ": no ranges provided" : ""); + return false; + } + + if ( nr_ranges > ARRAY_SIZE(ranges) ) + { + printk(XENLOG_WARNING + "Too many PFN ranges (%u > %zu), not attempting PFN compres= sion\n", + nr_ranges, ARRAY_SIZE(ranges)); + return false; + } + + /* Sort ranges by start address. */ + sort(ranges, nr_ranges, sizeof(*ranges), cmp_node, swp_node); + + for ( i =3D 0; i < nr_ranges; i++ ) + { + unsigned long start =3D ranges[i].base_pfn; + + /* + * Align range base to MAX_ORDER. This is required so the PDX off= set + * for the bits below MAX_ORDER matches the MFN offset, and pages + * greater than the minimal order can be used to populate the + * directmap. + */ + ranges[i].base_pfn =3D start & ~((1UL << MAX_ORDER) - 1); + ranges[i].pages =3D start + ranges[i].pages - ranges[i].base_pfn; + + /* + * Only merge overlapped regions now, leave adjacent regions separ= ated. + * They would be merged later if both use the same index into the + * lookup table. + */ + if ( !i || + ranges[i].base_pfn >=3D + (ranges[i - 1].base_pfn + ranges[i - 1].pages) ) + { + mask |=3D pdx_region_mask(ranges[i].base_pfn, ranges[i].pages); + continue; + } + + ranges[i - 1].pages =3D ranges[i].base_pfn + ranges[i].pages - + ranges[i - 1].base_pfn; + + if ( i + 1 < nr_ranges ) + memmove(&ranges[i], &ranges[i + 1], + (nr_ranges - (i + 1)) * sizeof(ranges[0])); + else /* last range */ + mask |=3D pdx_region_mask(ranges[i].base_pfn, ranges[i].pages); + nr_ranges--; + i--; + } + + /* + * Populate a mask with the non-equal bits of the different ranges, do= this + * to calculate the maximum PFN shift to use as the lookup table index. + */ + for ( i =3D 0; i < nr_ranges; i++ ) + for ( unsigned int j =3D 0; j < nr_ranges; j++ ) + idx_mask |=3D (ranges[i].base_pfn & ~mask) ^ + (ranges[j].base_pfn & ~mask); + + if ( !idx_mask ) + /* Single region case. */ + pfn_index_shift =3D flsl(mask); + else if ( flsl(idx_mask) - ffsl(idx_mask) < CONFIG_PDX_OFFSET_TBL_ORDE= R ) + /* The changed mask fits in the table index width. */ + pfn_index_shift =3D ffsl(idx_mask) - 1; + else + { + /* Changed mask is wider than array size, use most significant bit= s. */ + pfn_index_shift =3D flsl(idx_mask) - CONFIG_PDX_OFFSET_TBL_ORDER; + printk(XENLOG_DEBUG + "PFN compression table index truncated, requires order %u\n= ", + flsl(idx_mask) - ffsl(idx_mask) + 1); + } + + /* + * Ensure correctness of the calculated values, plus merge ranges if t= hey + * use the same lookup table index. + */ + if ( !pfn_offset_sanitize_ranges() ) + { + printk(XENLOG_DEBUG "PFN compression is invalid, disabling\n"); + pfn_pdx_compression_reset(); + return false; + } + + /* + * Find the maximum PFN range size after having merged ranges with same + * index. The rounded up region size will be the base for the PDX reg= ion + * size and shift. + */ + for ( i =3D 0; i < nr_ranges; i++ ) + pages =3D max(pages, ranges[i].pages); + + /* pdx_init_mask() already takes MAX_ORDER into account. */ + mask =3D PFN_DOWN(pdx_init_mask((paddr_t)pages << PAGE_SHIFT)); + pdx_index_shift =3D flsl(mask); + + /* Avoid compression if there's no gain. */ + if ( (mask + 1) * (nr_ranges - 1) >=3D ranges[nr_ranges - 1].base_pfn ) + { + printk(XENLOG_DEBUG + "PFN compression yields no space gain, disabling\n"); + pfn_pdx_compression_reset(); + return false; + } + + /* + * Set all entries in the bases table to ~0 to force both mfn_valid() = and + * pdx_is_region_compressible() to return false for non-handled pfns. + */ + memset(pfn_bases, ~0, sizeof(pfn_bases)); + + pdx_region_size =3D mask + 1; + + printk(XENLOG_INFO + "PFN compression using lookup table shift %u and region size %#= lx\n", + pfn_index_shift, pdx_region_size); + + for ( i =3D 0; i < nr_ranges; i++ ) + { + unsigned int idx =3D PFN_TBL_IDX(ranges[i].base_pfn); + + pfn_pdx_lookup[idx] =3D ranges[i].base_pfn - (mask + 1) * i; + pdx_pfn_lookup[i] =3D pfn_pdx_lookup[idx]; + pfn_bases[idx] =3D ranges[i].base_pfn; + + printk(XENLOG_DEBUG + " range %3u [%013lx, %013lx] PFN IDX %3u : %013lx\n", + i, ranges[i].base_pfn, ranges[i].base_pfn + ranges[i].pages= - 1, + idx, pfn_pdx_lookup[idx]); + } + + return true; +} + +void __init pfn_pdx_compression_reset(void) +{ + memset(pfn_pdx_lookup, 0, sizeof(pfn_pdx_lookup)); + memset(pdx_pfn_lookup, 0, sizeof(pfn_pdx_lookup)); + memset(pfn_bases, 0, sizeof(pfn_bases)); + pfn_index_shift =3D 0; + pdx_index_shift =3D 0; + pdx_region_size =3D ~0UL; + + nr_ranges =3D 0; +} + +#endif /* CONFIG_PDX_OFFSET_COMPRESSION */ =20 /* * Local variables: diff --git a/xen/include/xen/pdx.h b/xen/include/xen/pdx.h index 425d45e9f08e..a5693b956b25 100644 --- a/xen/include/xen/pdx.h +++ b/xen/include/xen/pdx.h @@ -65,6 +65,46 @@ * This scheme also holds for multiple regions, where HHHHHHH acts as * the region identifier and LLLLLL fully contains the span of every * region involved. + * + * ##=C2=A0PDX offset compression + * + * Alternative compression mechanism that relies on RAM ranges having a si= milar + * size and offset between them: + * + * PFN address space: + * =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=AC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=AC=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=AC=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=90= =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=AC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=90 + * =E2=94=82 RAM 0 =E2=94=82 =E2=94=82 RAM 1 =E2=94=82 = =E2=94=82...=E2=94=82 RAM N =E2=94=82 =E2=94=82 + * =E2=94=9C=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=B4=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=98= =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=B4=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=98 + * =E2=94=82<------>=E2=94=82 =E2=94=82 + * =E2=94=82 size =E2=94=82 + * =E2=94=82<----------------->=E2=94=82 + * offset + * + * The compression reduces the holes between RAM regions: + * + * PDX address space: + * =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=AC=E2=94=80=E2=94=80=E2=94=80=E2=94=AC=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=AC=E2=94=80=E2= =94=80=E2=94=80=E2=94=90 =E2=94=8C=E2=94=80=E2=94=AC=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=90 + * =E2=94=82 RAM 0 =E2=94=82 =E2=94=82 RAM 1 =E2=94=82 =E2=94=82...= =E2=94=82 =E2=94=82 RAM N =E2=94=82 + * =E2=94=9C=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=B4=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=B4=E2=94=80=E2= =94=80=E2=94=80=E2=94=98 =E2=94=94=E2=94=80=E2=94=B4=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=98 + * =E2=94=82<---------->=E2=94=82 + * pdx region size + * + * The offsets to convert from PFN to PDX and from PDX to PFN are stored i= n a + * pair of lookup tables, and the index into those tables to find the offs= et + * for each PFN or PDX is obtained by shifting the to be translated addres= s by + * a specific value calculated at boot: + * + * pdx =3D pfn - pfn_lookup_table[pfn >> pfn_shift] + * pfn =3D pdx + pdx_lookup_table[pdx >> pdx_shift] + * + * Note the indexes into the lookup tables are masked to avoid out of boun= ds + * accesses. + * + * This compression requires the PFN ranges to contain a non-equal most + * significant part that's smaller than the lookup table size, so that a v= alid + * shift value can be found to differentiate between PFN regions. The set= up + * algorithm might merge otherwise separate PFN ranges to use the same loo= kup + * table entry. */ =20 extern unsigned long max_pdx; @@ -157,7 +197,52 @@ static inline paddr_t directmapoff_to_maddr_xlate(unsi= gned long offset) (offset & ma_va_bottom_mask)); } =20 -#endif /* CONFIG_PDX_MASK_COMPRESSION */ +#elif defined(CONFIG_PDX_OFFSET_COMPRESSION) /* CONFIG_PDX_MASK_COMPRESSIO= N */ + +#include + +#define CONFIG_PDX_NR_LOOKUP (1UL << CONFIG_PDX_OFFSET_TBL_ORDER) +#define PDX_TBL_MASK (CONFIG_PDX_NR_LOOKUP - 1) + +#define PFN_TBL_IDX(pfn) \ + (((pfn) >> pfn_index_shift) & PDX_TBL_MASK) +#define PDX_TBL_IDX(pdx) \ + (((pdx) >> pdx_index_shift) & PDX_TBL_MASK) +#define MADDR_TBL_IDX(ma) \ + (((ma) >> (pfn_index_shift + PAGE_SHIFT)) & PDX_TBL_MASK) +#define DMAPOFF_TBL_IDX(off) \ + (((off) >> (pdx_index_shift + PAGE_SHIFT)) & PDX_TBL_MASK) + +extern unsigned int pfn_index_shift; +extern unsigned int pdx_index_shift; + +extern unsigned long pfn_pdx_lookup[]; +extern unsigned long pdx_pfn_lookup[]; +extern unsigned long pfn_bases[]; +extern unsigned long pdx_region_size; + +static inline unsigned long pfn_to_pdx_xlate(unsigned long pfn) +{ + return pfn - pfn_pdx_lookup[PFN_TBL_IDX(pfn)]; +} + +static inline unsigned long pdx_to_pfn_xlate(unsigned long pdx) +{ + return pdx + pdx_pfn_lookup[PDX_TBL_IDX(pdx)]; +} + +static inline unsigned long maddr_to_directmapoff_xlate(paddr_t ma) +{ + return ma - ((paddr_t)pfn_pdx_lookup[MADDR_TBL_IDX(ma)] << PAGE_SHIFT); +} + +static inline paddr_t directmapoff_to_maddr_xlate(unsigned long offset) +{ + return offset + ((paddr_t)pdx_pfn_lookup[DMAPOFF_TBL_IDX(offset)] << + PAGE_SHIFT); +} + +#endif /* CONFIG_PDX_OFFSET_COMPRESSION */ =20 #ifdef CONFIG_PDX_NONE =20 --=20 2.49.0 From nobody Fri Dec 19 22:07:44 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1754387626; cv=none; d=zohomail.com; s=zohoarc; b=Vg33fh7mYGn0KDJnRHXxIAJgdAyawVkbMYj3cbTOVrLUsG3Vi6lWoSSiJg2J0jjIf0sDKKNUv7WFo+grx9LsopdS/P7QhzZkXTRNrbTPP6Wehxa7LbiVtFqZJKdio2EE2k+sw3JsfwxORuazC4Um1hjBFWNVyef9pZFNPtbL09s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1754387626; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=lLIn3FF6zwDcWQpb5QcmoMzmzTKK4Qs20CfUmv+TlvU=; b=HnU1OUAmtpbbXPoAJTLlsTmkW0jzjFmebfj1mEvwzS48UI4Mju4SqG2P9jmsFxbzsLmgisazHQrsD7G7nTRNgpa1sixhUNliaCMZTO5c9MGomE2SFmMTZcwpCJPsOKiZSDdEZUdMK/PKysv8kXfzqmdrDG80wQEkAOosCCk4w7Q= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1754387626616730.0307174809024; Tue, 5 Aug 2025 02:53:46 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1070233.1433942 (Exim 4.92) (envelope-from ) id 1ujEMG-0003vq-4t; Tue, 05 Aug 2025 09:53:24 +0000 Received: by outflank-mailman (output) from mailman id 1070233.1433942; Tue, 05 Aug 2025 09:53:24 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEMF-0003vb-RK; Tue, 05 Aug 2025 09:53:23 +0000 Received: by outflank-mailman (input) for mailman id 1070233; Tue, 05 Aug 2025 09:53:21 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ujEMD-0001yh-RQ for xen-devel@lists.xenproject.org; Tue, 05 Aug 2025 09:53:21 +0000 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [2a00:1450:4864:20::42d]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 04c6e06f-71e2-11f0-a321-13f23c93f187; Tue, 05 Aug 2025 11:53:20 +0200 (CEST) Received: by mail-wr1-x42d.google.com with SMTP id ffacd0b85a97d-3b79bddd604so3581404f8f.0 for ; Tue, 05 Aug 2025 02:53:20 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id 5b1f17b1804b1-458b73868a4sm128606745e9.11.2025.08.05.02.53.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Aug 2025 02:53:19 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 04c6e06f-71e2-11f0-a321-13f23c93f187 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1754387600; x=1754992400; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=lLIn3FF6zwDcWQpb5QcmoMzmzTKK4Qs20CfUmv+TlvU=; b=pryDO7v4wpFvoa4dmDMvxdpOKkRxHpN7dF6Okli9zEBoyuEdbvVNgrGmx3UqXUa/Kd yRBJppAOglSfAL1iPUmjcDB0c4RWIPfDY+Gn4yoUjFIGlnbDqfdR8rPM7R/WFMOQBVCn UTCSQAkvxVI608jbJ3MRArKTS4HGkFBgrF774= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754387600; x=1754992400; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=lLIn3FF6zwDcWQpb5QcmoMzmzTKK4Qs20CfUmv+TlvU=; b=emBCJ0WJbH/KaxcUKZ9q1mLdaCE8jKSGFnIWRDPSHM617T9sHCs40d2jcxwO2O/R1v xAy1t1EC3bCWu0tRrdVcuIn9yC+1WYEuGXeG5PlhWjn3kKGG54HpyQi0pL+ssM9dLV46 NUTnbdJr62iO1IAWT0nELhoUs865thF2DW8HKyYXfvgsWem9pGBo9gFFtRusFMhkLxhz fJlOGU9sBPca+uoTtF5vd8Ljr0BSGzhhwWktKtZWW8rwFvv9nxmzLRoD+NVBUqP+mbZW 2veCoF7hnwR7RNO62i/wIJ8hrDstQDV7j7wQi2Tbfam5oEFRaG2B1O5dNiqB8lfwyJC6 s1qw== X-Gm-Message-State: AOJu0YwFEkOdL6QiAW6AnVVOrXC0CmtFOhud2dITX1a58/SZ3DeuUeJl k1NV673DKCk2nfTf/oAwjicvDa1XlX5shU5wdPuZePr//66TZv1/07uBeYCK+falle3N4+BpKyr febNQ X-Gm-Gg: ASbGncvCMp52xD6gXqOYFWeFJkEORdbC5ZtzntVtstJHmhFgeNpg2GaYuJQyylj3IGB ZE0OW0nqAz4P7fSn0R8LeZ4/iWX1P7m3FH103Jb90WJ7ihe43LdU/ZN9SobNiWxkyPiwPm9wmHT b74b1LkT/UC80/NVbZSMdsyWioO48jikk0YCMSP3vXx+IClj5uTpoVAF7yItkPbiggTVrGA2vso zGLsO1RHhixjWaWcSASusmu+VkcliN2dGZIsSv2voWHMMTZe9ZOIsaHzpBowTascrCyos3gu5B9 HaxzaD6aKv/TTgQFeelLM4Gq0O3urIqER8DFMBQHHkp8n/yiW5vVswACRo5lM1y+PB7PIofYhIU uy8aMZXNQ/d2/M4GcmMcioVlg2RK4SkMZrAJ9sLekxBZStfzma2sOVJP63IiVD41lTzIkNIzf1s Bc X-Google-Smtp-Source: AGHT+IF1tlMb6KZwDcyrJwRY0DLZ3X9YMOMVZzsA08b0rnKgAvFdrqoP72cSYcW9kqUAOHbX8Xfvpg== X-Received: by 2002:a5d:5d0e:0:b0:3b7:9564:29be with SMTP id ffacd0b85a97d-3b8d94c1febmr8669986f8f.49.1754387599726; Tue, 05 Aug 2025 02:53:19 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Jan Beulich , Andrew Cooper Subject: [PATCH v4 8/8] x86/mm: adjust loop in arch_init_memory() to iterate over the PDX space Date: Tue, 5 Aug 2025 11:52:57 +0200 Message-ID: <20250805095257.74975-9-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250805095257.74975-1-roger.pau@citrix.com> References: <20250805095257.74975-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1754387627898124100 There's a loop in arch_init_memory() that iterates over holes and non-RAM regions to possibly mark any page_info structures matching those addresses as IO. The looping there is done over the PFN space. PFNs not covered by the PDX space will always fail the mfn_valid() check, hence re-write the loop to iterate over the PDX space and avoid checking any holes that are not covered by the PDX translation. On a system with a ~6TiB hole this change together with using PDX compression reduces boot time in approximately 20 seconds. Xen boot time without the change is ~50s, with the change it's ~30s. Signed-off-by: Roger Pau Monn=C3=A9 --- Changes since v3: - Ensure parameter to pfn_to_pdx() is always RAM. Changes since v2: - New in this version. --- xen/arch/x86/mm.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index e7fd56c7ce90..e27dc28cfdd6 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -275,7 +275,7 @@ static void __init assign_io_page(struct page_info *pag= e) =20 void __init arch_init_memory(void) { - unsigned long i, pfn, rstart_pfn, rend_pfn, iostart_pfn, ioend_pfn; + unsigned long i, pfn, rstart_pfn, rend_pfn, iostart_pfn, ioend_pfn, pd= x; =20 /* * Basic guest-accessible flags: @@ -328,9 +328,20 @@ void __init arch_init_memory(void) destroy_xen_mappings((unsigned long)mfn_to_virt(iostart_pfn), (unsigned long)mfn_to_virt(ioend_pfn)); =20 - /* Mark as I/O up to next RAM region. */ - for ( ; pfn < rstart_pfn; pfn++ ) + /* + * Mark as I/O up to next RAM region. Iterate over the PDX space = to + * skip holes which would always fail the mfn_valid() check. + * + * pfn_to_pdx() requires a valid (iow: RAM) PFN to convert to PDX, + * hence provide pfn - 1, which is the tailing PFN from the last R= AM + * range, or pdx 0 if the input pfn is 0. + */ + for ( pdx =3D pfn ? pfn_to_pdx(pfn - 1) + 1 : 0; + pdx < pfn_to_pdx(rstart_pfn); + pdx++ ) { + pfn =3D pdx_to_pfn(pdx); + if ( !mfn_valid(_mfn(pfn)) ) continue; =20 --=20 2.49.0