{"id":1839913,"url":"http://patchwork.ozlabs.org/api/patches/1839913/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/patch/20230926185738.277351-7-david@redhat.com/","project":{"id":14,"url":"http://patchwork.ozlabs.org/api/projects/14/?format=json","name":"QEMU Development","link_name":"qemu-devel","list_id":"qemu-devel.nongnu.org","list_email":"qemu-devel@nongnu.org","web_url":"","scm_url":"","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20230926185738.277351-7-david@redhat.com>","list_archive_url":null,"date":"2023-09-26T18:57:26","name":"[v4,06/18] memory-device: Support memory devices with multiple memslots","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"5d3320e321e3787520f063e45891a48745a84220","submitter":{"id":70402,"url":"http://patchwork.ozlabs.org/api/people/70402/?format=json","name":"David Hildenbrand","email":"david@redhat.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/qemu-devel/patch/20230926185738.277351-7-david@redhat.com/mbox/","series":[{"id":374991,"url":"http://patchwork.ozlabs.org/api/series/374991/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/list/?series=374991","date":"2023-09-26T18:57:23","name":"virtio-mem: Expose device memory through multiple memslots","version":4,"mbox":"http://patchwork.ozlabs.org/series/374991/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/1839913/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/1839913/checks/","tags":{},"related":[],"headers":{"Return-Path":"<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=Av5T+1Y6;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4Rw8H300Mhz1ypM\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 27 Sep 2023 05:01:34 +1000 (AEST)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1qlDH0-000755-71; Tue, 26 Sep 2023 14:59:06 -0400","from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <david@redhat.com>) id 1qlDGw-00074Q-H9\n for qemu-devel@nongnu.org; Tue, 26 Sep 2023 14:59:02 -0400","from us-smtp-delivery-124.mimecast.com ([170.10.133.124])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <david@redhat.com>) id 1qlDGt-00033d-JE\n for qemu-devel@nongnu.org; Tue, 26 Sep 2023 14:59:01 -0400","from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com\n [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n us-mta-48-XkJhC17kOYS5HH0CKa08Yg-1; Tue, 26 Sep 2023 14:58:55 -0400","from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com\n [10.11.54.4])\n (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n (No client certificate requested)\n by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D88EB101A529;\n Tue, 26 Sep 2023 18:58:54 +0000 (UTC)","from t14s.fritz.box (unknown [10.39.192.33])\n by smtp.corp.redhat.com (Postfix) with ESMTP id 3264C2026D4B;\n Tue, 26 Sep 2023 18:58:46 +0000 (UTC)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1695754739;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=X6FoTWZmAFi9ZDQpW8tsN1nzgSbk2tEh+9iM6CbpDp4=;\n b=Av5T+1Y67dV43pG50FztodfKl8dQB4TT/dOrvCpLTsWdyHE+OWaTE7Bv+MO20QLX/Dbyvt\n w+FB+WrrnBY7yxEQyJVOXDBSEuPtYv6Pbpul8A9fnTfqD9I5Oqif42jMqpB2F2cSAulvwb\n K3JGAfsJVq+PU1N5YiSWWkJTNygvRjI=","X-MC-Unique":"XkJhC17kOYS5HH0CKa08Yg-1","From":"David Hildenbrand <david@redhat.com>","To":"qemu-devel@nongnu.org","Cc":"David Hildenbrand <david@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>,\n Igor Mammedov <imammedo@redhat.com>,\n Xiao Guangrong <xiaoguangrong.eric@gmail.com>,\n \"Michael S. Tsirkin\" <mst@redhat.com>, Peter Xu <peterx@redhat.com>,\n\t=?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= <philmd@linaro.org>,\n Eduardo Habkost <eduardo@habkost.net>,\n Marcel Apfelbaum <marcel.apfelbaum@gmail.com>,\n Yanan Wang <wangyanan55@huawei.com>, Michal Privoznik <mprivozn@redhat.com>,\n\t=?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= <berrange@redhat.com>,\n Gavin Shan <gshan@redhat.com>, Alex Williamson <alex.williamson@redhat.com>,\n Stefan Hajnoczi <stefanha@redhat.com>,\n \"Maciej S . Szmigiero\" <mail@maciej.szmigiero.name>, kvm@vger.kernel.org,\n \"Maciej S . Szmigiero\" <maciej.szmigiero@oracle.com>","Subject":"[PATCH v4 06/18] memory-device: Support memory devices with multiple\n memslots","Date":"Tue, 26 Sep 2023 20:57:26 +0200","Message-ID":"<20230926185738.277351-7-david@redhat.com>","In-Reply-To":"<20230926185738.277351-1-david@redhat.com>","References":"<20230926185738.277351-1-david@redhat.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","X-Scanned-By":"MIMEDefang 3.1 on 10.11.54.4","Received-SPF":"pass client-ip=170.10.133.124; envelope-from=david@redhat.com;\n helo=us-smtp-delivery-124.mimecast.com","X-Spam_score_int":"-20","X-Spam_score":"-2.1","X-Spam_bar":"--","X-Spam_report":"(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001,\n DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001,\n SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no","X-Spam_action":"no action","X-BeenThere":"qemu-devel@nongnu.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<qemu-devel.nongnu.org>","List-Unsubscribe":"<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>","List-Archive":"<https://lists.nongnu.org/archive/html/qemu-devel>","List-Post":"<mailto:qemu-devel@nongnu.org>","List-Help":"<mailto:qemu-devel-request@nongnu.org?subject=help>","List-Subscribe":"<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>","Errors-To":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org","Sender":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"},"content":"We want to support memory devices that have a memory region container as\ndevice memory region that maps multiple RAM memory regions. Let's start\nby supporting memory devices that statically map multiple RAM memory\nregions and, thereby, consume multiple memslots.\n\nWe already have one device that uses a container as device memory region:\nNVDIMMs. However, a NVDIMM always ends up consuming exactly one memslot.\n\nLet's add support for that by asking the memory device via a new\ncallback how many memslots it requires.\n\nReviewed-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>\nSigned-off-by: David Hildenbrand <david@redhat.com>\n---\n hw/mem/memory-device.c         | 27 +++++++++++++++++++--------\n include/hw/mem/memory-device.h | 18 ++++++++++++++++++\n 2 files changed, 37 insertions(+), 8 deletions(-)","diff":"diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c\nindex e09960744d..0eec0872a9 100644\n--- a/hw/mem/memory-device.c\n+++ b/hw/mem/memory-device.c\n@@ -52,19 +52,30 @@ static int memory_device_build_list(Object *obj, void *opaque)\n     return 0;\n }\n \n-static void memory_device_check_addable(MachineState *ms, MemoryRegion *mr,\n-                                        Error **errp)\n+static unsigned int memory_device_get_memslots(MemoryDeviceState *md)\n+{\n+    const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);\n+\n+    if (mdc->get_memslots) {\n+        return mdc->get_memslots(md);\n+    }\n+    return 1;\n+}\n+\n+static void memory_device_check_addable(MachineState *ms, MemoryDeviceState *md,\n+                                        MemoryRegion *mr, Error **errp)\n {\n     const uint64_t used_region_size = ms->device_memory->used_region_size;\n     const uint64_t size = memory_region_size(mr);\n+    const unsigned int required_memslots = memory_device_get_memslots(md);\n \n-    /* we will need a new memory slot for kvm and vhost */\n-    if (kvm_enabled() && !kvm_get_free_memslots()) {\n-        error_setg(errp, \"hypervisor has no free memory slots left\");\n+    /* we will need memory slots for kvm and vhost */\n+    if (kvm_enabled() && kvm_get_free_memslots() < required_memslots) {\n+        error_setg(errp, \"hypervisor has not enough free memory slots left\");\n         return;\n     }\n-    if (!vhost_get_free_memslots()) {\n-        error_setg(errp, \"a used vhost backend has no free memory slots left\");\n+    if (vhost_get_free_memslots() < required_memslots) {\n+        error_setg(errp, \"a used vhost backend has not enough free memory slots left\");\n         return;\n     }\n \n@@ -233,7 +244,7 @@ void memory_device_pre_plug(MemoryDeviceState *md, MachineState *ms,\n         goto out;\n     }\n \n-    memory_device_check_addable(ms, mr, &local_err);\n+    memory_device_check_addable(ms, md, mr, &local_err);\n     if (local_err) {\n         goto out;\n     }\ndiff --git a/include/hw/mem/memory-device.h b/include/hw/mem/memory-device.h\nindex 48d2611fc5..b51a579fb9 100644\n--- a/include/hw/mem/memory-device.h\n+++ b/include/hw/mem/memory-device.h\n@@ -41,6 +41,11 @@ typedef struct MemoryDeviceState MemoryDeviceState;\n  * successive memory regions are used, a covering memory region has to\n  * be provided. Scattered memory regions are not supported for single\n  * devices.\n+ *\n+ * The device memory region returned via @get_memory_region may either be a\n+ * single RAM memory region or a memory region container with subregions\n+ * that are RAM memory regions or aliases to RAM memory regions. Other\n+ * memory regions or subregions are not supported.\n  */\n struct MemoryDeviceClass {\n     /* private */\n@@ -88,6 +93,19 @@ struct MemoryDeviceClass {\n      */\n     MemoryRegion *(*get_memory_region)(MemoryDeviceState *md, Error **errp);\n \n+    /*\n+     * Optional for memory devices that require only a single memslot,\n+     * required for all other memory devices: Return the number of memslots\n+     * (distinct RAM memory regions in the device memory region) that are\n+     * required by the device.\n+     *\n+     * If this function is not implemented, the assumption is \"1\".\n+     *\n+     * Called when (un)plugging the memory device, to check if the requirements\n+     * can be satisfied, and to do proper accounting.\n+     */\n+    unsigned int (*get_memslots)(MemoryDeviceState *md);\n+\n     /*\n      * Optional: Return the desired minimum alignment of the device in guest\n      * physical address space. The final alignment is computed based on this\n","prefixes":["v4","06/18"]}