Received: by 2002:a25:23cc:0:0:0:0:0 with SMTP id j195csp761269ybj; Thu, 7 May 2020 07:06:22 -0700 (PDT) X-Google-Smtp-Source: APiQypKaEA2Ajlb0Trmdo0itNVBznZTUEkE7oEZSt2P+DEG/nO9Ad0t7xHTEw4akRvwoFtnsUNIm X-Received: by 2002:a17:906:9442:: with SMTP id z2mr11430973ejx.249.1588860382062; Thu, 07 May 2020 07:06:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1588860382; cv=none; d=google.com; s=arc-20160816; b=x2LHyiIvMTvyI8MbMLBqe9MU9t5xDrYXbJ5btFJ+zbK1b0rv4IiQmmH4hAjMy+CgKH W7xjF5X4D927CQZXr4ZaPOYtHKaxWpEgGxmkVyDPe5H+mtivvWl1UzDOm2nOmA8fsoY0 p4ajdOPnidnxRHqesQO5J9SlW7ajPB43V2iOTFShAMnV6FHDxRO8mTS+S++1tG+UnslF Ypk0qhPTMKA+VWdxEjJBiKI2MpfSMzabDrsVJ6BtznH7OhVdog5WgFVxGDQ8nDE4jTIS gNe7S9en19P968u/Apca7xgGYmFVzG9VL3bPpRig0QhyERhONwnf03oRx/ApWfvpWwTJ yLMw== 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=m6dfIUEjs/h5dLD4Q4Bj2mnMK58/7/bwe2OMjRm9IJU=; b=ki1BWVPOmkmq1Xu7U1ZI9wFLB7O2Cs2YzUL1TtGFK8XKo79PqLQmWg/Rc5BeiWHZXj YyriRCxEC+ghTwpldxh3AdfefSRUmf+y0CINs9hzuZYKJPq4goJeNB30RCoJZAqwsWmp dZ6rh/1xZP4gUyo1Xj+2U7J+mqCYfFYzLKbC4Abu+vntifUr2e34d+NItkITjtFt45Qy ihW740DjGfPzJjWQI3XbnDp+vRXnMPUsNn3lMu89tr+sUE+F4tgUneod2J+1q5MdZvXm Hy6Z3FXqeadhdE0mtSeGmfrOEZDJq3pUhiJ0Yrpum2ovRsyIgtQITrtHZrwZSDbxIhRh W/JA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=O2fQu2u1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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. [23.128.96.18]) by mx.google.com with ESMTP id u30si3521067edi.376.2020.05.07.07.05.54; Thu, 07 May 2020 07:06:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=O2fQu2u1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 S1727826AbgEGODY (ORCPT + 99 others); Thu, 7 May 2020 10:03:24 -0400 Received: from us-smtp-1.mimecast.com ([205.139.110.61]:20145 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726350AbgEGODX (ORCPT ); Thu, 7 May 2020 10:03:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1588860202; 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=m6dfIUEjs/h5dLD4Q4Bj2mnMK58/7/bwe2OMjRm9IJU=; b=O2fQu2u1eLjSMaobilrw+dfjBTRH8GS6PHPJqLc48f/L3sjPogRT6XGn3iMu0S7isMfHKD AKtOomwGdY8tF0ruZFENf1EZl9HJWhehBhxe+jITbQtiIaAc+ZvaWHvVXcsdkR0zRz/8DS 5pP/iKW1eg+n1umEaH4b/9bNCnG6zOg= 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-316-UdQ5DMgUMnWGruHd4aOkjg-1; Thu, 07 May 2020 10:03:15 -0400 X-MC-Unique: UdQ5DMgUMnWGruHd4aOkjg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CF15E1009616; Thu, 7 May 2020 14:03:13 +0000 (UTC) Received: from t480s.redhat.com (ovpn-113-245.ams2.redhat.com [10.36.113.245]) by smtp.corp.redhat.com (Postfix) with ESMTP id 56F6660BEC; Thu, 7 May 2020 14:03:05 +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 , Michal Hocko , Pankaj Gupta , Oscar Salvador , Pavel Tatashin , Wei Yang , Dan Williams , Qian Cai Subject: [PATCH v4 08/15] mm/memory_hotplug: Introduce offline_and_remove_memory() Date: Thu, 7 May 2020 16:01:32 +0200 Message-Id: <20200507140139.17083-9-david@redhat.com> In-Reply-To: <20200507140139.17083-1-david@redhat.com> References: <20200507140139.17083-1-david@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 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 is an interface to offline and remove the memory from kernel module context, where we don't have access to the memory block devices (esp. find_memory_block() and device_offline()) and the device hotplug lock. To keep things simple, allow to only work on a single memory block. Acked-by: Michal Hocko Tested-by: Pankaj Gupta Acked-by: Andrew Morton 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 | 37 ++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 93d9ada74ddd..cb7499843f5c 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -319,6 +319,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); #else static inline bool is_mem_section_removable(unsigned long pfn, diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 008e4a7ed8bc..4acb99aa9bf4 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1821,4 +1821,41 @@ 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 devices + * 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) +{ + struct memory_block *mem; + int rc = -EINVAL; + + if (!IS_ALIGNED(start, memory_block_size_bytes()) || + size != memory_block_size_bytes()) + return rc; + + lock_device_hotplug(); + mem = find_memory_block(__pfn_to_section(PFN_DOWN(start))); + if (mem) + rc = device_offline(&mem->dev); + /* Ignore if the device is already offline. */ + if (rc > 0) + rc = 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) { + rc = try_remove_memory(nid, start, size); + WARN_ON_ONCE(rc); + } + unlock_device_hotplug(); + + return rc; +} +EXPORT_SYMBOL_GPL(offline_and_remove_memory); #endif /* CONFIG_MEMORY_HOTREMOVE */ -- 2.25.3