From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: virtio-dev-return-6505-cohuck=redhat.com@lists.oasis-open.org Sender: List-Post: List-Help: List-Unsubscribe: List-Subscribe: Received: from lists.oasis-open.org (oasis-open.org [10.110.1.242]) by lists.oasis-open.org (Postfix) with ESMTP id A3ECC985DE3 for ; Thu, 12 Dec 2019 17:13:07 +0000 (UTC) From: David Hildenbrand Date: Thu, 12 Dec 2019 18:11:32 +0100 Message-Id: <20191212171137.13872-9-david@redhat.com> In-Reply-To: <20191212171137.13872-1-david@redhat.com> References: <20191212171137.13872-1-david@redhat.com> MIME-Version: 1.0 Subject: [virtio-dev] [PATCH RFC v4 08/13] mm/memory_hotplug: Introduce offline_and_remove_memory() Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable To: linux-kernel@vger.kernel.org Cc: linux-mm@kvack.org, virtio-dev@lists.oasis-open.org, virtualization@lists.linux-foundation.org, kvm@vger.kernel.org, Michal Hocko , Andrew Morton , "Michael S . Tsirkin" , David Hildenbrand , Oscar Salvador , Michal Hocko , Pavel Tatashin , Wei Yang , Dan Williams , Qian Cai List-ID: virtio-mem wants to offline and remove a memory block once it unplugged all subblocks (e.g., using alloc_contig_range()). Let's provide an interface to do that from a driver. virtio-mem already supports to offline partially unplugged memory blocks. Offlining a fully unplugged memory block will not require to migrate any pages. All unplugged subblocks are PageOffline() and have a reference count of 0 - so offlining code will simply skip them. All we need an interface to trigger the "offlining" and the removing in a single operation - to make sure the memory block cannot get onlined by user space again before it gets removed. To keep things simple, allow to only work on a single memory block. Cc: Andrew Morton Cc: David Hildenbrand Cc: Oscar Salvador Cc: Michal Hocko Cc: Pavel Tatashin Cc: Wei Yang Cc: Dan Williams Cc: Qian Cai Signed-off-by: David Hildenbrand --- include/linux/memory_hotplug.h | 1 + mm/memory_hotplug.c | 35 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.= h index ba0dca6aac6e..586f5c59c291 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -310,6 +310,7 @@ extern void try_offline_node(int nid); extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages); extern int remove_memory(int nid, u64 start, u64 size); extern void __remove_memory(int nid, u64 start, u64 size); +extern int offline_and_remove_memory(int nid, u64 start, u64 size); =20 #else static inline bool is_mem_section_removable(unsigned long pfn, diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index da01453a04e6..d04369e6d3cc 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1825,4 +1825,39 @@ int remove_memory(int nid, u64 start, u64 size) =09return rc; } EXPORT_SYMBOL_GPL(remove_memory); + +/* + * Try to offline and remove a memory block. Might take a long time to + * finish in case memory is still in use. Primarily useful for memory devi= ces + * that logically unplugged all memory (so it's no longer in use) and want= to + * offline + remove the memory block. + */ +int offline_and_remove_memory(int nid, u64 start, u64 size) +{ +=09struct memory_block *mem; +=09int rc =3D -EINVAL; + +=09if (!IS_ALIGNED(start, memory_block_size_bytes()) || +=09 size !=3D memory_block_size_bytes()) +=09=09return rc; + +=09lock_device_hotplug(); +=09mem =3D find_memory_block(__pfn_to_section(PFN_DOWN(start))); +=09if (mem) +=09=09rc =3D device_offline(&mem->dev); +=09/* Ignore if the device is already offline. */ +=09if (rc > 0) +=09=09rc =3D 0; + +=09/* +=09 * In case we succeeded to offline the memory block, remove it. +=09 * This cannot fail as it cannot get onlined in the meantime. +=09 */ +=09if (!rc && try_remove_memory(nid, start, size)) +=09=09BUG(); +=09unlock_device_hotplug(); + +=09return rc; +} +EXPORT_SYMBOL_GPL(offline_and_remove_memory); #endif /* CONFIG_MEMORY_HOTREMOVE */ --=20 2.23.0 --------------------------------------------------------------------- To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org