From nobody Thu Oct 30 18:58:36 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=1753355129; cv=none; d=zohomail.com; s=zohoarc; b=KYj8KKOW6U3kPx01dkQ/sISqOHp4tJkHNllvsESfc4B9107twd1WOHuIRaM05ABrJuEZphzDrSgFd+p52MKVShJUr2qhThxZRTj8l/maj/Yl8+eBtal6fUFwIw+X+NROMKNbttpGK2pgESsLt+/6wWHuKHs3mDAwohNbd4Ufpr0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753355129; 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=V/EBMqhJY7veNR7PVvbDHJJ7joaIXfPChdq3V8Id6DY=; b=IUtXvEyiReae5jxs8HJ0DN1ETbtzt/6OAMayOymWimJoZI4l10o3n+dG9WZisvqu1dzXN3okxNr/80CNC+3JJU3VZ0onjiqQPx5IYDz4Z4C3sYoISxDxPuvpkmTYRRtkBKmWH4yStfel86MbEupQVs9XtPmTMPB6TCXfVaM+RPY= 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 17533551297961012.7236491437982; Thu, 24 Jul 2025 04:05:29 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1055720.1424038 (Exim 4.92) (envelope-from ) id 1uetl2-00019J-4j; Thu, 24 Jul 2025 11:05:04 +0000 Received: by outflank-mailman (output) from mailman id 1055720.1424038; Thu, 24 Jul 2025 11:05:04 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uetl2-00019C-1s; Thu, 24 Jul 2025 11:05:04 +0000 Received: by outflank-mailman (input) for mailman id 1055720; Thu, 24 Jul 2025 11:05:02 +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 1uetl0-00011w-FF for xen-devel@lists.xenproject.org; Thu, 24 Jul 2025 11:05:02 +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 0abc0def-687e-11f0-b895-0df219b8e170; Thu, 24 Jul 2025 13:05:00 +0200 (CEST) Received: by mail-wr1-x430.google.com with SMTP id ffacd0b85a97d-3a53359dea5so430641f8f.0 for ; Thu, 24 Jul 2025 04:05:00 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id 5b1f17b1804b1-45870564ddbsm16044165e9.22.2025.07.24.04.04.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Jul 2025 04:04:59 -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: 0abc0def-687e-11f0-b895-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1753355099; x=1753959899; 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=V/EBMqhJY7veNR7PVvbDHJJ7joaIXfPChdq3V8Id6DY=; b=Iox8qVnKFDA0qKJmibt0bagWYXkQRADLTbAKducYOfVl2vwMwGp69q3qXVlM8Pltez YuYwB11pHWpEjuQ+4FdjUGoVdGczjZb6zngh4IzkajcklA6jxzELvOq2luLeYed4/B6I SYpF30nJyOCCQ0rYfvFvmCVo1ZWnl/NYbeu+g= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753355099; x=1753959899; 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=V/EBMqhJY7veNR7PVvbDHJJ7joaIXfPChdq3V8Id6DY=; b=RXkbANuJ37wa54WjaZ1vxbN6KQVQRh9NRytFhxWUtp0MIgAsN2nSMmBGWTRF6KWyhG BzkEj4Lr/gYhvIa1h97RK0yoqwePNtoU9tg7WpWJrnBCWazibEYzNPlGfveu5z4akx7a CGTk2RRUuVee6BvRgIR93yEI0ulaiC1vDTllvZdGyGrZzmBrGclfvdhj9naH8OCDp8Nt QzjIEj4R19bzxHIZUiz5m5hOoh5itoI6aDGKL1Kj0KICw1Gjy8ZYI9a+opHYie8cZ2cX YzITqZd1v3PhWbuJ7Udz1h/3086P4UOviTwmghLO7HPLQ7W8YofFI3qv7pFOeWNkwzsL 3kEA== X-Gm-Message-State: AOJu0YxkCiccTBnPB999CxdaC2nC9tkTtu6ZPou4ZtOfJaVkJnCbXmM6 wKPNxW9MFin+YBU11oeDcAsLcMhx8D1cAdEkXJRpdVUh0FjmPZBLeM+t5fiLk475YGgi8Lzg/Ru L51Kg X-Gm-Gg: ASbGnct6xA9GPX5eF/vGxEggwpVRMtyIAsZkTYDT0fQ5UMK2WA/+DGfeVQKVPuAVeEa 6H+N2mzBCPkG+kzHFk88GXKr5McNB5rgwNKDKQ5uFVCm1sD0R/3qrHul/i7+xVKLO0iPP5JcDxu xmru5UmFPxp6zYtqiK/bx4BN8TuCYVTbWIiBNnCX/znMBSpci1YKT4VLMi94MrteFL6VEdqk5xx g0ARPzhnhcJZfDY5iYyGuFHCHVc0bAHv53S5Wr81x8sY9EjktOJSgR9Z2KOz9UHXIeCtjSh7o0w QDtl9CuXzLUiOCQ5y9rXlKmBF+fAVf0ROS/jxgvppWTVUF95siI9qGMvAMLIfSFzCFR9h4bQdI6 Ha3RCdgvb9FNv2Fc+pH62C88ChsAzsBMXaffgA/ogAlo/aA/JH6U17R6MFtSlThKEUA== X-Google-Smtp-Source: AGHT+IF3TwN8DTRJPEGrs04ybn7wBmslHBOne2TFC+XJ9jP2vO62pfR/1U4oROPXkA/boeQwWuI6Rw== X-Received: by 2002:a05:6000:2c03:b0:3a4:f975:30f7 with SMTP id ffacd0b85a97d-3b768f12e09mr5423663f8f.56.1753355099371; Thu, 24 Jul 2025 04:04:59 -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 v3 1/8] kconfig: turn PDX compression into a choice Date: Thu, 24 Jul 2025 13:04:09 +0200 Message-ID: <20250724110416.2081-2-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250724110416.2081-1-roger.pau@citrix.com> References: <20250724110416.2081-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: 1753355131242116600 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 --- 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 27bd3f5a6ea3..ab30250bbf25 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 2539a635f111..0014f9b3d6d7 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 Thu Oct 30 18:58:36 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=1753355131; cv=none; d=zohomail.com; s=zohoarc; b=OS7wgVrBjJrbVZlthP30pr5885kbXfmLf6RIgm96BDJzdJTniORrdM2bs3xyNwJ/12jfifHKomcXJC/pKCDxJevS4j6bsLQEJERW/pTw0DJfrkI65YjAFiYP9DK8sOQWLejwCN9Q3ZOGzUm4Lnc1sr+KuoThFAeoiPI0ZcC4vnQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753355131; 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=whhsae1AmBQN2v043OXCC7Dq4hslcGg9RhiS1VfloUw=; b=barR041Rc4WA83i/29QYrxdWuw9XOwqZR8RAAAxeyXb1P83bJW0TKobLT8h2/O3Qc8QmKjOifVP4yjKozyf03dv+RvNljUNvucP72N8DiZdutP4fHCs4hu6Zy2oL/Xo8bxsms8LTu/ZjDpuVb4XzcBSRPDTSZuP16EPvcbCekbw= 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 1753355131523222.51020881123554; Thu, 24 Jul 2025 04:05:31 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1055721.1424046 (Exim 4.92) (envelope-from ) id 1uetl2-0001Ch-Gj; Thu, 24 Jul 2025 11:05:04 +0000 Received: by outflank-mailman (output) from mailman id 1055721.1424046; Thu, 24 Jul 2025 11:05:04 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uetl2-0001CN-9c; Thu, 24 Jul 2025 11:05:04 +0000 Received: by outflank-mailman (input) for mailman id 1055721; Thu, 24 Jul 2025 11:05:02 +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 1uetl0-0000v1-MM for xen-devel@lists.xenproject.org; Thu, 24 Jul 2025 11:05:02 +0000 Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com [2a00:1450:4864:20::32d]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 0bd3e34e-687e-11f0-a31e-13f23c93f187; Thu, 24 Jul 2025 13:05:02 +0200 (CEST) Received: by mail-wm1-x32d.google.com with SMTP id 5b1f17b1804b1-4555f89b236so7715855e9.1 for ; Thu, 24 Jul 2025 04:05:02 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id 5b1f17b1804b1-458705c4fcfsm15908175e9.29.2025.07.24.04.04.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Jul 2025 04:05:00 -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: 0bd3e34e-687e-11f0-a31e-13f23c93f187 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1753355101; x=1753959901; 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=whhsae1AmBQN2v043OXCC7Dq4hslcGg9RhiS1VfloUw=; b=VBULYGI9qDI8/yzzOU+spoX+DRK6hO5AxKHGZDWgsmcXRGCZKT1FyLs2TcF8v6w5sq VIYo5cNHZ+trgnNN7f6ToorBQ5dK5jcNtkK1ZSSMX3fNQhsC0cPDkqY2UuuUXUkRoirJ ZagurQeONGCQoLLSCut1855wFTGD+B5LsmqqY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753355101; x=1753959901; 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=whhsae1AmBQN2v043OXCC7Dq4hslcGg9RhiS1VfloUw=; b=Xl4QtRl5M36aqvGU13GxZSQJAMooMf8y0Qohq+zqY5RayrGTORkiGAtJd5mVykyyDL yJnSFA5rJtCPPWaOdbbPRLAq8OQlBq15bf1Z7leKUIW5ClgUwI7+Gfc9CP252uoZtAni iSaq/m/6heUuPf/fm7LE1s5Ds8MXWQes/7sUvtCy9bSCaJZnPX0xstYX3EL6RnPdpLK4 i8yZuHECnxcD7Xcu++d/NiTw5ZqAfeZXn/Rg7z4SIvl+bsvLeb6aOCsaSfP3aNG/QZ1g h/kiOtTKvTXHrrUtkitflPzpmRt7+z878ny6T9h3UUat/Cm7I6zPzppoERx5+lNAFLG3 UWiQ== X-Gm-Message-State: AOJu0YwPKEWpx+Lf/4CFy4TCvLUJy5AoYR3wCFkjQdFepMo1t92xhVG0 acm5N0a4hYFs6Z7zx+DOVjrC7mhr8qrGCz/lB0JIEEBe+0qhyhLBztNnxuOlOKHPVthO+Y8URZp MoWJG X-Gm-Gg: ASbGnctL9kwIzism8kBjhI9bjQouSxN2ejRc2OF4l+iMPrSMrvuok2f0ScOrJ6FPUSK x5oL3NEmHtN/71HCIF3xuOf3Y7O6WnFxqHVCMHyIeTFtY5djvVX4S+zvVScPL3WEx73Ap+bpttJ r1BbpQRvIe86Zb5NYygtTQTdZYpF0m4SQC1y3BC6LbZZ+LZJXnAoVonKE37+vCycXSqmAY94+6C j6bXZpkkKt/b3eZdzU9wggZBwM2VTCWgAv8hfTPJZWANmY5Tlc3FfFDOpRvTuQHGkJh4BopQTh+ am1Zsn3KUzTcGzZwWDCwuxmgZbOp67DrUdYj/YMRmNbpaq54HQELsLDTP10A4MdcNP8cI+2kv+u /whjvysWTaQl3Vbsd1HWhedre5R4ewHK3Hb0ud6eyE9bkwgiQjp9Mj7wrTedwaIq7PA== X-Google-Smtp-Source: AGHT+IGH19xNr4cpQbi9V6PkxjB10U4SkkaCsRQML6HY0XTgD16Qb1Ko6jq0244Dx6wpxz3yPtudoA== X-Received: by 2002:a05:600c:6295:b0:456:1bae:5478 with SMTP id 5b1f17b1804b1-45868c75008mr64880405e9.2.1753355100977; Thu, 24 Jul 2025 04:05:00 -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 v3 2/8] pdx: provide a unified set of unit functions Date: Thu, 24 Jul 2025 13:04:10 +0200 Message-ID: <20250724110416.2081-3-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250724110416.2081-1-roger.pau@citrix.com> References: <20250724110416.2081-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: 1753355133332116600 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 --- 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 ab30250bbf25..1d7cf2492fd6 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..49c9dbf9e5fa 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, size; +} 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 =3D PFN_DOWN(base); + ranges[nr_ranges++].size =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 | + pdx_region_mask(ranges[i].base, ranges[i].size); =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 Thu Oct 30 18:58:36 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=1753355125; cv=none; d=zohomail.com; s=zohoarc; b=QAoYsFE7UiXBdPahR+X+UzdxXOZzwn1mONfRswS3n9PTTGzI6+Ejkadg2DgVolJ9UPPYbCsrS0UOXkhfnuGXAPq7xnYiSjMHfLhzkeGB/ZcBUsqOQWEZLFzX/4yvGnvBN79tpE2Qd5pGyCfbWhbBjSHsqzAEV8w0fc5UYTfPjO8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753355125; 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=3zceg71Pnqj3ImLkxP+2Mg3UE0d3Wnna2dUrKt8QAy0=; b=hWqh4nNnvrFq4/cUqsWZQoQ/tDLDCK6NT858ykSaRmBIsUL09037Z9CtmH9W3v2+1o5n2ra2Gf0w6x0OJuT0zqm3co4cxQtDh/8mm/iihX0v1y0VPUmk7hsAgTQKZp1FHqpC7QM0iJxSzmAAIsL2/rP0R8oz3OTBKFvOy/0haYk= 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 175335512582128.303530497052634; Thu, 24 Jul 2025 04:05:25 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1055722.1424058 (Exim 4.92) (envelope-from ) id 1uetl4-0001bt-JF; Thu, 24 Jul 2025 11:05:06 +0000 Received: by outflank-mailman (output) from mailman id 1055722.1424058; Thu, 24 Jul 2025 11:05:06 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uetl4-0001bm-Gf; Thu, 24 Jul 2025 11:05:06 +0000 Received: by outflank-mailman (input) for mailman id 1055722; Thu, 24 Jul 2025 11:05:05 +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 1uetl3-00011w-8j for xen-devel@lists.xenproject.org; Thu, 24 Jul 2025 11:05:05 +0000 Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [2a00:1450:4864:20::329]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 0cb20f43-687e-11f0-b895-0df219b8e170; Thu, 24 Jul 2025 13:05:03 +0200 (CEST) Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-4561ca74829so9237065e9.0 for ; Thu, 24 Jul 2025 04:05:03 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id 5b1f17b1804b1-4587054c37csm16762615e9.8.2025.07.24.04.05.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Jul 2025 04:05:01 -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: 0cb20f43-687e-11f0-b895-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1753355102; x=1753959902; 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=3zceg71Pnqj3ImLkxP+2Mg3UE0d3Wnna2dUrKt8QAy0=; b=soZ3jotS715QRAUjePJSpGp+3811W2Eb904IYAIxU+nknj4nRf3oiwPZuAQiS5Vb0p pqFoYsuepfEKB4wy24MO7SCX8tT9zHXQaaZPUPN6FlCFm0wssRPRnuDwKXHyqXq5w9Yw HzmSgYjC77gWWgCGNuRU8fO2rufsq6OlvmzXU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753355102; x=1753959902; 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=3zceg71Pnqj3ImLkxP+2Mg3UE0d3Wnna2dUrKt8QAy0=; b=AMiQee0fSKvqmd4E/RB6QBS1T/9pZnELwDaiZwKl3zNOiAJjuCdUPfcFwX4cwKVJxd HZyGQIfiQxEz4/Z6ypD1gPc2rZB9qGn8DOXvOlNjyp+rwCM173922vYMVFGsDCmmPyAa boO/ZdUawIr1pjn75tWuNw6KeIGZzjz9DXWqXS69CKIKpDeLB7EV/ZSOJ++I6cjFRbbc sg8ITVAK3nKZWvRZZq0OYU0LTyK5GANJOgPjfIbuGpvkoEznkx+wXeRHg9AcdcDwKsKx uDNl98q9D+XFDGKoRu/QASr92m5JxoVcLrOwi2U6wQbRA/DeKS3/L6eGAeEve+ckkVHO Zsrw== X-Gm-Message-State: AOJu0YwgUMGFqqYaW8SqZTEdGXiLlM+yOYNLFjILj9eCPR3R14EqlSc0 jqJg8HnlNq16vxju0ALBMAL2WSun4KBpj/rDpw0CzjJhv93Evv2xxZQrW1EVVQJ1+O10UkzP/Xv c6hJU X-Gm-Gg: ASbGnctdjpxTyNFOGFKOElgFJlAhdLZjBT+KwrliKHkzHrDHAYT+DzjTxrlKmDVMYTF PKL3lVvIxNi1iIJdykmDlKovQDhm7Iud8HKDLtEd0dhvKbzAhyQpI8cNypx13M5GXtkmyw+X4W5 1l0DUyBL7bJfR6h5d8efVVYNMIPf0HCHzLXqrut68tUZlD6JgnYQNaZjaXs04NrBVugoeCC/iYG brcXCPqK0gJzD2hxpht55L+nqK0Ql4SweFKRcXz4cVL3+7DD02jsfoAoWrzsGhrXbQnAMX8d5TP Gf50g9X/XnV0jYLiJotxvoiW3+Z2/zMFMIIpsr2heHEcWxkh/HLiToiXUtq4GPrPKphDYHPo87M kQjFqB8eWiZe/Wo0IBl8nT8XTl/z+5SJPHrzl5ItRCu8BDpW411TEefAhqiEMdcnicg== X-Google-Smtp-Source: AGHT+IHH6U0ylScaSpGCzT78sQEfFST9V4KLsm2VWM2leCHNtZ7t5h1+5hZK2OCWUYLruC4XPlYy6A== X-Received: by 2002:a05:600c:638f:b0:456:1611:cea5 with SMTP id 5b1f17b1804b1-45868d46f15mr64914895e9.18.1753355102429; Thu, 24 Jul 2025 04:05:02 -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 v3 3/8] pdx: introduce command line compression toggle Date: Thu, 24 Jul 2025 13:04:11 +0200 Message-ID: <20250724110416.2081-4-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250724110416.2081-1-roger.pau@citrix.com> References: <20250724110416.2081-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: 1753355127105116600 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 49c9dbf9e5fa..ad7871ad90be 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 Thu Oct 30 18:58:36 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=1753355126; cv=none; d=zohomail.com; s=zohoarc; b=TDFJ7hDYBvzxLQ4h+iTVwlAtacRvI4H3ZmyblphVEuNJ4n2LBkjXDquuxkxuLf5N96Cwd7n77dDDxqRDYuzaRpyWvEmmF59o8BCFSMR+pnyHr51Z810H6r5NR3CHmK9VEyYLy6l1B3GcdtsQXN+o14UXBzMRORUhUBHm1pe80iY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753355126; 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=JPvk01+jvD+QkqQzSEPQ24j6gzkrPWZQXCb8655/PtA=; b=XFZvc4iYLXIiPcgy6flvLzIIUxb5alj8dusPaDR1IHFkNWlTX9B9NUZOnT4O7ER4n3b9I/Pp58hN6Pki4MGvJ40inBlRwpgoGAU4aAh1hhXqeEFopcTYjZWiQDDeRPvUeAR/HbyhIq5/NmJU6LE6WNflSRWRrov789vL/hOgUts= 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 1753355126592204.0044119633029; Thu, 24 Jul 2025 04:05:26 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1055724.1424075 (Exim 4.92) (envelope-from ) id 1uetl7-0001x1-Fo; Thu, 24 Jul 2025 11:05:09 +0000 Received: by outflank-mailman (output) from mailman id 1055724.1424075; Thu, 24 Jul 2025 11:05:09 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uetl7-0001we-7A; Thu, 24 Jul 2025 11:05:09 +0000 Received: by outflank-mailman (input) for mailman id 1055724; Thu, 24 Jul 2025 11:05:07 +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 1uetl5-00011w-9L for xen-devel@lists.xenproject.org; Thu, 24 Jul 2025 11:05:07 +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 0dcc6da7-687e-11f0-b895-0df219b8e170; Thu, 24 Jul 2025 13:05:05 +0200 (CEST) Received: by mail-wr1-x430.google.com with SMTP id ffacd0b85a97d-3a6d1369d4eso497431f8f.2 for ; Thu, 24 Jul 2025 04:05:05 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id ffacd0b85a97d-3b76fc6d2b6sm1843244f8f.22.2025.07.24.04.05.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Jul 2025 04:05:03 -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: 0dcc6da7-687e-11f0-b895-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1753355104; x=1753959904; 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=JPvk01+jvD+QkqQzSEPQ24j6gzkrPWZQXCb8655/PtA=; b=oySBWd3RT6/GEpuvb0ZWX1hcLMEfq+TITMXtz/KoIEcsjwcGMW9p41lGUBH/iV87gb 7DW75HE3aQFm5gOl3/NUBnCFRXFE1eRx7fcTk+y31c/8XrKcA/kJdttyT+z9EIsOY1gb Y5k4PSO6l0D+K4a5kH/MUZ+kcYpt76GtY9dLI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753355104; x=1753959904; 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=JPvk01+jvD+QkqQzSEPQ24j6gzkrPWZQXCb8655/PtA=; b=L/9BhvdeCIWgcBZ0myrPhDL648c1pLDC2S8Dav5SqpxP6z4FjCUDMKNzYwBnSBkqbt k9JpQyZHhS61t8qHMI9NDZsNDtmUgG05pqZQ2PV0ce8JBWm6vJIYBQxj++mL2IAN1JC9 Qt6BTGJwO6yKIReSbcR8RKksdecmxgmj8z29f6lOUF5R1gs/YMAMWvYtF+RsyEO4TyfM zPAhRYBqbrHujQo6SQWJCXVW2alspU3sFon5X+hfiScLY5HMGuPQq5SOrNy+FHtGcLru sG07LXHYrTTrksnHybkLoNZi/QkvjlP75V7XlOjILBLIvOxzmx6eMtSjxvOFrSOs0HFW rgtg== X-Gm-Message-State: AOJu0YywJLlZYKx5dbxqas0jBtEpAVK0wK9H0h2fK6hXb5qflSejMkbk tRoaG66CssLite4xElkH0XBwVj7yk1MvsQ2MtP5dm5JTD019Vy01izJ7f3iokkpYNXBZvgEKP+T YpAQS X-Gm-Gg: ASbGncs1d5QkSgn0fxyag4UgDkbD32bBO8E+JVZYgZLJ6rxHN/Au6BaZIyxJCRDBpOS u6poxH+FlVd+S8f5PrMq2/3X2S7EcWWUdwkAqF//gX18ksShFvsThakk2vY+Z+lJ8fOPp+h4Jxr /x43zLnZPyNTSFKLSVmxFGJKdvDktRrHGBmvn9oNXzT2PVLislWk7HkPzXm/CRIqaao30DMAA3g UGpDrkQvSZDwLbPQJyXxZIrCl5KHG+nfYb/Xjjq5PA3+QuI2uzhI08Kth4Odtru9VlT2BDxh7R8 EU91WvlQDIckS0g5lWUCtvcy5AZ4qvWY2aAnR1uymUKK/VGV320DQUa3hv6jchX6YFItAyfSfHl f7Wd6YpNACPxBqiHEdIMiK7C/hEVMt1dSYxryE/jAbl500x1Jpn7AfmoMV1UteaF9SA== X-Google-Smtp-Source: AGHT+IFxHvuiHvyQ2qSnocuSuJlAPPKbPiqDm0DzpLwM/iUkhFPLpVJfM0jH0cC+ZDfeyCfdYMWWeQ== X-Received: by 2002:a05:6000:2512:b0:3b3:9c75:acc6 with SMTP id ffacd0b85a97d-3b768f165ecmr5023969f8f.59.1753355104249; Thu, 24 Jul 2025 04:05:04 -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 , Shawn Anastasio , Alistair Francis , Bob Eshleman , Connor Davis , Oleksii Kurochko Subject: [PATCH v3 4/8] pdx: allow per-arch optimization of PDX conversion helpers Date: Thu, 24 Jul 2025 13:04:12 +0200 Message-ID: <20250724110416.2081-5-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250724110416.2081-1-roger.pau@citrix.com> References: <20250724110416.2081-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: 1753355127441116600 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 a generic header that maps 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 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/arm/include/asm/Makefile | 1 + xen/arch/ppc/include/asm/Makefile | 1 + xen/arch/riscv/include/asm/Makefile | 1 + xen/arch/x86/include/asm/cpufeatures.h | 1 + xen/arch/x86/include/asm/pdx.h | 75 ++++++++++++++++++++++++++ xen/arch/x86/srat.c | 6 ++- xen/common/pdx.c | 10 ++-- xen/include/asm-generic/pdx.h | 24 +++++++++ xen/include/xen/pdx.h | 22 +++++--- 9 files changed, 130 insertions(+), 11 deletions(-) create mode 100644 xen/arch/x86/include/asm/pdx.h create mode 100644 xen/include/asm-generic/pdx.h diff --git a/xen/arch/arm/include/asm/Makefile b/xen/arch/arm/include/asm/M= akefile index 4565baca6a4d..cec13c889dab 100644 --- a/xen/arch/arm/include/asm/Makefile +++ b/xen/arch/arm/include/asm/Makefile @@ -5,6 +5,7 @@ generic-y +=3D hardirq.h generic-y +=3D iocap.h generic-y +=3D irq-dt.h generic-y +=3D paging.h +generic-y +=3D pdx.h generic-y +=3D percpu.h generic-y +=3D random.h generic-y +=3D softirq.h diff --git a/xen/arch/ppc/include/asm/Makefile b/xen/arch/ppc/include/asm/M= akefile index c989a7f89b34..0ad45133baac 100644 --- a/xen/arch/ppc/include/asm/Makefile +++ b/xen/arch/ppc/include/asm/Makefile @@ -6,6 +6,7 @@ generic-y +=3D hardirq.h generic-y +=3D hypercall.h generic-y +=3D iocap.h generic-y +=3D paging.h +generic-y +=3D pdx.h generic-y +=3D percpu.h generic-y +=3D perfc_defn.h generic-y +=3D random.h diff --git a/xen/arch/riscv/include/asm/Makefile b/xen/arch/riscv/include/a= sm/Makefile index bfdf186c682f..de04daf68df3 100644 --- a/xen/arch/riscv/include/asm/Makefile +++ b/xen/arch/riscv/include/asm/Makefile @@ -7,6 +7,7 @@ generic-y +=3D hypercall.h generic-y +=3D iocap.h generic-y +=3D irq-dt.h generic-y +=3D paging.h +generic-y +=3D pdx.h generic-y +=3D percpu.h generic-y +=3D perfc_defn.h generic-y +=3D random.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..00666e49831a --- /dev/null +++ b/xen/arch/x86/include/asm/pdx.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef X86_PDX_H +#define X86_PDX_H + +#ifndef CONFIG_PDX_NONE + +#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 /* !CONFIG_PDX_NONE */ + +#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 ad7871ad90be..f4ee2198841d 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/asm-generic/pdx.h b/xen/include/asm-generic/pdx.h new file mode 100644 index 000000000000..4dea2b97c3e5 --- /dev/null +++ b/xen/include/asm-generic/pdx.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef GENERIC_PDX_H +#define GENERIC_PDX_H + +#ifndef CONFIG_PDX_NONE + +#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 /* !CONFIG_PDX_NONE */ + +#endif /* GENERIC_PDX_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/xen/pdx.h b/xen/include/xen/pdx.h index 10153da98bf1..91fc32370f21 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)); @@ -159,6 +159,14 @@ static inline paddr_t directmapoff_to_maddr(unsigned l= ong offset) =20 #endif /* CONFIG_PDX_MASK_COMPRESSION */ =20 +/* + * Allow each architecture to define it's (possibly optimized) versions of= the + * translation functions. + * + * Do not use _xlate suffixed functions, always use the non _xlate variant= s. + */ +#include + #ifdef CONFIG_PDX_NONE =20 /* Without PDX compression we can skip some computations */ @@ -181,8 +189,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) @@ -215,8 +224,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 Thu Oct 30 18:58:36 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=1753355129; cv=none; d=zohomail.com; s=zohoarc; b=m+IkNIJdtKrzsJ5aW5sRjynAF2j0u6ZBb8jsvGxB1CQfmgOiBJxjPJfPY1AajzJQHIJrEym0+bVb8Wam29tV7/lwefzzHlvFlRtT9i85aKCwbehJ30B+2pES2XQaJnb/DeCrR90B3d741RFd0WXVKP3pFCGyRyEUPXst9CqAe8c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753355129; 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=VfMGn8u0wtzpSEZPvLvEyIwXmFi4IRmv1Yr6i8nv/Po=; b=QiYzmyZwEpzooYxuykxct71jFM5NUqqL7xeWISbEnR48aTqK3p6EXhg2UczpJVu5E1kQr6xy67cWE02+AHfw/+nBsbGYlZLT+WrUO2NVvN+pxnOmYTTK8Yh5QxrPaMs/+ghgLVulbtShgYnZY7gj8R/0xPIzB2KEiP83g83escs= 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 1753355129564894.3067402517494; Thu, 24 Jul 2025 04:05:29 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1055723.1424068 (Exim 4.92) (envelope-from ) id 1uetl7-0001tF-0v; Thu, 24 Jul 2025 11:05:09 +0000 Received: by outflank-mailman (output) from mailman id 1055723.1424068; Thu, 24 Jul 2025 11:05:08 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uetl6-0001ss-Ti; Thu, 24 Jul 2025 11:05:08 +0000 Received: by outflank-mailman (input) for mailman id 1055723; Thu, 24 Jul 2025 11:05:07 +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 1uetl5-0000v1-8c for xen-devel@lists.xenproject.org; Thu, 24 Jul 2025 11:05:07 +0000 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [2a00:1450:4864:20::336]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 0e8b7023-687e-11f0-a31e-13f23c93f187; Thu, 24 Jul 2025 13:05:06 +0200 (CEST) Received: by mail-wm1-x336.google.com with SMTP id 5b1f17b1804b1-4563bc166a5so5387315e9.1 for ; Thu, 24 Jul 2025 04:05:06 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id ffacd0b85a97d-3b76fcb8aa6sm1846237f8f.67.2025.07.24.04.05.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Jul 2025 04:05:05 -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: 0e8b7023-687e-11f0-a31e-13f23c93f187 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1753355106; x=1753959906; 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=VfMGn8u0wtzpSEZPvLvEyIwXmFi4IRmv1Yr6i8nv/Po=; b=OabB9AGNkOCCkCSZ1+/ib7AW5gqZp3Jo06AZhls/GuWpElEro1GhLg/XUsnYiXHi8M mEsnvcKre2B32RA5yp6PUAqCD8hrYFtJ/Hg6vBa/HjJheR0vupgvMiR5W8IyhVIQqyuj 463UPTXXRzK3Ok44/ucUfAfT5XnRmZJDpP1Lw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753355106; x=1753959906; 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=VfMGn8u0wtzpSEZPvLvEyIwXmFi4IRmv1Yr6i8nv/Po=; b=cYXC2aamYimAcYTDhBB5pK1SG9sYcUy1t+4eUV8GyifjEGDNUtvmdeaMW80lFzIn6o tIPoU9bXi/M2cedjyzh4/1IJMvL92HskbTv3oLuBtqiT1TbulPp/3twpcZ5/cZCt3Onj crcVwuYCRNa20CwgW/vX46kJelMUas7/97MM3fjgjAkOUEIBC4slQHcjZZoWlK7g7T+h 8gPwPZTP5qJ0D6YOE4ER1LWtGuT82Eo6RTHXaEB7w+A78BoiUOAJULTj1B4KtX5/nhsK kISfLtxtQkHCUkSHaxnmHEgGh0PifBh9cdbjmccYJ1uUOMBKfOi1d8xtcbazZbKtbtUq 4l2g== X-Gm-Message-State: AOJu0Ywb6ac1f3oBnSMYmyFfyB0B8Hzt75BgkF/gGUtl/Z9PF5pn4SWo x7+5k2bG22+LuOsgKK+MI7sWN2ofEyikfEoN8/TyxO3n+ZXdP6za8l50qzfM6Bs58+sikB6r6RS Dx4Ue X-Gm-Gg: ASbGncsgNz1zwHH0UH3Y0IWe62+mpdOm2Zr9HOfPGR4l70hhgfG6fDKRgI/W/Sy+vky i2NESMzZf88cwthEeYD05NHavOHzVnF5VajM84M/dAcJrEjFEyuC1K3sAFyCXFGPXUckC9WkaDe mtV50UFAgDldYFjhZ1uEYF3wHB9vbNHXYjzikQsMQaEeJij7LXbznmC4/agTOJ8c1J9603odNpp bApUId8ObDIaKu3O7bw5Inhd/ATrYnoy5zoZm1y4DI3pEsDuSTLMkZmyRtKNvFrxYkoX6zQQP0s QGgsKugtt8rjbo3M8URK4lTmMRtEPvQYe/YdA0dWlwUGFVi4DNEnd+iD9DiQdLDavKUQEO23z0n XnaHisoPmdZrFWLypZz3NY1SWXNPyk8xUSkLsvDtPsAuXEDPynkI0f+lABEO/94kyUg== X-Google-Smtp-Source: AGHT+IFotDbUgLRpQ8cDPvOXhY+CINzju0YAwor2Y8HXe+klATwB5Vt4WOT6gsalQlsRhn6GK5ftpA== X-Received: by 2002:a05:600c:4f06:b0:450:c9e3:91fe with SMTP id 5b1f17b1804b1-45870973ccbmr11959465e9.0.1753355105710; Thu, 24 Jul 2025 04:05:05 -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 v3 5/8] test/pdx: add PDX compression unit tests Date: Thu, 24 Jul 2025 13:04:13 +0200 Message-ID: <20250724110416.2081-6-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250724110416.2081-1-roger.pau@citrix.com> References: <20250724110416.2081-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: 1753355131026116600 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 --- 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 | 89 +++++++++++++ tools/tests/pdx/test-pdx.c | 267 +++++++++++++++++++++++++++++++++++++ xen/common/pdx.c | 4 + 6 files changed, 412 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..891b4de0bbb7 --- /dev/null +++ b/tools/tests/pdx/harness.h @@ -0,0 +1,89 @@ +/* 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 (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) + +#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 + +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 f4ee2198841d..e58002e59db4 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 Thu Oct 30 18:58:36 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=1753355125; cv=none; d=zohomail.com; s=zohoarc; b=ewnLHsAbtWrc97bOYLlufAgBPwjJAfQ8wLSQvWWlEGK+8OcHmmcbQrik/a4l4ZJg+t4Yz8SkUGljVDYEQc0wR8hDzfydRvrZx6uSViwEqYX3Ju/2/gpfnQMiHNBZJT+yxyR5M82KcMy69QpQe0p0GWA8peV4gzY7udCTGzshxUI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753355125; 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=rHCexFksmnu7nsjmzWKTR3uqAjvVWoxlILSljO2WnJo=; b=hVOjQnt30GsZDIW2rhmaSQKXM9NOvBpAhsQmm4lOAxyePDAm74jeIQHFN8Av1vui5n/NFVN3Ap3pceGX+san8BsD77CqBM/VSxiiyw2pemgUL7arFidBFXIIJMbPgJd96BPjnlMu+0ttRhgEouOFhQljaUzoDuRSY2QaOlIOTes= 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 1753355125649789.827003504567; Thu, 24 Jul 2025 04:05:25 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1055725.1424082 (Exim 4.92) (envelope-from ) id 1uetl7-00026r-Vh; Thu, 24 Jul 2025 11:05:09 +0000 Received: by outflank-mailman (output) from mailman id 1055725.1424082; Thu, 24 Jul 2025 11:05:09 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uetl7-00025R-Q2; Thu, 24 Jul 2025 11:05:09 +0000 Received: by outflank-mailman (input) for mailman id 1055725; Thu, 24 Jul 2025 11:05:08 +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 1uetl6-0000v1-Qd for xen-devel@lists.xenproject.org; Thu, 24 Jul 2025 11:05:08 +0000 Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [2a00:1450:4864:20::32e]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 0f7c65b6-687e-11f0-a31e-13f23c93f187; Thu, 24 Jul 2025 13:05:08 +0200 (CEST) Received: by mail-wm1-x32e.google.com with SMTP id 5b1f17b1804b1-4561a4a8bf2so9678065e9.1 for ; Thu, 24 Jul 2025 04:05:08 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id 5b1f17b1804b1-4587054c819sm15659425e9.13.2025.07.24.04.05.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Jul 2025 04:05:06 -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: 0f7c65b6-687e-11f0-a31e-13f23c93f187 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1753355107; x=1753959907; 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=rHCexFksmnu7nsjmzWKTR3uqAjvVWoxlILSljO2WnJo=; b=dUGlkar0VpRKyBBAL60LKy9YWEhA/hss0hc9mZrFOc8KeB4GeH5OXJBG/67xb26dev x2/lsrfek4UtgQ6YOTDmK0ZF/DtSuYhhksyPtkLg9k92lFo+862r2ZNob8ryl/e40bX6 MdpxY/LF6gCVgdvggY91eJ4vJPdPcKkxGVGbQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753355107; x=1753959907; 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=rHCexFksmnu7nsjmzWKTR3uqAjvVWoxlILSljO2WnJo=; b=M58rTpNKS+K7dq8rbK/ZHpjDibR1BZ7pGmtY6r4pluZEMx5JoGBqH8cLm1XQl/WsTh ttANZgthlbYW4WsTmSvchXb6KhJKz/R/HVZOMYJAEE0rpwnVLlT1AU9B/CwBmAoS7kBO YL1KGr1JY2KFHcRyIDdEJdTqULAuHLNlvlb2/ka46TBqaznwM6xZs41+ej4rZoQcCdYq f0CbXEH/p66J/VaTm7FqXXFEUGuM5uID6VqYI/8E4CZLPtqmKk+YQ+xA08C1wcI8bNXw +Vu82AlLZf/OwzDJDWskIFkdhKlMfpSsHe6ftjlHCXQOY+0YBCg8uXkdUd5HqDW5bfLg PmuQ== X-Gm-Message-State: AOJu0YxhecWJz1gEasrwB38QYf+KRXG3kj9g1HZ6N7snaXqjDIBFz4XO 3efdgtzyxLEkn3IX7YmOeK4sqekDi7yhx5XJTgs/ebcrZcZwNKWK8L1/hwO3oIVDNxu8J08jS6H b3V4O X-Gm-Gg: ASbGncsow446amIZ/qGojT1ZfYpn3lqS9mDxnbxI2bz4OjvukltMaBX5CecA/iuz5vl WDYJQExyC8AYsdbuDK/fuZNZd+cElfbKD5d06C6GTg5nwqLFjZzUPTRio5HYL2XDbvIaAoF20jJ UTq8tmL7YiBnWBxsEzWcxr/EFvnDt0TD1QGfGsuz/+++qFt3T2rTZ6IgYTLmxoJGJux/xEqUFLg msiA11Qq0Ys/J2AoGcqVHBgJmK+IfqQIi7He4luuEE5J7ZvJF4AzoBJ4zpS16hUiTCDr//6deL8 Im6w8XrfJeVXWm4728/f/lR2ZQsc6cJyMyUU7uF9W/G4XSDyi6LcydRtN7gA5WKBHRFSbctUHqC 1TjhS64k3HC2UyJzbshWVvD+7TIj5SBTC5MNDcEf6Wb8sQfmOMhwUSn0TXrD069Uekg== X-Google-Smtp-Source: AGHT+IFRqr8aHXYtijrzcFdXt2309MvJS+TCPZs8pXmRDNTbwDiyzjNc9u8PtEWJ+IfBR3sqef+xaA== X-Received: by 2002:a05:600c:198d:b0:453:483b:626c with SMTP id 5b1f17b1804b1-45868d256a7mr47028655e9.23.1753355107485; Thu, 24 Jul 2025 04:05:07 -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 v3 6/8] pdx: move some helpers in preparation for new compression Date: Thu, 24 Jul 2025 13:04:14 +0200 Message-ID: <20250724110416.2081-7-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250724110416.2081-1-roger.pau@citrix.com> References: <20250724110416.2081-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: 1753355127336116600 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 e58002e59db4..cfe2a3fd344b 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++].size =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 Thu Oct 30 18:58:36 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=1753355134; cv=none; d=zohomail.com; s=zohoarc; b=hZIX4Wb+7fzC4lk5xc+XTsIsxnE94qOGgGRiOF3+bCGBuhmF/a1kUCbvwqKQQ+TmAUzv9OFjbWdrTt5JY/glnSUl+YIx5Kf91V9eaHZZciid3ePEWWNSI5QdCDrAGh7PZF2Y13/cKKrTDjXHApPhWuEiOkDqMaAnuskGp1EIWAI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753355134; 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=qpbmO3mRK8slUcG3TMeLuGAREyFitBGFQBxFIYHXj1k=; b=Vg8TB1GtpejZ0srQoip9G2xnpp4PvYkvxOWQtvhEIwX+jpMC30jL3DZ6eXmkoZ8jdMvWd7YwPCZw0PUQw19LrtmMw1CWvDvaBveYQJNt+MMCxaEjdibiTM1www5qIKSEsTXmIq789VpSatxOt3XkrM5py7Arlo3a1RcQGwiDO7U= 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 175335513481999.23885370104972; Thu, 24 Jul 2025 04:05:34 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1055726.1424099 (Exim 4.92) (envelope-from ) id 1uetlA-0002gf-7P; Thu, 24 Jul 2025 11:05:12 +0000 Received: by outflank-mailman (output) from mailman id 1055726.1424099; Thu, 24 Jul 2025 11:05:12 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uetlA-0002gO-3p; Thu, 24 Jul 2025 11:05:12 +0000 Received: by outflank-mailman (input) for mailman id 1055726; Thu, 24 Jul 2025 11:05:11 +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 1uetl9-0000v1-52 for xen-devel@lists.xenproject.org; Thu, 24 Jul 2025 11:05:11 +0000 Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com [2a00:1450:4864:20::32c]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 10bb125a-687e-11f0-a31e-13f23c93f187; Thu, 24 Jul 2025 13:05:10 +0200 (CEST) Received: by mail-wm1-x32c.google.com with SMTP id 5b1f17b1804b1-45629702e52so4067295e9.2 for ; Thu, 24 Jul 2025 04:05:10 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id ffacd0b85a97d-3b77078e537sm1582685f8f.12.2025.07.24.04.05.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Jul 2025 04:05:08 -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: 10bb125a-687e-11f0-a31e-13f23c93f187 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1753355109; x=1753959909; 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=qpbmO3mRK8slUcG3TMeLuGAREyFitBGFQBxFIYHXj1k=; b=JGtxkI0e0iB8CW++vo63e4VvI8n4O3hyvhLKBhxtDGwaQXJhmhXpmMR4ULXTsy5l/m 5cu/ZkFJ3J6pMqNJyOrEB+gitBb6dsl/JF92QoHY7DfFYZS7wMPLqJlwd8vflkf0wsYK UE/up7HMRoz5SrmzotBOC+u4eiUhLFr7jHvBE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753355109; x=1753959909; 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=qpbmO3mRK8slUcG3TMeLuGAREyFitBGFQBxFIYHXj1k=; b=Pipu/mBmuDG5ucr+PrnNy1utGllV+MT0KJIxtJ9T5UvtXaapB/KhoN5+bIiLgDIfKZ 6tr4z/YcC+BrRyOQFbTBz7OV1cVd3lExjelQnlzwM0/xLBUYm12H1DZ0aWZ2EPCL6/6n q9at2H9tAEQ9ylo9EbCULoC7N2sf/OaK4kFfjsrdwceeW79SiE+panu75nhwDPR9OM81 O864WfQxqD4P5NQOtoRCiZC8VWrNeraz6sqRDtP5lEANuKr3jdr4eMk51w+y2L1ctXc9 vdzIS4DzqU4vwv4ODpVuUeteY+uOxLQIKwhC66Xfi7c8jvMGXSXnZOrbdmHARwaPiZKl UVcQ== X-Gm-Message-State: AOJu0YwpdhklG+J+oi9tBgLiz1DakLC1YosbDDw3QBZc7j87pyhxMv6o H/XQK2w9IH6Xfsd0/qTdsbOmpS3XOagZuiHnqdn5Q1hKAcy5t3m4H2cv+sOygoBc/getLV2Ruaa V1GNP X-Gm-Gg: ASbGncvvEVD3aQY08SQNJ0D7aJeLKR8SOTE66/GKrPiFTPMFSL+3p8IyhQ62qam48lh mI+u09Llu1HZX8vxaB8aS6hg4AJLM7ZYXI3EbAxsXny9OoQ4AljP15/JwpkE9jytS3tAW88Li97 ne/gxRz7ZtEU8UoA4w9dq7Mi3Gwz9riyZeFkLB+OyueLNFDntp83vz4HdKXJA/BIfRXsaoLuHTM dbJclkPoYxqMfw3PdmYTciYAMB3xyw+lkoliRqck1qpcNdsJC89kHCENpNHWA2R2DGTOm6Nn/o4 UhalEjigq9kXUTAQbVp0yB6l2wsUqXbJKx3DNr+FcIfOW6gKhbPS9o0r2PypOHWwnilz744sxRJ YCZn5q1r6YiIEmnMe2Z7KDaa7i3vxN32+hjJLu0n5ua4181dVE5ItD7CJwkS30DSXTvft5gbmZm gl X-Google-Smtp-Source: AGHT+IE4u3udc4FlIO/FGtxM4E7OvA3KmJ96RZwnAduEwHhp1v7bm4GDz2HOBXPi3Q++3YYMaxftQA== X-Received: by 2002:a05:600c:8b2b:b0:453:6ca:16b1 with SMTP id 5b1f17b1804b1-4586e52be18mr21384985e9.26.1753355108735; Thu, 24 Jul 2025 04:05:08 -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 v3 7/8] pdx: introduce a new compression algorithm based on region offsets Date: Thu, 24 Jul 2025 13:04:15 +0200 Message-ID: <20250724110416.2081-8-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250724110416.2081-1-roger.pau@citrix.com> References: <20250724110416.2081-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: 1753355137363116600 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 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 | 255 ++++++++++++++++++++++++++++++++++++- xen/include/xen/pdx.h | 87 ++++++++++++- 8 files changed, 382 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 891b4de0bbb7..18935b283f71 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,6 +68,9 @@ 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 #define pdx_to_pfn pdx_to_pfn_xlate @@ -75,6 +80,15 @@ static inline unsigned int find_next( =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 0014f9b3d6d7..1bfd1e49c8b9 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 cfe2a3fd344b..34ce48170122 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_pdx_mask __init +#else +# define __init_or_pdx_mask +#endif + /* Generic PFN compression helpers. */ static struct pfn_range { unsigned long base, size; @@ -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_pdx_mask 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_pdx_mask 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,242 @@ 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 > r->base ) + return 1; + if ( l->base < r->base ) + return -1; + + return 0; +} + +static void __init cf_check swp_node(void *a, void *b, size_t size) +{ + SWAP(a, b); +} + +static bool __init pfn_offset_sanitize_ranges(void) +{ + unsigned int i =3D 0; + + if ( nr_ranges =3D=3D 1 ) + { + ASSERT(PFN_TBL_IDX(ranges[0].base) =3D=3D + PFN_TBL_IDX(ranges[0].base + ranges[0].size - 1)); + return true; + } + + 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].base) !=3D + PFN_TBL_IDX(ranges[i].base + ranges[i].size - 1) || + PFN_TBL_IDX(ranges[i + 1].base) !=3D + PFN_TBL_IDX(ranges[i + 1].base + ranges[i + 1].size - 1) ) + { + ASSERT_UNREACHABLE(); + return false; + } + + if ( PFN_TBL_IDX(ranges[i].base) !=3D PFN_TBL_IDX(ranges[i + 1].ba= se) ) + { + i++; + continue; + } + + /* Merge ranges with the same table index. */ + ranges[i].size =3D ranges[i + 1].base + ranges[i + 1].size - + ranges[i].base; + 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 size =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; + + /* + * 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 =3D ranges[i].base & ~((1UL << MAX_ORDER) - 1); + ranges[i].size =3D start + ranges[i].size - ranges[i].base; + + /* + * 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 >=3D (ranges[i - 1].base + ranges[i - 1]= .size) ) + { + /* + * We might parse the region at position 0 more than once, as = for + * index 0 we don't attempt to merge to keep this simple. + */ + mask |=3D pdx_region_mask(ranges[i].base, ranges[i].size); + continue; + } + + ranges[i - 1].size =3D ranges[i].base + ranges[i].size - + ranges[i - 1].base; + + 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, ranges[i].size); + 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 & ~mask) ^ (ranges[j].base & ~ma= sk); + + 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; + + /* + * 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++ ) + size =3D max(size, ranges[i].size); + + /* pdx_init_mask() already takes MAX_ORDER into account. */ + mask =3D PFN_DOWN(pdx_init_mask(size << 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 ) + { + 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_pdx_lookup[idx] =3D ranges[i].base - (mask + 1) * i; + pdx_pfn_lookup[i] =3D pfn_pdx_lookup[idx]; + pfn_bases[idx] =3D ranges[i].base; + + printk(XENLOG_DEBUG + " range %3u [%013lx, %013lx] PFN IDX %3u : %013lx\n", + i, ranges[i].base, ranges[i].base + ranges[i].size - 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 91fc32370f21..57e47e6daa11 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 /* * Allow each architecture to define it's (possibly optimized) versions of= the --=20 2.49.0 From nobody Thu Oct 30 18:58:36 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=1753355135; cv=none; d=zohomail.com; s=zohoarc; b=ZHEP/gAHAPKYlhkNiWwqVVncPNmsnv1FNZoXEkjn1tBHRYs5CTFNslkCYfzSjqwh9MXDBpblnkoD7qHvgYRfblD9k4xCfrMADLsbR0eJzkgPUgXreU1rxk3YkfRYh7BpD75FdFZ2lgyHAHtECz6FU4Ga5pPY72v21GFWEBVe0Do= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753355135; 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=tFlfWuMJOmhx5usqEIhEHfIIY5QCQp99txG+M8VywEQ=; b=GDDDHvD0KUQgrQguTFDNKqgOUvFyu4C+xngz2HScHjFaW5/j8SbZg6fsOtCx6V2Nyik6gzfeOKIYF+HogQFvldyMwkc3yUvLVESkzM0mLRf5tvfGQBQzcJHeg+ZrUOloa5hNg06z7LfkAlbhV5mELv7HUCWshUaD9NOAiL+JFo4= 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 1753355135122817.1055187741943; Thu, 24 Jul 2025 04:05:35 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1055728.1424109 (Exim 4.92) (envelope-from ) id 1uetlC-00032p-Rx; Thu, 24 Jul 2025 11:05:14 +0000 Received: by outflank-mailman (output) from mailman id 1055728.1424109; Thu, 24 Jul 2025 11:05:14 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uetlC-00032a-Me; Thu, 24 Jul 2025 11:05:14 +0000 Received: by outflank-mailman (input) for mailman id 1055728; Thu, 24 Jul 2025 11:05: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 1uetlB-00011w-FI for xen-devel@lists.xenproject.org; Thu, 24 Jul 2025 11:05:13 +0000 Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [2a00:1450:4864:20::32a]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 119074be-687e-11f0-b895-0df219b8e170; Thu, 24 Jul 2025 13:05:12 +0200 (CEST) Received: by mail-wm1-x32a.google.com with SMTP id 5b1f17b1804b1-451d54214adso5372575e9.3 for ; Thu, 24 Jul 2025 04:05:12 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id 5b1f17b1804b1-45870532baesm16529805e9.1.2025.07.24.04.05.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Jul 2025 04:05:09 -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: 119074be-687e-11f0-b895-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1753355111; x=1753959911; 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=tFlfWuMJOmhx5usqEIhEHfIIY5QCQp99txG+M8VywEQ=; b=C50+pDZME59I38jNbQylyYEPlBF/6puzwXmxzwlJk03tV4aNPgYMccx8BPTi72eul9 pPd4yfHOLnB3GxfsRhjLLaOU41uPxm8Ioqt2luRclFw49LC2wfnq3/vhkzz88GwJIC+r DM9AF9Qd2hB0Wc0LerIfEVnSJKdSAgI0eS5uI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753355111; x=1753959911; 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=tFlfWuMJOmhx5usqEIhEHfIIY5QCQp99txG+M8VywEQ=; b=NfPRgaSgPslW+56VU5Ur5c+lm+Y7FSA+DIXE6DzaFdHCSkNl+SL7GDsMMBnhFswUSv FxL/Hnm2is8beLKPdgOqF+V0s9nMJHRtSuCpMySiKeOTxUIqyDzamdEriZa5EuoWG/2+ q7NhTs6LcM2xK/tYaahTM/6vKizOXNw2AwIEIftoKgCaPfvlJ74oh0/Kdy3sMDWRbTBM Pw1Z6Nb0FNwjf1/hBfOOOQdlOOX1VNDRaSIuALluijwMz3tNq9Ru0ZjO2KNkOYQNI6Iw qeaqLqPToYHsJl+t7ifK1yAxZC1kYyuVkdfw9v0LEn/MwEEQaYpkneNLCsBNHO/IA5rV noHw== X-Gm-Message-State: AOJu0Yz2eNQXKhY6mzmQ/gfnGEAsZUaEs6+1U7gX/oKgrSgDsbuCBYwv heErbqkS8LAfxzWr8q3Hlx1wsGjN/0VIAIciFnTbj4+jiICSdcn/BvZMITytDPbCqYRdWJTt41a alC1d X-Gm-Gg: ASbGncuY7fi9mbHQPkXepsXYWVNsfoWZCrNkSyyhIsz58iiS5wWK/GiQurGE+4ROur7 hIcXxw6WqGqCO/1JPjGtN/hSLLxmUVAAH3lqXESoZYUJXqvYZmOirlUkPZztk64ak/55jst0s0/ cUCiEFDHdXgM1NssHFmDESEsvOLUPdc2e5MjDht2yRtx63fBWOOELiR8wXHiNV5jCs6NtS/iLzd q7DnCYLhQbE6mrqP/F253dS8b6Q1bfbfq5l5HwHBq2NerLoMQ2QF4BvKaPABsEYsNWxrnbdBb/v UbBdi0bTsVVnAINi9yhO5uqoyQdVFp/9yW1ASB1a2GgTV77LG7ZqZtE70lQeMzgT19O80LD7IAL qh/1JD1/SJ8PaqtDxAhjLbfUxm2oFLf8udElNmzF+W+gePZBsp80TGj6wybqfJQtb2A== X-Google-Smtp-Source: AGHT+IEzCmI44FtmhD/GUunQws3PmEjOyLqKx9nZqyLxCLTipWpVA4pZ3wgU1qzKaxD36LAruVBfSg== X-Received: by 2002:a05:600c:6209:b0:442:c993:6f94 with SMTP id 5b1f17b1804b1-45868c8ec7fmr54963695e9.12.1753355110979; Thu, 24 Jul 2025 04:05:10 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Jan Beulich , Andrew Cooper Subject: [PATCH v3 8/8] x86/mm: adjust loop in arch_init_memory() to iterate over the PDX space Date: Thu, 24 Jul 2025 13:04:16 +0200 Message-ID: <20250724110416.2081-9-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250724110416.2081-1-roger.pau@citrix.com> References: <20250724110416.2081-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: 1753355137131116600 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 v2: - New in this version. --- xen/arch/x86/mm.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index e7fd56c7ce90..647bf0b41db6 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,14 @@ 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. + */ + for ( pdx =3D pfn_to_pdx(pfn); pdx < pfn_to_pdx(rstart_pfn); pdx++= ) { + pfn =3D pdx_to_pfn(pdx); + if ( !mfn_valid(_mfn(pfn)) ) continue; =20 --=20 2.49.0