From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ed1-f50.google.com (mail-ed1-f50.google.com [209.85.208.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EFEF92D8372 for ; Wed, 19 Nov 2025 11:42:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.50 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763552577; cv=none; b=AgyJi89arcIfJeNzoHSseHC46dUYSXW1e2RdMIDR1nIPtXOjILQ1ywXRmYjMKDzc8f/eLpkwms4ZJJ+9sJL0U9xNnKvBaSL4hrBALTi/NBlxFuZ7QUQoXl/TQrZv2WkUr3G91mO70xL1maIXAmq51C/fN0uB717ZBt3fAgSWzYU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763552577; c=relaxed/simple; bh=lQh2Ye8gQxDPzP73XhzbjFuwiXQbl9rCsYl70ed+CU4=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=iaiKeR6q64vSPddS7JspQRBuu0uNC8gydM0yeSghGgm88sTDiXcJkmxk70ruwRiizikFPl7JK+q35dD9p/JZQLD8iCdqhTKx6eI/zLuTWa6UfLUr7ONyKtFgUHpJvH41K8Yxx9fk2zhoBM29WaQaArWL9fi3IyXo7zIFGwD3VgY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=OuvigBJ/; arc=none smtp.client-ip=209.85.208.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OuvigBJ/" Received: by mail-ed1-f50.google.com with SMTP id 4fb4d7f45d1cf-64074f01a6eso1857021a12.2 for ; Wed, 19 Nov 2025 03:42:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1763552574; x=1764157374; darn=vger.kernel.org; h=user-agent:in-reply-to:content-disposition:mime-version:references :reply-to:message-id:subject:cc:to:from:date:from:to:cc:subject:date :message-id:reply-to; bh=p+8CdVW7qRHuadRsFNXcHiteFeYMuyKZGGt4Q4lo3EA=; b=OuvigBJ/DpvPlfZnmMgJfE9o+xatP3eBqIgpU6uBNHMT1mmKFsGR42DTqqTA5YPN18 9GSxIzv9UT5Ds/mY1q/b+dh9AgM0p4Yp3WXF2Dqp+JReCgHUfcKN7Proy+1R28RIt5nP oZfm1LyHOpXaQoUsGxpNdLSmq0Z5EFYNba771/3ePLKvmHyN8irXe8oN8DJmN1IELGgr bkB2Z/ClCNPaFnJrmj2Wb78oTnZ2F8/fEyiCWK68FI7fC9QdcuhFDvPi9swk3uZCLaJ3 26KUcPqBL1rTsY7o+SYrx8bU+Vq3KKUKQpyXqgCpYYkyUyC43D1coPOiv2dDJAzumoZr RM1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763552574; x=1764157374; h=user-agent:in-reply-to:content-disposition:mime-version:references :reply-to:message-id:subject:cc:to:from:date:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=p+8CdVW7qRHuadRsFNXcHiteFeYMuyKZGGt4Q4lo3EA=; b=T05VjNWcpuUTE5FXbMX9YeakenvmbWI8ATnc0cpeUMYusdjuSZkwWMFSKKp18YgH9R kglfw7zdhAg33U8fgBNTPuKII7eWA7UVVmZLILsKgzbGOhe4V+NkJt2CYOHTrgi7IPuS JfUz7eafEZ9xt+PPDZSzEAdP+hG8lnamXW4QAQBNWCcMcoB16hmz8jpbf3DrbkG0jL+k VDZKKmQ5XvINvi3kPR9h5F7Y81eKfl45o5SLiTDqEXDzS5noGHMJFAOJDVXq2cLT3gEz DgqC3bzEfpNa5efPxSK5uCk20D0NjShnHEDuCXGeCESx++mK/hUi38CxZWm7KoQx4ucN V0kw== X-Forwarded-Encrypted: i=1; AJvYcCUS8+2hVgFDzPoIkpAbtIp0bL8rH4LHOyB/PF7F1apmgdvrg5g2qWMl7qOoiZLOlQBjfIfUxsPBvcCKewk=@vger.kernel.org X-Gm-Message-State: AOJu0YylpF4+A8HA9sJULzauf6rkljpWKtKHWeoSQnisxDt63WDiyHpJ yVWl9KH5nFOtrAp1SIcx2Okz7uRrTglREgAFqm5RoLV/ZXcsQtd5iyJd X-Gm-Gg: ASbGncvdDIkHnfb+zO6L8JZWcEQ3P3/VIAvJPWedoH1J7ujkKeNBGBaUz5KX44Za4RR mqMST1TD3jhbXBw/91PKlSwAnTvKFJakqSubLyepTC6egUUTN+Dpq9weVUJYok7HIVYkAqnWgmh 9V0PkFsruvQMdND5ZQpEEyDJ//eV2iplUWRmXbONGrVgSGHkY95Z9dHTr/OsFTcBxuVmxVznHD1 Qhw0wSKJ3rxWZz3WvqQP86NAZ8wlgT8u0eGj9HMXTZsSpr5T0OM/5sUXfEf0umz3H3qv9FAc9mu /ttSsHgEmMqoz9M8QYsZQEiuELM2NMj59fnG3cr66R+hdWDACypmAW6y/i8d7oWVFd9qzW9HjtZ e3wcR0LHWSAASR9DcmWVj7JXBB9A+lQKVdIiObNW859I8rPEFD1RZACAYRxWzUEh9xNfspj/7BT b841aJoV978S4b7g== X-Google-Smtp-Source: AGHT+IHsC8WLzRz86acSXKKLf9htyktUYbaQTt584boJvhtqrXAJbQVTaPMhhYWIheLKaJCxpnT9YA== X-Received: by 2002:a05:6402:2806:b0:643:60b6:3eed with SMTP id 4fb4d7f45d1cf-64360b63f56mr15412046a12.31.1763552574059; Wed, 19 Nov 2025 03:42:54 -0800 (PST) Received: from localhost ([185.92.221.13]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6433a4b1fadsm16169223a12.31.2025.11.19.03.42.52 (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 19 Nov 2025 03:42:53 -0800 (PST) Date: Wed, 19 Nov 2025 11:42:52 +0000 From: Wei Yang To: Tianyou Li Cc: David Hildenbrand , Oscar Salvador , Mike Rapoport , linux-mm@kvack.org, Yong Hu , Nanhai Zou , Yuan Liu , Tim Chen , Qiuxu Zhuo , Yu C Chen , Pan Deng , Chen Zhang , linux-kernel@vger.kernel.org Subject: Re: [PATCH v2] mm/memory hotplug/unplug: Optimize zone->contiguous update when move pfn range Message-ID: <20251119114252.oykrczprf3ecd7ak@master> Reply-To: Wei Yang References: <20251119040718.2735199-1-tianyou.li@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20251119040718.2735199-1-tianyou.li@intel.com> User-Agent: NeoMutt/20170113 (1.7.2) On Wed, Nov 19, 2025 at 12:07:18PM +0800, Tianyou Li wrote: >When invoke move_pfn_range_to_zone, it will update the zone->contiguous by >checking the new zone's pfn range from the beginning to the end, regardless >the previous state of the old zone. When the zone's pfn range is large, the >cost of traversing the pfn range to update the zone->contiguous could be >significant. > >Add fast paths to quickly detect cases where zone is definitely not >contiguous without scanning the new zone. The cases are: when the new range >did not overlap with previous range, the contiguous should be false; if the >new range adjacent with the previous range, just need to check the new >range; if the new added pages could not fill the hole of previous zone, the >contiguous should be false. > >The following test cases of memory hotplug for a VM [1], tested in the >environment [2], show that this optimization can significantly reduce the >memory hotplug time [3]. > >+----------------+------+---------------+--------------+----------------+ >| | Size | Time (before) | Time (after) | Time Reduction | >| +------+---------------+--------------+----------------+ >| Memory Hotplug | 256G | 10s | 2s | 80% | >| +------+---------------+--------------+----------------+ >| | 512G | 33s | 6s | 81% | >+----------------+------+---------------+--------------+----------------+ > Nice >[1] Qemu commands to hotplug 512G memory for a VM: > object_add memory-backend-ram,id=hotmem0,size=512G,share=on > device_add virtio-mem-pci,id=vmem1,memdev=hotmem0,bus=port1 > qom-set vmem1 requested-size 512G > >[2] Hardware : Intel Icelake server > Guest Kernel : v6.18-rc2 > Qemu : v9.0.0 > > Launch VM : > qemu-system-x86_64 -accel kvm -cpu host \ > -drive file=./Centos10_cloud.qcow2,format=qcow2,if=virtio \ > -drive file=./seed.img,format=raw,if=virtio \ > -smp 3,cores=3,threads=1,sockets=1,maxcpus=3 \ > -m 2G,slots=10,maxmem=2052472M \ > -device pcie-root-port,id=port1,bus=pcie.0,slot=1,multifunction=on \ > -device pcie-root-port,id=port2,bus=pcie.0,slot=2 \ > -nographic -machine q35 \ > -nic user,hostfwd=tcp::3000-:22 > > Guest kernel auto-onlines newly added memory blocks: > echo online > /sys/devices/system/memory/auto_online_blocks > >[3] The time from typing the QEMU commands in [1] to when the output of > 'grep MemTotal /proc/meminfo' on Guest reflects that all hotplugged > memory is recognized. > >Reported-by: Nanhai Zou >Reported-by: Chen Zhang >Tested-by: Yuan Liu >Reviewed-by: Tim Chen >Reviewed-by: Qiuxu Zhuo >Reviewed-by: Yu C Chen >Reviewed-by: Pan Deng >Reviewed-by: Nanhai Zou >Reviewed-by: Yuan Liu >Signed-off-by: Tianyou Li >--- > mm/memory_hotplug.c | 57 ++++++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 54 insertions(+), 3 deletions(-) > >diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c >index 0be83039c3b5..8f126f20ca47 100644 >--- a/mm/memory_hotplug.c >+++ b/mm/memory_hotplug.c >@@ -723,6 +723,57 @@ static void __meminit resize_pgdat_range(struct pglist_data *pgdat, unsigned lon > > } > >+static bool __meminit check_zone_contiguous_fast(struct zone *zone, >+ unsigned long start_pfn, unsigned long nr_pages) >+{ >+ const unsigned long end_pfn = start_pfn + nr_pages; >+ unsigned long nr_filled_pages; >+ >+ /* >+ * Given the moved pfn range's contiguous property is always true, >+ * under the conditional of empty zone, the contiguous property should >+ * be true. >+ */ >+ if (zone_is_empty(zone)) { >+ zone->contiguous = true; >+ return true; >+ } >+ >+ /* >+ * If the moved pfn range does not intersect with the original zone span, >+ * the contiguous property is surely false. >+ */ >+ if (end_pfn < zone->zone_start_pfn || start_pfn > zone_end_pfn(zone)) { >+ zone->contiguous = false; >+ return true; >+ } >+ >+ /* >+ * If the moved pfn range is adjacent to the original zone span, given >+ * the moved pfn range's contiguous property is always true, the zone's >+ * contiguous property inherited from the original value. >+ */ >+ if (end_pfn == zone->zone_start_pfn || start_pfn == zone_end_pfn(zone)) >+ return true; >+ >+ /* >+ * If the original zone's hole larger than the new filled pages, the >+ * contiguous property is surely false. >+ */ >+ nr_filled_pages = end_pfn - zone->zone_start_pfn; >+ if (start_pfn > zone->zone_start_pfn) >+ nr_filled_pages -= start_pfn - zone->zone_start_pfn; >+ if (end_pfn > zone_end_pfn(zone)) >+ nr_filled_pages -= end_pfn - zone_end_pfn(zone); >+ if (nr_filled_pages < (zone->spanned_pages - zone->present_pages)) { >+ zone->contiguous = false; >+ return true; >+ } >+ Mike's suggestion is easier for me to understand :-) >+ clear_zone_contiguous(zone); >+ return false; >+} >+ > #ifdef CONFIG_ZONE_DEVICE > static void section_taint_zone_device(unsigned long pfn) > { >@@ -752,8 +803,7 @@ void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn, > { > struct pglist_data *pgdat = zone->zone_pgdat; > int nid = pgdat->node_id; >- >- clear_zone_contiguous(zone); >+ const bool fast_path = check_zone_contiguous_fast(zone, start_pfn, nr_pages); > > if (zone_is_empty(zone)) > init_currently_empty_zone(zone, start_pfn, nr_pages); >@@ -783,7 +833,8 @@ void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn, > MEMINIT_HOTPLUG, altmap, migratetype, > isolate_pageblock); > >- set_zone_contiguous(zone); >+ if (!fast_path) >+ set_zone_contiguous(zone); > } > > struct auto_movable_stats { >-- >2.47.1 > -- Wei Yang Help you, Help me