Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp1074017ybl; Thu, 12 Dec 2019 09:14:13 -0800 (PST) X-Google-Smtp-Source: APXvYqylcKW2LGZvYCfVUtHDSCf594dujcRDBjmqCvUOB63zlNqawLup9PLEeKA4nbDKePNqlzH+ X-Received: by 2002:a05:6808:102:: with SMTP id b2mr5773738oie.127.1576170853601; Thu, 12 Dec 2019 09:14:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1576170853; cv=none; d=google.com; s=arc-20160816; b=jxrSrnMmdoCf1tg6/aBtMvuUHKXa0ukfmYwQkwDMDn1XSvFy2LqKpdbJe7PZi5inJ7 jhYmBwFiOsSA0Sq1nDOAIu50hMqmhi+3e3qPP5qwy1FT6iqJoeNNUW9uEgnk1EPGt920 8dedSosPNDFN5S13bwIkKVySl36kET7XLsTKDJjLlPlMVv35SjFJeEKJubRQ7n6PIVg2 1rv+o3W6MYfr2/bg3sI3sruO4V/aTkOUL3qXTjHIGW98aezrG98xyU687j8XffraQF1W 2AkSRS3g55ZjSGSDj8Zv5ReGy6wYzRxtfIcZyjf+DljZMw6fUnPwmjk70PKyggfCZNaj Nx9w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=FRA+T3LczXKLz/t1x5ONbwAW2HplNDXABfw4iwLSung=; b=w29/+8CjOHEyXUxXFlRmJ2NsnXqXzer9t9V4BJeG/LqGJuHdiP8S+QoZnIAYxHwMFd ScviLycL9slqoHZyW0nE7B/tSqAMsbZyTQE49CnTWuVuImwyhBHai4lqLrYKxHYD0Oml 4+kMAMMjwYP5hgkF+b6Kq6tTiCvGOKyw8ntz1r9Qrx/gTpxvddaLt7qx9EtVPrLvs+tc 2lGavxWZUKxjA4CIuvjsJQ802LthHGFFzd+B2aYbvihAs4GvBYHb43FLNUZECWNz0QYz 6NmyWKcytP26qtxLRZnbnQ6vLg9DD1h5Zmf94xQpLgzYCc9+jIngsixWZJvkSIbZcfbo zcmg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=GvIQ3IoN; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 123si3654852oif.177.2019.12.12.09.14.00; Thu, 12 Dec 2019 09:14:13 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=GvIQ3IoN; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730200AbfLLRNH (ORCPT + 99 others); Thu, 12 Dec 2019 12:13:07 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:23431 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1730190AbfLLRNF (ORCPT ); Thu, 12 Dec 2019 12:13:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1576170784; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=FRA+T3LczXKLz/t1x5ONbwAW2HplNDXABfw4iwLSung=; b=GvIQ3IoNhbxzJsKwz8C5CTdV3+QO5e2ruUlcbNHdWFmB5PHFJYn3+8L00Sl0KSa7oXkiRJ wE6SL+1LXzNS5qGslEaGiLzxY+QPtbyYzRJPRBn3PkrzYLLTrtZncpYaTwJNT7JGYyBx3g 0KkphcQ4Rxc4YiYFQa5DoqPEsXvRWgY= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-257-v1whvpOoM_OtlY-bBijBcA-1; Thu, 12 Dec 2019 12:13:01 -0500 X-MC-Unique: v1whvpOoM_OtlY-bBijBcA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 52813800D5A; Thu, 12 Dec 2019 17:12:59 +0000 (UTC) Received: from t480s.redhat.com (ovpn-117-65.ams2.redhat.com [10.36.117.65]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7388F5C21B; Thu, 12 Dec 2019 17:12:56 +0000 (UTC) From: David Hildenbrand 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 Subject: [PATCH RFC v4 08/13] mm/memory_hotplug: Introduce offline_and_remove_memory() 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 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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_hotplu= g.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) return 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 de= vices + * that logically unplugged all memory (so it's no longer in use) and wa= nt to + * offline + remove the memory block. + */ +int offline_and_remove_memory(int nid, u64 start, u64 size) +{ + struct memory_block *mem; + int rc =3D -EINVAL; + + if (!IS_ALIGNED(start, memory_block_size_bytes()) || + size !=3D memory_block_size_bytes()) + return rc; + + lock_device_hotplug(); + mem =3D find_memory_block(__pfn_to_section(PFN_DOWN(start))); + if (mem) + rc =3D device_offline(&mem->dev); + /* Ignore if the device is already offline. */ + if (rc > 0) + rc =3D 0; + + /* + * In case we succeeded to offline the memory block, remove it. + * This cannot fail as it cannot get onlined in the meantime. + */ + if (!rc && try_remove_memory(nid, start, size)) + BUG(); + unlock_device_hotplug(); + + return rc; +} +EXPORT_SYMBOL_GPL(offline_and_remove_memory); #endif /* CONFIG_MEMORY_HOTREMOVE */ --=20 2.23.0