From patchwork Thu Mar 5 14:29:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1249607 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=RTgK0QiL; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YCq65fYSz9sPK for ; Fri, 6 Mar 2020 01:31:14 +1100 (AEDT) Received: from localhost ([::1]:50238 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rWq-0006S3-LT for incoming@patchwork.ozlabs.org; Thu, 05 Mar 2020 09:31:12 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35296) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rWJ-0006Kk-Er for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:30:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9rWH-0001y7-Sq for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:30:39 -0500 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:53302 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j9rWH-0001xl-P9 for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:30:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583418637; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zwsZQQ5MN8MY5ICY0EQq4aovYGXTGBvqIvi5JLhszK0=; b=RTgK0QiLfMXBUyx8TO7j4Suv4VK2OgySwoyCt/nPb79ME0zIvJfP+XXehfpmQIvbCceJSC DTs4+/qzZLcZEqgov5IcexRLbw3O+edJrRAoXpeowA6/6wFiXMQO63xUceSIlTgdqiWE/A y0avn/VH86gOoVXwcxCdtpVmtj+e6+Q= 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-148-ri2IzFBxMxCRh_TycEN30A-1; Thu, 05 Mar 2020 09:30:36 -0500 X-MC-Unique: ri2IzFBxMxCRh_TycEN30A-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id F194D80573D; Thu, 5 Mar 2020 14:30:34 +0000 (UTC) Received: from t480s.redhat.com (ovpn-120-166.rdu2.redhat.com [10.10.120.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id C010690538; Thu, 5 Mar 2020 14:30:13 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 01/15] util: vfio-helpers: Fix qemu_vfio_close() Date: Thu, 5 Mar 2020 15:29:31 +0100 Message-Id: <20200305142945.216465-2-david@redhat.com> In-Reply-To: <20200305142945.216465-1-david@redhat.com> References: <20200305142945.216465-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 205.139.110.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Igor Kotrasinski , David Hildenbrand , "Dr . David Alan Gilbert" , Peter Xu , Alex Williamson , Murilo Opsfelder Araujo , Igor Mammedov , Paolo Bonzini , Stefan Hajnoczi , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" qemu_vfio_undo_mapping() will decrement the number of mappings and reshuffle the array elements to fit into the reduced size. Iterating over all elements like this does not work as expected, let's make sure to remove all mappings properly. Reviewed-by: Peter Xu Cc: Richard Henderson Cc: Paolo Bonzini Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Alex Williamson Cc: Stefan Hajnoczi Signed-off-by: David Hildenbrand Reviewed-by: Philippe Mathieu-Daudé --- util/vfio-helpers.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c index 9ec01bfe26..f31aa77ffe 100644 --- a/util/vfio-helpers.c +++ b/util/vfio-helpers.c @@ -695,13 +695,11 @@ static void qemu_vfio_reset(QEMUVFIOState *s) /* Close and free the VFIO resources. */ void qemu_vfio_close(QEMUVFIOState *s) { - int i; - if (!s) { return; } - for (i = 0; i < s->nr_mappings; ++i) { - qemu_vfio_undo_mapping(s, &s->mappings[i], NULL); + while (s->nr_mappings) { + qemu_vfio_undo_mapping(s, &s->mappings[s->nr_mappings - 1], NULL); } ram_block_notifier_remove(&s->ram_notifier); qemu_vfio_reset(s); From patchwork Thu Mar 5 14:29:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1249608 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=HhbrqhWz; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YCqZ5MHPz9sPK for ; Fri, 6 Mar 2020 01:31:38 +1100 (AEDT) Received: from localhost ([::1]:50246 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rXE-0006sw-KH for incoming@patchwork.ozlabs.org; Thu, 05 Mar 2020 09:31:36 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35358) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rWd-0006je-NN for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:31:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9rWc-0002Ni-GU for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:30:59 -0500 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:36421 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j9rWc-0002Mr-CQ for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:30:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583418657; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tSdqeDwxoY+yI2Z7vVys/AxXflRczSoFv2iz+5GIaqc=; b=HhbrqhWzFWWyIP0ZCt+XFhYuFQJijIdFzxI/mRxonNcCNeJ/NIDYNmUDciMoWLPVVDxmS3 Nh2EFdn4TMm14hMbVK5CPejmkZfXyS4F1250WvmMRopa1tSGSYgXzL5sQ92P39c1TL9o3F jXM2yF9wwaxIl2hXlZ65OnHAKeFmJO4= 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-471-JwQVP6qjO4WMU0B9XcPW4Q-1; Thu, 05 Mar 2020 09:30:56 -0500 X-MC-Unique: JwQVP6qjO4WMU0B9XcPW4Q-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E8A5110CE780; Thu, 5 Mar 2020 14:30:54 +0000 (UTC) Received: from t480s.redhat.com (ovpn-120-166.rdu2.redhat.com [10.10.120.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id F11BD91D79; Thu, 5 Mar 2020 14:30:35 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 02/15] util: vfio-helpers: Remove Error parameter from qemu_vfio_undo_mapping() Date: Thu, 5 Mar 2020 15:29:32 +0100 Message-Id: <20200305142945.216465-3-david@redhat.com> In-Reply-To: <20200305142945.216465-1-david@redhat.com> References: <20200305142945.216465-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.81 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Igor Kotrasinski , David Hildenbrand , "Dr . David Alan Gilbert" , Peter Xu , Alex Williamson , Murilo Opsfelder Araujo , Igor Mammedov , Paolo Bonzini , Stefan Hajnoczi , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Everybody discards the error. Let's error_report() instead so this error doesn't get lost. This is now the same error handling as in qemu_vfio_do_mapping(). However, we don't report any errors via the return value to the caller. This seems to be one of these "will never happen, but let's better print an error because the caller can't handle it either way" cases. Cc: Richard Henderson Cc: Paolo Bonzini Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Alex Williamson Cc: Stefan Hajnoczi Signed-off-by: David Hildenbrand Acked-by: Murilo Opsfelder Araujo --- util/vfio-helpers.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c index f31aa77ffe..7085ca702c 100644 --- a/util/vfio-helpers.c +++ b/util/vfio-helpers.c @@ -541,8 +541,7 @@ static int qemu_vfio_do_mapping(QEMUVFIOState *s, void *host, size_t size, /** * Undo the DMA mapping from @s with VFIO, and remove from mapping list. */ -static void qemu_vfio_undo_mapping(QEMUVFIOState *s, IOVAMapping *mapping, - Error **errp) +static void qemu_vfio_undo_mapping(QEMUVFIOState *s, IOVAMapping *mapping) { int index; struct vfio_iommu_type1_dma_unmap unmap = { @@ -557,7 +556,7 @@ static void qemu_vfio_undo_mapping(QEMUVFIOState *s, IOVAMapping *mapping, assert(QEMU_IS_ALIGNED(mapping->size, qemu_real_host_page_size)); assert(index >= 0 && index < s->nr_mappings); if (ioctl(s->container, VFIO_IOMMU_UNMAP_DMA, &unmap)) { - error_setg_errno(errp, errno, "VFIO_UNMAP_DMA failed"); + error_report("VFIO_UNMAP_DMA failed: %s", strerror(errno)); } memmove(mapping, &s->mappings[index + 1], sizeof(s->mappings[0]) * (s->nr_mappings - index - 1)); @@ -622,7 +621,7 @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, assert(qemu_vfio_verify_mappings(s)); ret = qemu_vfio_do_mapping(s, host, size, iova0); if (ret) { - qemu_vfio_undo_mapping(s, mapping, NULL); + qemu_vfio_undo_mapping(s, mapping); goto out; } s->low_water_mark += size; @@ -682,7 +681,7 @@ void qemu_vfio_dma_unmap(QEMUVFIOState *s, void *host) if (!m) { goto out; } - qemu_vfio_undo_mapping(s, m, NULL); + qemu_vfio_undo_mapping(s, m); out: qemu_mutex_unlock(&s->lock); } @@ -699,7 +698,7 @@ void qemu_vfio_close(QEMUVFIOState *s) return; } while (s->nr_mappings) { - qemu_vfio_undo_mapping(s, &s->mappings[s->nr_mappings - 1], NULL); + qemu_vfio_undo_mapping(s, &s->mappings[s->nr_mappings - 1]); } ram_block_notifier_remove(&s->ram_notifier); qemu_vfio_reset(s); From patchwork Thu Mar 5 14:29:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1249610 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=JUHKsOwf; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YCrh1Dn2z9sPK for ; Fri, 6 Mar 2020 01:32:36 +1100 (AEDT) Received: from localhost ([::1]:50260 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rY8-00089R-P0 for incoming@patchwork.ozlabs.org; Thu, 05 Mar 2020 09:32:32 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35458) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rX8-0007U2-2L for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:31:35 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9rX6-0002jF-OC for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:31:29 -0500 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:46123 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j9rX6-0002it-Jw for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:31:28 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583418688; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0oUugQEab4bqH2Kasf8WtgB6oPJtcM2uppzFCmdwZI8=; b=JUHKsOwfi1Kc0W/U2f6gTaLNzEItgpz1+Dup93ILvn1F+lrF2Ohwd5YNpfw/hCMQpEcEr0 zjMTvMVXs5cw5InhGt0e2Z8q1t4C6skyGYQ3kEDzMZhYqlSiqGuin3l6yMs2K3zcS+VENu TiEtM8wfS5gBc4Wq2j0jMG+k37h6GUs= 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-408-YfrNahMhMHGve8jcxcwk8A-1; Thu, 05 Mar 2020 09:31:21 -0500 X-MC-Unique: YfrNahMhMHGve8jcxcwk8A-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E7638107ACCD; Thu, 5 Mar 2020 14:31:19 +0000 (UTC) Received: from t480s.redhat.com (ovpn-120-166.rdu2.redhat.com [10.10.120.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id E882E90538; Thu, 5 Mar 2020 14:30:55 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 03/15] util: vfio-helpers: Factor out removal from qemu_vfio_undo_mapping() Date: Thu, 5 Mar 2020 15:29:33 +0100 Message-Id: <20200305142945.216465-4-david@redhat.com> In-Reply-To: <20200305142945.216465-1-david@redhat.com> References: <20200305142945.216465-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 205.139.110.61 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Igor Kotrasinski , David Hildenbrand , "Dr . David Alan Gilbert" , Peter Xu , Alex Williamson , Murilo Opsfelder Araujo , Igor Mammedov , Paolo Bonzini , Stefan Hajnoczi , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Factor it out and properly use it where applicable. Make qemu_vfio_undo_mapping() look like qemu_vfio_do_mapping(), passing the size and iova, not the mapping. Reviewed-by: Peter Xu Cc: Richard Henderson Cc: Paolo Bonzini Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Alex Williamson Cc: Stefan Hajnoczi Signed-off-by: David Hildenbrand Acked-by: Murilo Opsfelder Araujo --- util/vfio-helpers.c | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c index 7085ca702c..f0c77f0d69 100644 --- a/util/vfio-helpers.c +++ b/util/vfio-helpers.c @@ -518,6 +518,20 @@ static IOVAMapping *qemu_vfio_add_mapping(QEMUVFIOState *s, return insert; } +/** + * Remove the mapping from @s and free it. + */ +static void qemu_vfio_remove_mapping(QEMUVFIOState *s, IOVAMapping *mapping) +{ + const int index = mapping - s->mappings; + + assert(index >= 0 && index < s->nr_mappings); + memmove(mapping, &s->mappings[index + 1], + sizeof(s->mappings[0]) * (s->nr_mappings - index - 1)); + s->nr_mappings--; + s->mappings = g_renew(IOVAMapping, s->mappings, s->nr_mappings); +} + /* Do the DMA mapping with VFIO. */ static int qemu_vfio_do_mapping(QEMUVFIOState *s, void *host, size_t size, uint64_t iova) @@ -539,29 +553,22 @@ static int qemu_vfio_do_mapping(QEMUVFIOState *s, void *host, size_t size, } /** - * Undo the DMA mapping from @s with VFIO, and remove from mapping list. + * Undo the DMA mapping from @s with VFIO. */ -static void qemu_vfio_undo_mapping(QEMUVFIOState *s, IOVAMapping *mapping) +static void qemu_vfio_undo_mapping(QEMUVFIOState *s, size_t size, uint64_t iova) { - int index; struct vfio_iommu_type1_dma_unmap unmap = { .argsz = sizeof(unmap), .flags = 0, - .iova = mapping->iova, - .size = mapping->size, + .iova = iova, + .size = size, }; - index = mapping - s->mappings; - assert(mapping->size > 0); - assert(QEMU_IS_ALIGNED(mapping->size, qemu_real_host_page_size)); - assert(index >= 0 && index < s->nr_mappings); + assert(size > 0); + assert(QEMU_IS_ALIGNED(size, qemu_real_host_page_size)); if (ioctl(s->container, VFIO_IOMMU_UNMAP_DMA, &unmap)) { error_report("VFIO_UNMAP_DMA failed: %s", strerror(errno)); } - memmove(mapping, &s->mappings[index + 1], - sizeof(s->mappings[0]) * (s->nr_mappings - index - 1)); - s->nr_mappings--; - s->mappings = g_renew(IOVAMapping, s->mappings, s->nr_mappings); } /* Check if the mapping list is (ascending) ordered. */ @@ -621,7 +628,7 @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, assert(qemu_vfio_verify_mappings(s)); ret = qemu_vfio_do_mapping(s, host, size, iova0); if (ret) { - qemu_vfio_undo_mapping(s, mapping); + qemu_vfio_remove_mapping(s, mapping); goto out; } s->low_water_mark += size; @@ -681,7 +688,8 @@ void qemu_vfio_dma_unmap(QEMUVFIOState *s, void *host) if (!m) { goto out; } - qemu_vfio_undo_mapping(s, m); + qemu_vfio_undo_mapping(s, m->size, m->iova); + qemu_vfio_remove_mapping(s, m); out: qemu_mutex_unlock(&s->lock); } @@ -698,7 +706,10 @@ void qemu_vfio_close(QEMUVFIOState *s) return; } while (s->nr_mappings) { - qemu_vfio_undo_mapping(s, &s->mappings[s->nr_mappings - 1]); + IOVAMapping *m = &s->mappings[s->nr_mappings - 1]; + + qemu_vfio_undo_mapping(s, m->size, m->iova); + qemu_vfio_remove_mapping(s, m); } ram_block_notifier_remove(&s->ram_notifier); qemu_vfio_reset(s); From patchwork Thu Mar 5 14:29:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1249612 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=MsYyAbrO; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YCtW6nmQz9sQt for ; Fri, 6 Mar 2020 01:34:11 +1100 (AEDT) Received: from localhost ([::1]:50310 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rZh-0002z7-Rj for incoming@patchwork.ozlabs.org; Thu, 05 Mar 2020 09:34:09 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35577) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rXN-0007rT-Ph for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:31:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9rXI-0002rW-MP for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:31:45 -0500 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:53051 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j9rXI-0002rD-I0 for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:31:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583418700; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=H1vGZKqDhRtg8g2lSBh3C+rY8EjMrCl2v+tMPCxz9io=; b=MsYyAbrOF3gFRlQ7tnAYc72bXbR1dzCc/70ZkX7iCtmznTo0zUuli3RmNKclJawXsxCstG ceHAE7uAe0Uj7g5u2xwXwkYuhPJ5W1gL8kZaS5Lno0/CJWfYKR63Qqfhc8pVwl3ABS9D8l 2P2NJB0OtlLtboXNhtr7+shFhy/6g48= 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-32-5rRkZvsoMnC8HeoaK5BQaA-1; Thu, 05 Mar 2020 09:31:38 -0500 X-MC-Unique: 5rRkZvsoMnC8HeoaK5BQaA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 5B4DA107ACC4; Thu, 5 Mar 2020 14:31:34 +0000 (UTC) Received: from t480s.redhat.com (ovpn-120-166.rdu2.redhat.com [10.10.120.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4724F90538; Thu, 5 Mar 2020 14:31:20 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 04/15] exec: Factor out setting ram settings (madvise ...) into qemu_ram_apply_settings() Date: Thu, 5 Mar 2020 15:29:34 +0100 Message-Id: <20200305142945.216465-5-david@redhat.com> In-Reply-To: <20200305142945.216465-1-david@redhat.com> References: <20200305142945.216465-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 205.139.110.61 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Richard Henderson , Igor Kotrasinski , David Hildenbrand , "Dr . David Alan Gilbert" , Peter Xu , Murilo Opsfelder Araujo , Igor Mammedov , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Factor all settings out into qemu_ram_apply_settings(). For memory_try_enable_merging(), the important bit is that it won't be called with XEN - which is now still the case as new_block->host will remain NULL. Reviewed-by: Richard Henderson Reviewed-by: Peter Xu Cc: Richard Henderson Cc: Paolo Bonzini Cc: Igor Mammedov Signed-off-by: David Hildenbrand --- exec.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/exec.c b/exec.c index 3e980e14e0..13a0ca91fb 100644 --- a/exec.c +++ b/exec.c @@ -2069,6 +2069,21 @@ static int memory_try_enable_merging(void *addr, size_t len) return qemu_madvise(addr, len, QEMU_MADV_MERGEABLE); } +static void qemu_ram_apply_settings(void *host, size_t length) +{ + memory_try_enable_merging(host, length); + qemu_ram_setup_dump(host, length); + qemu_madvise(host, length, QEMU_MADV_HUGEPAGE); + /* + * MADV_DONTFORK is also needed by KVM in absence of synchronous MMU + * Configure it unless the machine is a qtest server, in which case KVM is + * not used and it may be forked (eg for fuzzing purposes). + */ + if (!qtest_enabled()) { + qemu_madvise(host, length, QEMU_MADV_DONTFORK); + } +} + /* * Resizing RAM while migrating can result in the migration being canceled. * Care has to be taken if the guest might have already detected the memory. @@ -2227,7 +2242,6 @@ static void ram_block_add(RAMBlock *new_block, Error **errp, bool shared) qemu_mutex_unlock_ramlist(); return; } - memory_try_enable_merging(new_block->host, new_block->max_length); } } @@ -2265,17 +2279,7 @@ static void ram_block_add(RAMBlock *new_block, Error **errp, bool shared) DIRTY_CLIENTS_ALL); if (new_block->host) { - qemu_ram_setup_dump(new_block->host, new_block->max_length); - qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_HUGEPAGE); - /* - * MADV_DONTFORK is also needed by KVM in absence of synchronous MMU - * Configure it unless the machine is a qtest server, in which case - * KVM is not used and it may be forked (eg for fuzzing purposes). - */ - if (!qtest_enabled()) { - qemu_madvise(new_block->host, new_block->max_length, - QEMU_MADV_DONTFORK); - } + qemu_ram_apply_settings(new_block->host, new_block->max_length); ram_block_notify_add(new_block->host, new_block->used_length, new_block->max_length); } From patchwork Thu Mar 5 14:29:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1249609 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=goUES688; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YCrW2c43z9sPK for ; Fri, 6 Mar 2020 01:32:27 +1100 (AEDT) Received: from localhost ([::1]:50258 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rY0-00081D-VU for incoming@patchwork.ozlabs.org; Thu, 05 Mar 2020 09:32:25 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35580) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rXO-0007rz-5Q for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:31:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9rXM-0002vo-UG for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:31:45 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:50650 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j9rXM-0002tn-KJ for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:31:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583418703; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Gkp7fjbvX7Nm/DRryTdHidK6wwGuuVyuDCVl3FhjKwo=; b=goUES688jWbNcOxl5HA+CsVx2eypA2Scjbj77gHKLhMbtDY9BGtUCUNF6mRdbgwn0gacZ9 dGZaVqymhdHfWfN0yksA0zx3dj/WeQ5+Kwz2PRC2pCdAdvROlum884I0uPUq4eh3m+0+S8 FeVSJ5QJwyuJvpilcIyd1YZfkw0jV0w= 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-391-oWn3h0PHMmmhPibmANd0fg-1; Thu, 05 Mar 2020 09:31:41 -0500 X-MC-Unique: oWn3h0PHMmmhPibmANd0fg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0302F100550E; Thu, 5 Mar 2020 14:31:40 +0000 (UTC) Received: from t480s.redhat.com (ovpn-120-166.rdu2.redhat.com [10.10.120.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id A4A8090538; Thu, 5 Mar 2020 14:31:34 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 05/15] exec: Reuse qemu_ram_apply_settings() in qemu_ram_remap() Date: Thu, 5 Mar 2020 15:29:35 +0100 Message-Id: <20200305142945.216465-6-david@redhat.com> In-Reply-To: <20200305142945.216465-1-david@redhat.com> References: <20200305142945.216465-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Richard Henderson , Igor Kotrasinski , David Hildenbrand , "Dr . David Alan Gilbert" , Peter Xu , Murilo Opsfelder Araujo , Igor Mammedov , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" I don't see why we shouldn't apply all settings to make it look like the surrounding RAM (and enable proper VMA merging). Note: memory backend settings might have overridden these settings. We would need a callback to let the memory backend fix that up. Reviewed-by: Richard Henderson Reviewed-by: Peter Xu Cc: Richard Henderson Cc: Paolo Bonzini Cc: Igor Mammedov Signed-off-by: David Hildenbrand --- exec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/exec.c b/exec.c index 13a0ca91fb..7df1ecaf5d 100644 --- a/exec.c +++ b/exec.c @@ -2516,8 +2516,7 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length) length, addr); exit(1); } - memory_try_enable_merging(vaddr, length); - qemu_ram_setup_dump(vaddr, length); + qemu_ram_apply_settings(vaddr, length); } } } From patchwork Thu Mar 5 14:29:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1249613 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ZD8iDThm; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YCtg6mX2z9sPK for ; Fri, 6 Mar 2020 01:34:19 +1100 (AEDT) Received: from localhost ([::1]:50314 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rZp-0003Fp-PE for incoming@patchwork.ozlabs.org; Thu, 05 Mar 2020 09:34:17 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35644) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rXd-0008G0-5s for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9rXb-00035w-28 for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:01 -0500 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:53291 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j9rXa-00035c-U4 for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:31:59 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583418718; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ShYiHE6kFQxkIi922zjEjjdiqynzXHmbI7RWuGJZQ88=; b=ZD8iDThms2iogs2qLUfCBwYjnHpPlP0f+dRWMQDAHh+/1DRbIVRyRQTm2eTsTLjf8wWGT0 Ka1l57AsKiCwfr2HdazYA0fZBAjyY36fAqZuS2ak0W1vvsZn+hu37qYXtTOnkmpe4Dfm3V m5sTxlkK+WXnwVonryDQXv/fJbVFuE0= 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-130-8A-VtGG1Pki5QstW2By9pw-1; Thu, 05 Mar 2020 09:31:57 -0500 X-MC-Unique: 8A-VtGG1Pki5QstW2By9pw-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D9A1110CE780; Thu, 5 Mar 2020 14:31:55 +0000 (UTC) Received: from t480s.redhat.com (ovpn-120-166.rdu2.redhat.com [10.10.120.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id 01DF691D68; Thu, 5 Mar 2020 14:31:40 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 06/15] exec: Drop "shared" parameter from ram_block_add() Date: Thu, 5 Mar 2020 15:29:36 +0100 Message-Id: <20200305142945.216465-7-david@redhat.com> In-Reply-To: <20200305142945.216465-1-david@redhat.com> References: <20200305142945.216465-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 205.139.110.61 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Richard Henderson , Igor Kotrasinski , David Hildenbrand , "Dr . David Alan Gilbert" , Peter Xu , Murilo Opsfelder Araujo , Igor Mammedov , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Properly store it in the flags of the ram block instead (and the flag even already exists and is used). E.g., qemu_ram_is_shared() now properly succeeds on all ram blocks that are actually shared. Reviewed-by: Igor Kotrasinski Reviewed-by: Richard Henderson Reviewed-by: Peter Xu Cc: Richard Henderson Cc: Paolo Bonzini Cc: Igor Mammedov Signed-off-by: David Hildenbrand --- exec.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/exec.c b/exec.c index 7df1ecaf5d..9c3cc79193 100644 --- a/exec.c +++ b/exec.c @@ -2211,7 +2211,7 @@ static void dirty_memory_extend(ram_addr_t old_ram_size, } } -static void ram_block_add(RAMBlock *new_block, Error **errp, bool shared) +static void ram_block_add(RAMBlock *new_block, Error **errp) { RAMBlock *block; RAMBlock *last_block = NULL; @@ -2234,7 +2234,8 @@ static void ram_block_add(RAMBlock *new_block, Error **errp, bool shared) } } else { new_block->host = phys_mem_alloc(new_block->max_length, - &new_block->mr->align, shared); + &new_block->mr->align, + qemu_ram_is_shared(new_block)); if (!new_block->host) { error_setg_errno(errp, errno, "cannot set up guest memory '%s'", @@ -2339,7 +2340,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr, return NULL; } - ram_block_add(new_block, &local_err, ram_flags & RAM_SHARED); + ram_block_add(new_block, &local_err); if (local_err) { g_free(new_block); error_propagate(errp, local_err); @@ -2401,10 +2402,13 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size, if (host) { new_block->flags |= RAM_PREALLOC; } + if (share) { + new_block->flags |= RAM_SHARED; + } if (resizeable) { new_block->flags |= RAM_RESIZEABLE; } - ram_block_add(new_block, &local_err, share); + ram_block_add(new_block, &local_err); if (local_err) { g_free(new_block); error_propagate(errp, local_err); From patchwork Thu Mar 5 14:29:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1249630 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=aHfteZn8; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YCyM5zXDz9sSM for ; Fri, 6 Mar 2020 01:37:31 +1100 (AEDT) Received: from localhost ([::1]:50370 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rcv-0000bC-Pj for incoming@patchwork.ozlabs.org; Thu, 05 Mar 2020 09:37:29 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35671) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rXg-0008Og-Rw for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9rXf-00038z-KR for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:04 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:45764 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j9rXf-00038h-GG for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583418723; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6BRQjN964Dr4w6axvvjVY5gJygw5QYBcf+sSZYLkYQo=; b=aHfteZn8LZaK9Rf95BGcSEQMlZBAYnx/sJYNL9l5xltLqrctHEcTwOFkjVyQV+a6tdF2aN mvAfRM+W59Oi79Qm1dscGpgnZaohdu6uC5Pr6nuWkz1WuPBO9wBciUohnLFGafRP0B4SaP Qx/BKi472UavW3cISkNr3QaxwVnFvwI= 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-471-wPRTW4a-PxqCROMY29kVpQ-1; Thu, 05 Mar 2020 09:31:59 -0500 X-MC-Unique: wPRTW4a-PxqCROMY29kVpQ-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 6DEE913E4; Thu, 5 Mar 2020 14:31:58 +0000 (UTC) Received: from t480s.redhat.com (ovpn-120-166.rdu2.redhat.com [10.10.120.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2E63790538; Thu, 5 Mar 2020 14:31:56 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 07/15] util/mmap-alloc: Factor out calculation of the pagesize for the guard page Date: Thu, 5 Mar 2020 15:29:37 +0100 Message-Id: <20200305142945.216465-8-david@redhat.com> In-Reply-To: <20200305142945.216465-1-david@redhat.com> References: <20200305142945.216465-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Igor Kotrasinski , David Hildenbrand , "Dr . David Alan Gilbert" , Peter Xu , Greg Kurz , Murilo Opsfelder Araujo , Igor Mammedov , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Let's factor out calculating the size of the guard page and rename the variable to make it clearer that this pagesize only applies to the guard page. Reviewed-by: Peter Xu Cc: "Michael S. Tsirkin" Cc: Murilo Opsfelder Araujo Cc: Greg Kurz Cc: Eduardo Habkost Cc: "Dr. David Alan Gilbert" Cc: Igor Mammedov Signed-off-by: David Hildenbrand Acked-by: Murilo Opsfelder Araujo --- util/mmap-alloc.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c index 27dcccd8ec..f0277f9fad 100644 --- a/util/mmap-alloc.c +++ b/util/mmap-alloc.c @@ -82,17 +82,27 @@ size_t qemu_mempath_getpagesize(const char *mem_path) return qemu_real_host_page_size; } +static inline size_t mmap_guard_pagesize(int fd) +{ +#if defined(__powerpc64__) && defined(__linux__) + /* Mappings in the same segment must share the same page size */ + return qemu_fd_getpagesize(fd); +#else + return qemu_real_host_page_size; +#endif +} + void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared, bool is_pmem) { + const size_t guard_pagesize = mmap_guard_pagesize(fd); int flags; int map_sync_flags = 0; int guardfd; size_t offset; - size_t pagesize; size_t total; void *guardptr; void *ptr; @@ -113,8 +123,7 @@ void *qemu_ram_mmap(int fd, * anonymous memory is OK. */ flags = MAP_PRIVATE; - pagesize = qemu_fd_getpagesize(fd); - if (fd == -1 || pagesize == qemu_real_host_page_size) { + if (fd == -1 || guard_pagesize == qemu_real_host_page_size) { guardfd = -1; flags |= MAP_ANONYMOUS; } else { @@ -123,7 +132,6 @@ void *qemu_ram_mmap(int fd, } #else guardfd = -1; - pagesize = qemu_real_host_page_size; flags = MAP_PRIVATE | MAP_ANONYMOUS; #endif @@ -135,7 +143,7 @@ void *qemu_ram_mmap(int fd, assert(is_power_of_2(align)); /* Always align to host page size */ - assert(align >= pagesize); + assert(align >= guard_pagesize); flags = MAP_FIXED; flags |= fd == -1 ? MAP_ANONYMOUS : 0; @@ -189,8 +197,8 @@ void *qemu_ram_mmap(int fd, * a guard page guarding against potential buffer overflows. */ total -= offset; - if (total > size + pagesize) { - munmap(ptr + size + pagesize, total - size - pagesize); + if (total > size + guard_pagesize) { + munmap(ptr + size + guard_pagesize, total - size - guard_pagesize); } return ptr; @@ -198,15 +206,8 @@ void *qemu_ram_mmap(int fd, void qemu_ram_munmap(int fd, void *ptr, size_t size) { - size_t pagesize; - if (ptr) { /* Unmap both the RAM block and the guard page */ -#if defined(__powerpc64__) && defined(__linux__) - pagesize = qemu_fd_getpagesize(fd); -#else - pagesize = qemu_real_host_page_size; -#endif - munmap(ptr, size + pagesize); + munmap(ptr, size + mmap_guard_pagesize(fd)); } } From patchwork Thu Mar 5 14:29:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1249633 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QtwvBt3v; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YCzq09LHz9sRR for ; Fri, 6 Mar 2020 01:38:47 +1100 (AEDT) Received: from localhost ([::1]:50390 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9re8-00036Q-RF for incoming@patchwork.ozlabs.org; Thu, 05 Mar 2020 09:38:44 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35699) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rXi-0008TT-Va for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:08 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9rXh-0003BT-LS for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:06 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:24213 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j9rXh-0003BB-HG for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583418725; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0M+moTdl0qV7+Qhg/JRf45CFzQnG475adDlEdMRPHAI=; b=QtwvBt3vVIvKJmS8s7tJlhEPDuEQPGGPVDNiaRLm3jhqi/zPHjSxmT3JweIsKgmgOriGb2 SlP8AHf4EDlUBFM1UrF8jA6rc047b5XUpKMKQ0sF9mEC1pCtsn49LVHgUKxaEZTEBfgzdJ 42dKWqjyxN7dWepNcBWmFPZBsJQgO1s= 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-27-MiGM3g_mMW-NoMMQTnF6Hg-1; Thu, 05 Mar 2020 09:32:03 -0500 X-MC-Unique: MiGM3g_mMW-NoMMQTnF6Hg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 26945800D55; Thu, 5 Mar 2020 14:32:01 +0000 (UTC) Received: from t480s.redhat.com (ovpn-120-166.rdu2.redhat.com [10.10.120.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id B51A790538; Thu, 5 Mar 2020 14:31:58 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 08/15] util/mmap-alloc: Factor out reserving of a memory region to mmap_reserve() Date: Thu, 5 Mar 2020 15:29:38 +0100 Message-Id: <20200305142945.216465-9-david@redhat.com> In-Reply-To: <20200305142945.216465-1-david@redhat.com> References: <20200305142945.216465-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Richard Henderson , Igor Kotrasinski , David Hildenbrand , "Dr . David Alan Gilbert" , Peter Xu , Greg Kurz , Murilo Opsfelder Araujo , Igor Mammedov , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" We want to reserve a memory region without actually populating memory. Let's factor that out. Reviewed-by: Igor Kotrasinski Acked-by: Murilo Opsfelder Araujo Reviewed-by: Richard Henderson Reviewed-by: Peter Xu Cc: "Michael S. Tsirkin" Cc: Greg Kurz Cc: Murilo Opsfelder Araujo Cc: Eduardo Habkost Cc: "Dr. David Alan Gilbert" Cc: Igor Mammedov Signed-off-by: David Hildenbrand --- util/mmap-alloc.c | 58 +++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c index f0277f9fad..9e9534a07e 100644 --- a/util/mmap-alloc.c +++ b/util/mmap-alloc.c @@ -82,6 +82,38 @@ size_t qemu_mempath_getpagesize(const char *mem_path) return qemu_real_host_page_size; } +/* + * Reserve a new memory region of the requested size to be used for mapping + * from the given fd (if any). + */ +static void *mmap_reserve(size_t size, int fd) +{ + int flags = MAP_PRIVATE; + +#if defined(__powerpc64__) && defined(__linux__) + /* + * On ppc64 mappings in the same segment (aka slice) must share the same + * page size. Since we will be re-allocating part of this segment + * from the supplied fd, we should make sure to use the same page size, to + * this end we mmap the supplied fd. In this case, set MAP_NORESERVE to + * avoid allocating backing store memory. + * We do this unless we are using the system page size, in which case + * anonymous memory is OK. + */ + if (fd == -1 || qemu_fd_getpagesize(fd) == qemu_real_host_page_size) { + fd = -1; + flags |= MAP_ANONYMOUS; + } else { + flags |= MAP_NORESERVE; + } +#else + fd = -1; + flags |= MAP_ANONYMOUS; +#endif + + return mmap(0, size, PROT_NONE, flags, fd, 0); +} + static inline size_t mmap_guard_pagesize(int fd) { #if defined(__powerpc64__) && defined(__linux__) @@ -101,7 +133,6 @@ void *qemu_ram_mmap(int fd, const size_t guard_pagesize = mmap_guard_pagesize(fd); int flags; int map_sync_flags = 0; - int guardfd; size_t offset; size_t total; void *guardptr; @@ -113,30 +144,7 @@ void *qemu_ram_mmap(int fd, */ total = size + align; -#if defined(__powerpc64__) && defined(__linux__) - /* On ppc64 mappings in the same segment (aka slice) must share the same - * page size. Since we will be re-allocating part of this segment - * from the supplied fd, we should make sure to use the same page size, to - * this end we mmap the supplied fd. In this case, set MAP_NORESERVE to - * avoid allocating backing store memory. - * We do this unless we are using the system page size, in which case - * anonymous memory is OK. - */ - flags = MAP_PRIVATE; - if (fd == -1 || guard_pagesize == qemu_real_host_page_size) { - guardfd = -1; - flags |= MAP_ANONYMOUS; - } else { - guardfd = fd; - flags |= MAP_NORESERVE; - } -#else - guardfd = -1; - flags = MAP_PRIVATE | MAP_ANONYMOUS; -#endif - - guardptr = mmap(0, total, PROT_NONE, flags, guardfd, 0); - + guardptr = mmap_reserve(total, fd); if (guardptr == MAP_FAILED) { return MAP_FAILED; } From patchwork Thu Mar 5 14:29:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1249611 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=BOa0dJ54; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YCsj5t85z9sSM for ; Fri, 6 Mar 2020 01:33:29 +1100 (AEDT) Received: from localhost ([::1]:50298 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rZ1-0001Qp-GH for incoming@patchwork.ozlabs.org; Thu, 05 Mar 2020 09:33:27 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35728) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rXp-0000GE-Li for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9rXo-0003GV-Cw for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:13 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:33026 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j9rXo-0003GK-9H for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583418732; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5lGKktvpp3+XdkvJGg3g7hD+l344AtPs6h6RHl03TEQ=; b=BOa0dJ54G38m9d4UN7JtF8hn/cNNe+5U8wbNI8qrou3R+why31LowI58ccdxS2nGkaefEQ DEMIXIUCowvRJNbWkLHtn/7KiF/N5tazEffMHJWjAavO0viGBjv3LNs24xtjItJ33NPNWW x4d0tRepsj/ryOM3SXmWHFoJyRN2B6o= 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-269-sLI3RBJYOAqwvftCriaCiQ-1; Thu, 05 Mar 2020 09:32:10 -0500 X-MC-Unique: sLI3RBJYOAqwvftCriaCiQ-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 54DD38017DF; Thu, 5 Mar 2020 14:32:09 +0000 (UTC) Received: from t480s.redhat.com (ovpn-120-166.rdu2.redhat.com [10.10.120.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6E14090538; Thu, 5 Mar 2020 14:32:01 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 09/15] util/mmap-alloc: Factor out activating of memory to mmap_activate() Date: Thu, 5 Mar 2020 15:29:39 +0100 Message-Id: <20200305142945.216465-10-david@redhat.com> In-Reply-To: <20200305142945.216465-1-david@redhat.com> References: <20200305142945.216465-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Richard Henderson , Igor Kotrasinski , David Hildenbrand , "Dr . David Alan Gilbert" , Peter Xu , Greg Kurz , Murilo Opsfelder Araujo , Igor Mammedov , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" We want to activate memory within a reserved memory region, to make it accessible. Let's factor that out. Reviewed-by: Richard Henderson Acked-by: Murilo Opsfelder Araujo Reviewed-by: Peter Xu Cc: Igor Kotrasinski Cc: "Michael S. Tsirkin" Cc: Greg Kurz Cc: Murilo Opsfelder Araujo Cc: Eduardo Habkost Cc: "Dr. David Alan Gilbert" Cc: Igor Mammedov Signed-off-by: David Hildenbrand --- util/mmap-alloc.c | 90 +++++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 42 deletions(-) diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c index 9e9534a07e..8f40ef4fed 100644 --- a/util/mmap-alloc.c +++ b/util/mmap-alloc.c @@ -114,6 +114,51 @@ static void *mmap_reserve(size_t size, int fd) return mmap(0, size, PROT_NONE, flags, fd, 0); } +/* + * Activate memory in a reserved region from the given fd (if any), to make + * it accessible. + */ +static void *mmap_activate(void *ptr, size_t size, int fd, bool shared, + bool is_pmem) +{ + int map_sync_flags = 0; + int flags = MAP_FIXED; + void *activated_ptr; + + flags |= fd == -1 ? MAP_ANONYMOUS : 0; + flags |= shared ? MAP_SHARED : MAP_PRIVATE; + if (shared && is_pmem) { + map_sync_flags = MAP_SYNC | MAP_SHARED_VALIDATE; + } + + activated_ptr = mmap(ptr, size, PROT_READ | PROT_WRITE, + flags | map_sync_flags, fd, 0); + if (activated_ptr == MAP_FAILED && map_sync_flags) { + if (errno == ENOTSUP) { + char *proc_link = g_strdup_printf("/proc/self/fd/%d", fd); + char *file_name = g_malloc0(PATH_MAX); + int len = readlink(proc_link, file_name, PATH_MAX - 1); + + if (len < 0) { + len = 0; + } + file_name[len] = '\0'; + fprintf(stderr, "Warning: requesting persistence across crashes " + "for backend file %s failed. Proceeding without " + "persistence, data might become corrupted in case of host " + "crash.\n", file_name); + g_free(proc_link); + g_free(file_name); + } + /* + * If mmap failed with MAP_SHARED_VALIDATE | MAP_SYNC, we will try + * again without these flags to handle backwards compatibility. + */ + activated_ptr = mmap(ptr, size, PROT_READ | PROT_WRITE, flags, fd, 0); + } + return activated_ptr; +} + static inline size_t mmap_guard_pagesize(int fd) { #if defined(__powerpc64__) && defined(__linux__) @@ -131,12 +176,8 @@ void *qemu_ram_mmap(int fd, bool is_pmem) { const size_t guard_pagesize = mmap_guard_pagesize(fd); - int flags; - int map_sync_flags = 0; - size_t offset; - size_t total; - void *guardptr; - void *ptr; + size_t offset, total; + void *ptr, *guardptr; /* * Note: this always allocates at least one extra page of virtual address @@ -153,44 +194,9 @@ void *qemu_ram_mmap(int fd, /* Always align to host page size */ assert(align >= guard_pagesize); - flags = MAP_FIXED; - flags |= fd == -1 ? MAP_ANONYMOUS : 0; - flags |= shared ? MAP_SHARED : MAP_PRIVATE; - if (shared && is_pmem) { - map_sync_flags = MAP_SYNC | MAP_SHARED_VALIDATE; - } - offset = QEMU_ALIGN_UP((uintptr_t)guardptr, align) - (uintptr_t)guardptr; - ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE, - flags | map_sync_flags, fd, 0); - - if (ptr == MAP_FAILED && map_sync_flags) { - if (errno == ENOTSUP) { - char *proc_link, *file_name; - int len; - proc_link = g_strdup_printf("/proc/self/fd/%d", fd); - file_name = g_malloc0(PATH_MAX); - len = readlink(proc_link, file_name, PATH_MAX - 1); - if (len < 0) { - len = 0; - } - file_name[len] = '\0'; - fprintf(stderr, "Warning: requesting persistence across crashes " - "for backend file %s failed. Proceeding without " - "persistence, data might become corrupted in case of host " - "crash.\n", file_name); - g_free(proc_link); - g_free(file_name); - } - /* - * if map failed with MAP_SHARED_VALIDATE | MAP_SYNC, - * we will remove these flags to handle compatibility. - */ - ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE, - flags, fd, 0); - } - + ptr = mmap_activate(guardptr + offset, size, fd, shared, is_pmem); if (ptr == MAP_FAILED) { munmap(guardptr, total); return MAP_FAILED; From patchwork Thu Mar 5 14:29:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1249634 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=X4ORHxKo; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YD1G3DL9z9sPg for ; Fri, 6 Mar 2020 01:40:02 +1100 (AEDT) Received: from localhost ([::1]:50410 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rfM-00055x-AJ for incoming@patchwork.ozlabs.org; Thu, 05 Mar 2020 09:40:00 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35789) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rXx-0000QZ-IX for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:22 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9rXw-0003O4-6l for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:21 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:41326 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j9rXw-0003N6-2N for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583418739; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2eknTrxrpZwJTyM4q9bbVp/0nK/Ipyt3w1hOhR5L378=; b=X4ORHxKooLCqQOKeU5fnoQlYaaRZRXXf8jDe/OObYv1TqkiM3nclYqWP29wa4JWW45K4Jo BQpIa9i+XkaZsJuLJzvPCutqD2Cq91qaaiFlRFOoM5PL2jP60qg2TZizcM/oS4r1l0eeeX D90GLfeArConvQcr5ZbLAxj05nkX7xQ= 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-27-nFi3yssxP-akRBGnaTv5rQ-1; Thu, 05 Mar 2020 09:32:16 -0500 X-MC-Unique: nFi3yssxP-akRBGnaTv5rQ-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B40EA1005510; Thu, 5 Mar 2020 14:32:14 +0000 (UTC) Received: from t480s.redhat.com (ovpn-120-166.rdu2.redhat.com [10.10.120.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9743F91D7A; Thu, 5 Mar 2020 14:32:09 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 10/15] util/mmap-alloc: Prepare for resizeable mmaps Date: Thu, 5 Mar 2020 15:29:40 +0100 Message-Id: <20200305142945.216465-11-david@redhat.com> In-Reply-To: <20200305142945.216465-1-david@redhat.com> References: <20200305142945.216465-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Richard Henderson , Igor Kotrasinski , David Hildenbrand , "Dr . David Alan Gilbert" , Peter Xu , Greg Kurz , Murilo Opsfelder Araujo , Igor Mammedov , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" When shrinking a mmap we want to re-reserve the already activated area. When growing a memory region, we want to activate starting with a given fd_offset. Prepare by allowing to pass these parameters. Also, let's make sure we always process full pages, to avoid unmapping/remapping pages that are already in use when growing/shrinking. Add some asserts. Reviewed-by: Richard Henderson Reviewed-by: Peter Xu Cc: Igor Kotrasinski Cc: Murilo Opsfelder Araujo Cc: "Michael S. Tsirkin" Cc: Greg Kurz Cc: Murilo Opsfelder Araujo Cc: Eduardo Habkost Cc: "Dr. David Alan Gilbert" Cc: Igor Mammedov Signed-off-by: David Hildenbrand Acked-by: Murilo Opsfelder Araujo --- util/mmap-alloc.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c index 8f40ef4fed..2767caa33b 100644 --- a/util/mmap-alloc.c +++ b/util/mmap-alloc.c @@ -83,12 +83,12 @@ size_t qemu_mempath_getpagesize(const char *mem_path) } /* - * Reserve a new memory region of the requested size to be used for mapping - * from the given fd (if any). + * Reserve a new memory region of the requested size or re-reserve parts + * of an activated region to be used for mapping from the given fd (if any). */ -static void *mmap_reserve(size_t size, int fd) +static void *mmap_reserve(void *ptr, size_t size, int fd) { - int flags = MAP_PRIVATE; + int flags = MAP_PRIVATE | (ptr ? MAP_FIXED : 0); #if defined(__powerpc64__) && defined(__linux__) /* @@ -111,20 +111,24 @@ static void *mmap_reserve(size_t size, int fd) flags |= MAP_ANONYMOUS; #endif - return mmap(0, size, PROT_NONE, flags, fd, 0); + return mmap(ptr, size, PROT_NONE, flags, fd, 0); } /* * Activate memory in a reserved region from the given fd (if any), to make * it accessible. */ -static void *mmap_activate(void *ptr, size_t size, int fd, bool shared, - bool is_pmem) +static void *mmap_activate(void *ptr, size_t size, int fd, size_t fd_offset, + bool shared, bool is_pmem) { int map_sync_flags = 0; int flags = MAP_FIXED; void *activated_ptr; + if (fd == -1) { + fd_offset = 0; + } + flags |= fd == -1 ? MAP_ANONYMOUS : 0; flags |= shared ? MAP_SHARED : MAP_PRIVATE; if (shared && is_pmem) { @@ -132,7 +136,7 @@ static void *mmap_activate(void *ptr, size_t size, int fd, bool shared, } activated_ptr = mmap(ptr, size, PROT_READ | PROT_WRITE, - flags | map_sync_flags, fd, 0); + flags | map_sync_flags, fd, fd_offset); if (activated_ptr == MAP_FAILED && map_sync_flags) { if (errno == ENOTSUP) { char *proc_link = g_strdup_printf("/proc/self/fd/%d", fd); @@ -154,7 +158,8 @@ static void *mmap_activate(void *ptr, size_t size, int fd, bool shared, * If mmap failed with MAP_SHARED_VALIDATE | MAP_SYNC, we will try * again without these flags to handle backwards compatibility. */ - activated_ptr = mmap(ptr, size, PROT_READ | PROT_WRITE, flags, fd, 0); + activated_ptr = mmap(ptr, size, PROT_READ | PROT_WRITE, flags, fd, + fd_offset); } return activated_ptr; } @@ -176,16 +181,19 @@ void *qemu_ram_mmap(int fd, bool is_pmem) { const size_t guard_pagesize = mmap_guard_pagesize(fd); + const size_t pagesize = qemu_fd_getpagesize(fd); size_t offset, total; void *ptr, *guardptr; + g_assert(QEMU_IS_ALIGNED(size, pagesize)); + /* * Note: this always allocates at least one extra page of virtual address * space, even if size is already aligned. */ total = size + align; - guardptr = mmap_reserve(total, fd); + guardptr = mmap_reserve(NULL, total, fd); if (guardptr == MAP_FAILED) { return MAP_FAILED; } @@ -196,7 +204,7 @@ void *qemu_ram_mmap(int fd, offset = QEMU_ALIGN_UP((uintptr_t)guardptr, align) - (uintptr_t)guardptr; - ptr = mmap_activate(guardptr + offset, size, fd, shared, is_pmem); + ptr = mmap_activate(guardptr + offset, size, fd, 0, shared, is_pmem); if (ptr == MAP_FAILED) { munmap(guardptr, total); return MAP_FAILED; @@ -220,6 +228,10 @@ void *qemu_ram_mmap(int fd, void qemu_ram_munmap(int fd, void *ptr, size_t size) { + const size_t pagesize = qemu_fd_getpagesize(fd); + + g_assert(QEMU_IS_ALIGNED(size, pagesize)); + if (ptr) { /* Unmap both the RAM block and the guard page */ munmap(ptr, size + mmap_guard_pagesize(fd)); From patchwork Thu Mar 5 14:29:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1249615 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ZvwrFpjn; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YCvn6F0Zz9sQt for ; Fri, 6 Mar 2020 01:35:17 +1100 (AEDT) Received: from localhost ([::1]:50332 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9ral-0005Uu-GE for incoming@patchwork.ozlabs.org; Thu, 05 Mar 2020 09:35:15 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35794) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rXy-0000Sd-7N for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9rXw-0003Oq-NU for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:22 -0500 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:34147 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j9rXw-0003O9-Hj for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583418740; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MVaLnjXvJg6zL4YkvtGMVqzRgwjU5unEthNhKZGounY=; b=ZvwrFpjnrezPkQnlYmpPpwccCx7/V20I0jy2DyYgSA9N5Ws38WJPSRNmQk+OvsPK7tHY/t AzuIar20LngzjiJE/TjPJVRsZLkHPMSXK7WrRiSLLcVuyRfkLp+8NS9qWKccGnQt+oZQ0j bQUZPEdJpbZLNW3rkNhzGlklhSSutmk= 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-xdx8g9ajNhOd9JEkwZUm-w-1; Thu, 05 Mar 2020 09:32:18 -0500 X-MC-Unique: xdx8g9ajNhOd9JEkwZUm-w-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9DB9013EA; Thu, 5 Mar 2020 14:32:17 +0000 (UTC) Received: from t480s.redhat.com (ovpn-120-166.rdu2.redhat.com [10.10.120.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id 086BF90538; Thu, 5 Mar 2020 14:32:14 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 11/15] util/mmap-alloc: Implement resizeable mmaps Date: Thu, 5 Mar 2020 15:29:41 +0100 Message-Id: <20200305142945.216465-12-david@redhat.com> In-Reply-To: <20200305142945.216465-1-david@redhat.com> References: <20200305142945.216465-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 205.139.110.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Richard Henderson , Igor Kotrasinski , David Hildenbrand , "Dr . David Alan Gilbert" , Peter Xu , Greg Kurz , Murilo Opsfelder Araujo , Igor Mammedov , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Implement resizeable mmaps. For now, the actual resizing is not wired up. Introduce qemu_ram_mmap_resizeable() and qemu_ram_mmap_resize(). Make qemu_ram_mmap() a wrapper of qemu_ram_mmap_resizeable(). Reviewed-by: Peter Xu Cc: Richard Henderson Cc: Igor Kotrasinski Cc: Murilo Opsfelder Araujo Cc: "Michael S. Tsirkin" Cc: Greg Kurz Cc: Eduardo Habkost Cc: "Dr. David Alan Gilbert" Cc: Igor Mammedov Signed-off-by: David Hildenbrand Acked-by: Murilo Opsfelder Araujo --- include/qemu/mmap-alloc.h | 21 +++++++++++-------- util/mmap-alloc.c | 43 ++++++++++++++++++++++++++++----------- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h index e786266b92..ca8f7edf70 100644 --- a/include/qemu/mmap-alloc.h +++ b/include/qemu/mmap-alloc.h @@ -7,11 +7,13 @@ size_t qemu_fd_getpagesize(int fd); size_t qemu_mempath_getpagesize(const char *mem_path); /** - * qemu_ram_mmap: mmap the specified file or device. + * qemu_ram_mmap_resizeable: reserve a memory region of @max_size to mmap the + * specified file or device and mmap @size of it. * * Parameters: * @fd: the file or the device to mmap * @size: the number of bytes to be mmaped + * @max_size: the number of bytes to be reserved * @align: if not zero, specify the alignment of the starting mapping address; * otherwise, the alignment in use will be determined by QEMU. * @shared: map has RAM_SHARED flag. @@ -21,12 +23,15 @@ size_t qemu_mempath_getpagesize(const char *mem_path); * On success, return a pointer to the mapped area. * On failure, return MAP_FAILED. */ -void *qemu_ram_mmap(int fd, - size_t size, - size_t align, - bool shared, - bool is_pmem); - -void qemu_ram_munmap(int fd, void *ptr, size_t size); +void *qemu_ram_mmap_resizeable(int fd, size_t size, size_t max_size, + size_t align, bool shared, bool is_pmem); +bool qemu_ram_mmap_resize(void *ptr, int fd, size_t old_size, size_t new_size, + bool shared, bool is_pmem); +static inline void *qemu_ram_mmap(int fd, size_t size, size_t align, + bool shared, bool is_pmem) +{ + return qemu_ram_mmap_resizeable(fd, size, size, align, shared, is_pmem); +} +void qemu_ram_munmap(int fd, void *ptr, size_t max_size); #endif diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c index 2767caa33b..7ed85f16d3 100644 --- a/util/mmap-alloc.c +++ b/util/mmap-alloc.c @@ -174,11 +174,8 @@ static inline size_t mmap_guard_pagesize(int fd) #endif } -void *qemu_ram_mmap(int fd, - size_t size, - size_t align, - bool shared, - bool is_pmem) +void *qemu_ram_mmap_resizeable(int fd, size_t size, size_t max_size, + size_t align, bool shared, bool is_pmem) { const size_t guard_pagesize = mmap_guard_pagesize(fd); const size_t pagesize = qemu_fd_getpagesize(fd); @@ -186,12 +183,14 @@ void *qemu_ram_mmap(int fd, void *ptr, *guardptr; g_assert(QEMU_IS_ALIGNED(size, pagesize)); + g_assert(QEMU_IS_ALIGNED(max_size, pagesize)); /* * Note: this always allocates at least one extra page of virtual address - * space, even if size is already aligned. + * space, even if the size is already aligned. We will reserve an area of + * at least max_size, but only activate the requested part of it. */ - total = size + align; + total = max_size + align; guardptr = mmap_reserve(NULL, total, fd); if (guardptr == MAP_FAILED) { @@ -219,21 +218,41 @@ void *qemu_ram_mmap(int fd, * a guard page guarding against potential buffer overflows. */ total -= offset; - if (total > size + guard_pagesize) { - munmap(ptr + size + guard_pagesize, total - size - guard_pagesize); + if (total > max_size + guard_pagesize) { + munmap(ptr + max_size + guard_pagesize, + total - max_size - guard_pagesize); } return ptr; } -void qemu_ram_munmap(int fd, void *ptr, size_t size) +bool qemu_ram_mmap_resize(void *ptr, int fd, size_t old_size, size_t new_size, + bool shared, bool is_pmem) { const size_t pagesize = qemu_fd_getpagesize(fd); - g_assert(QEMU_IS_ALIGNED(size, pagesize)); + g_assert(QEMU_IS_ALIGNED(old_size, pagesize)); + g_assert(QEMU_IS_ALIGNED(new_size, pagesize)); + + if (old_size < new_size) { + /* activate the missing piece in the reserved area */ + ptr = mmap_activate(ptr + old_size, new_size - old_size, fd, old_size, + shared, is_pmem); + } else if (old_size > new_size) { + /* discard this piece, marking it reserved */ + ptr = mmap_reserve(ptr + new_size, old_size - new_size, fd); + } + return ptr != MAP_FAILED; +} + +void qemu_ram_munmap(int fd, void *ptr, size_t max_size) +{ + const size_t pagesize = qemu_fd_getpagesize(fd); + + g_assert(QEMU_IS_ALIGNED(max_size, pagesize)); if (ptr) { /* Unmap both the RAM block and the guard page */ - munmap(ptr, size + mmap_guard_pagesize(fd)); + munmap(ptr, max_size + mmap_guard_pagesize(fd)); } } From patchwork Thu Mar 5 14:29:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1249628 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=bP6NrN0r; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YCy13Gc1z9sRR for ; Fri, 6 Mar 2020 01:37:12 +1100 (AEDT) Received: from localhost ([::1]:50366 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rcb-0008GM-Lx for incoming@patchwork.ozlabs.org; Thu, 05 Mar 2020 09:37:09 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:35936) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rYF-0000tZ-AT for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:41 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9rYC-0003h7-Uq for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:39 -0500 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:31073 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j9rYC-0003gH-Ow for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583418755; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NgzR8p5sGdHITGt0eLFva8UxByAMeItf9wW8PoeeJIs=; b=bP6NrN0rDnlx2Y8jIu1dBWH7sTEC6VygLDfJtW8r/JIkM9rtSbml9eI9gXOX0AysxJbSRY 65LqK3hrkylJ2+XHKCZ28TcyFXRJpG66owVMx72PSxcWsVHmnv206ojYBUoX9W9CRGZ0tG kWzENVn3FX4L180C6SQ4m6llyUCU9rQ= 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-76-urTWfxLcMnCbhqFogWRJDA-1; Thu, 05 Mar 2020 09:32:31 -0500 X-MC-Unique: urTWfxLcMnCbhqFogWRJDA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 2DA9F800D50; Thu, 5 Mar 2020 14:32:30 +0000 (UTC) Received: from t480s.redhat.com (ovpn-120-166.rdu2.redhat.com [10.10.120.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id E6DC390538; Thu, 5 Mar 2020 14:32:17 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 12/15] util: vfio-helpers: Implement ram_block_resized() Date: Thu, 5 Mar 2020 15:29:42 +0100 Message-Id: <20200305142945.216465-13-david@redhat.com> In-Reply-To: <20200305142945.216465-1-david@redhat.com> References: <20200305142945.216465-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 205.139.110.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Igor Kotrasinski , David Hildenbrand , "Dr . David Alan Gilbert" , Peter Xu , Alex Williamson , Murilo Opsfelder Araujo , Igor Mammedov , Paolo Bonzini , Stefan Hajnoczi , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Let's implement ram_block_resized(), allowing resizeable mappings. For resizeable mappings, we reserve $max_size IOVA address space, but only map $size of it. When resizing, unmap the old part and remap the new part. We'll need e.g., new ioctl to do this atomically (e.g., to resize while the guest is running). Right now, we only resize RAM blocks during incoming migration (when syncing RAM block sizes during the precopy phase) or after guest resets when building acpi tables. Any future user of resizeable RAM has to be aware that vfio has to be treated with care. Reviewed-by: Peter Xu Cc: Richard Henderson Cc: Paolo Bonzini Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Alex Williamson Cc: Stefan Hajnoczi Cc: "Dr. David Alan Gilbert" Signed-off-by: David Hildenbrand Acked-by: Murilo Opsfelder Araujo --- util/trace-events | 7 ++-- util/vfio-helpers.c | 95 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 88 insertions(+), 14 deletions(-) diff --git a/util/trace-events b/util/trace-events index 83b6639018..a4d39eca5e 100644 --- a/util/trace-events +++ b/util/trace-events @@ -74,10 +74,11 @@ qemu_mutex_unlock(void *mutex, const char *file, const int line) "released mutex # vfio-helpers.c qemu_vfio_dma_reset_temporary(void *s) "s %p" -qemu_vfio_ram_block_added(void *s, void *p, size_t size) "s %p host %p size 0x%zx" -qemu_vfio_ram_block_removed(void *s, void *p, size_t size) "s %p host %p size 0x%zx" +qemu_vfio_ram_block_added(void *s, void *p, size_t size, size_t max_size) "s %p host %p size 0x%zx max_size 0x%zx" +qemu_vfio_ram_block_removed(void *s, void *p, size_t size, size_t max_size) "s %p host %p size 0x%zx max_size 0x%zx" +qemu_vfio_ram_block_resized(void *s, void *p, size_t old_size, size_t new_sizze) "s %p host %p old_size 0x%zx new_size 0x%zx" qemu_vfio_find_mapping(void *s, void *p) "s %p host %p" -qemu_vfio_new_mapping(void *s, void *host, size_t size, int index, uint64_t iova) "s %p host %p size %zu index %d iova 0x%"PRIx64 +qemu_vfio_new_mapping(void *s, void *host, size_t size, size_t max_size, int index, uint64_t iova) "s %p host %p size %zu max_size %zu index %d iova 0x%"PRIx64 qemu_vfio_do_mapping(void *s, void *host, size_t size, uint64_t iova) "s %p host %p size %zu iova 0x%"PRIx64 qemu_vfio_dma_map(void *s, void *host, size_t size, bool temporary, uint64_t *iova) "s %p host %p size %zu temporary %d iova %p" qemu_vfio_dma_unmap(void *s, void *host) "s %p host %p" diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c index f0c77f0d69..789faf38bd 100644 --- a/util/vfio-helpers.c +++ b/util/vfio-helpers.c @@ -36,6 +36,7 @@ typedef struct { /* Page aligned addr. */ void *host; size_t size; + size_t max_size; uint64_t iova; } IOVAMapping; @@ -372,14 +373,20 @@ fail_container: return ret; } +static int qemu_vfio_dma_map_resizeable(QEMUVFIOState *s, void *host, + size_t size, size_t max_size, + bool temporary, uint64_t *iova); +static void qemu_vfio_dma_map_resize(QEMUVFIOState *s, void *host, + size_t old_size, size_t new_size); + static void qemu_vfio_ram_block_added(RAMBlockNotifier *n, void *host, size_t size, size_t max_size) { QEMUVFIOState *s = container_of(n, QEMUVFIOState, ram_notifier); int ret; - trace_qemu_vfio_ram_block_added(s, host, max_size); - ret = qemu_vfio_dma_map(s, host, max_size, false, NULL); + trace_qemu_vfio_ram_block_added(s, host, size, max_size); + ret = qemu_vfio_dma_map_resizeable(s, host, size, max_size, false, NULL); if (ret) { error_report("qemu_vfio_dma_map(%p, %zu) failed: %s", host, max_size, strerror(-ret)); @@ -391,16 +398,28 @@ static void qemu_vfio_ram_block_removed(RAMBlockNotifier *n, void *host, { QEMUVFIOState *s = container_of(n, QEMUVFIOState, ram_notifier); if (host) { - trace_qemu_vfio_ram_block_removed(s, host, max_size); + trace_qemu_vfio_ram_block_removed(s, host, size, max_size); qemu_vfio_dma_unmap(s, host); } } +static void qemu_vfio_ram_block_resized(RAMBlockNotifier *n, void *host, + size_t old_size, size_t new_size) +{ + QEMUVFIOState *s = container_of(n, QEMUVFIOState, ram_notifier); + + if (host) { + trace_qemu_vfio_ram_block_resized(s, host, old_size, new_size); + qemu_vfio_dma_map_resize(s, host, old_size, new_size); + } +} + static void qemu_vfio_open_common(QEMUVFIOState *s) { qemu_mutex_init(&s->lock); s->ram_notifier.ram_block_added = qemu_vfio_ram_block_added; s->ram_notifier.ram_block_removed = qemu_vfio_ram_block_removed; + s->ram_notifier.ram_block_resized = qemu_vfio_ram_block_resized; s->low_water_mark = QEMU_VFIO_IOVA_MIN; s->high_water_mark = QEMU_VFIO_IOVA_MAX; ram_block_notifier_add(&s->ram_notifier); @@ -495,16 +514,23 @@ static IOVAMapping *qemu_vfio_find_mapping(QEMUVFIOState *s, void *host, */ static IOVAMapping *qemu_vfio_add_mapping(QEMUVFIOState *s, void *host, size_t size, - int index, uint64_t iova) + size_t max_size, int index, + uint64_t iova) { + const IOVAMapping m = { + .host = host, + .size = size, + .max_size = max_size, + .iova = iova, + }; int shift; - IOVAMapping m = {.host = host, .size = size, .iova = iova}; IOVAMapping *insert; assert(QEMU_IS_ALIGNED(size, qemu_real_host_page_size)); + assert(size <= max_size); assert(QEMU_IS_ALIGNED(s->low_water_mark, qemu_real_host_page_size)); assert(QEMU_IS_ALIGNED(s->high_water_mark, qemu_real_host_page_size)); - trace_qemu_vfio_new_mapping(s, host, size, index, iova); + trace_qemu_vfio_new_mapping(s, host, size, max_size, index, iova); assert(index >= 0); s->nr_mappings++; @@ -597,9 +623,14 @@ static bool qemu_vfio_verify_mappings(QEMUVFIOState *s) * the result in @iova if not NULL. The caller need to make sure the area is * aligned to page size, and mustn't overlap with existing mapping areas (split * mapping status within this area is not allowed). + * + * If size < max_size, a region of max_size in IOVA address is reserved, such + * that the mapping can later be resized. Resizeable mappings are only allowed + * for !temporary mappings. */ -int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, - bool temporary, uint64_t *iova) +static int qemu_vfio_dma_map_resizeable(QEMUVFIOState *s, void *host, + size_t size, size_t max_size, + bool temporary, uint64_t *iova) { int ret = 0; int index; @@ -608,19 +639,24 @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, assert(QEMU_PTR_IS_ALIGNED(host, qemu_real_host_page_size)); assert(QEMU_IS_ALIGNED(size, qemu_real_host_page_size)); + assert(QEMU_IS_ALIGNED(max_size, qemu_real_host_page_size)); + assert(size == max_size || !temporary); + assert(size <= max_size); + trace_qemu_vfio_dma_map(s, host, size, temporary, iova); qemu_mutex_lock(&s->lock); mapping = qemu_vfio_find_mapping(s, host, &index); if (mapping) { iova0 = mapping->iova + ((uint8_t *)host - (uint8_t *)mapping->host); } else { - if (s->high_water_mark - s->low_water_mark + 1 < size) { + if (s->high_water_mark - s->low_water_mark + 1 < max_size) { ret = -ENOMEM; goto out; } if (!temporary) { iova0 = s->low_water_mark; - mapping = qemu_vfio_add_mapping(s, host, size, index + 1, iova0); + mapping = qemu_vfio_add_mapping(s, host, size, max_size, index + 1, + iova0); if (!mapping) { ret = -ENOMEM; goto out; @@ -631,7 +667,7 @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, qemu_vfio_remove_mapping(s, mapping); goto out; } - s->low_water_mark += size; + s->low_water_mark += max_size; qemu_vfio_dump_mappings(s); } else { iova0 = s->high_water_mark - size; @@ -650,6 +686,12 @@ out: return ret; } +int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, + bool temporary, uint64_t *iova) +{ + return qemu_vfio_dma_map_resizeable(s, host, size, size, temporary, iova); +} + /* Reset the high watermark and free all "temporary" mappings. */ int qemu_vfio_dma_reset_temporary(QEMUVFIOState *s) { @@ -694,6 +736,37 @@ out: qemu_mutex_unlock(&s->lock); } +static void qemu_vfio_dma_map_resize(QEMUVFIOState *s, void *host, + size_t old_size, size_t new_size) +{ + IOVAMapping *m; + int index = 0; + + qemu_mutex_lock(&s->lock); + m = qemu_vfio_find_mapping(s, host, &index); + if (!m) { + return; + } + assert(m->size == old_size); + assert(new_size <= m->max_size); + + /* + * For now, we must unmap the whole mapped range first and remap with + * the new size. The reason is that VFIO_IOMMU_UNMAP_DMA might fail + * when partially unmapping previous mappings. Although we could add + * new mappings to extend the old range, we won't able to always + * shrink. The side effect is that it's never safe to resize during VM + * execution and we'll e.g., need a new IOCTL to make this work. + */ + qemu_vfio_undo_mapping(s, m->iova, m->size); + qemu_vfio_do_mapping(s, host, m->iova, new_size); + + m->size = new_size; + assert(qemu_vfio_verify_mappings(s)); + + qemu_mutex_unlock(&s->lock); +} + static void qemu_vfio_reset(QEMUVFIOState *s) { ioctl(s->device, VFIO_DEVICE_RESET); From patchwork Thu Mar 5 14:29:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1249636 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=dLVvAOBD; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YD3F0ztMz9sPK for ; Fri, 6 Mar 2020 01:41:45 +1100 (AEDT) Received: from localhost ([::1]:50458 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rh1-0007YX-1r for incoming@patchwork.ozlabs.org; Thu, 05 Mar 2020 09:41:43 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36023) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rYO-0001Bm-Qx for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9rYN-0003tl-CS for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:48 -0500 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:26600 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j9rYN-0003tZ-7v for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:47 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583418766; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rsKZZfmGf4FTjYAGcSvxDcDvtjCsMTO9zMXFazmq4nI=; b=dLVvAOBD/nZ8ykR99frX8Vw9gBV8ZOlHZ1GdqOi7A3nakhPvwoqQLP/BTzjTMV965rHVWo MLluD4Oj12Ftoc2+IfrU81XcilGNtCDym7z1jRXzI4Ah2j6p+61QIkJ5w/N7aDbNRczL2r jwcEoUuk+R7gb8dR5Ekbk5CkZQbi6+I= 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-25-SFyd3lYwP0K6PPThgbjaBQ-1; Thu, 05 Mar 2020 09:32:45 -0500 X-MC-Unique: SFyd3lYwP0K6PPThgbjaBQ-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BC82E13E6; Thu, 5 Mar 2020 14:32:43 +0000 (UTC) Received: from t480s.redhat.com (ovpn-120-166.rdu2.redhat.com [10.10.120.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id A3A4390538; Thu, 5 Mar 2020 14:32:30 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 13/15] util: oslib: Resizeable anonymous allocations under POSIX Date: Thu, 5 Mar 2020 15:29:43 +0100 Message-Id: <20200305142945.216465-14-david@redhat.com> In-Reply-To: <20200305142945.216465-1-david@redhat.com> References: <20200305142945.216465-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.81 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Stefan Weil , Igor Kotrasinski , David Hildenbrand , "Dr . David Alan Gilbert" , Peter Xu , Murilo Opsfelder Araujo , Igor Mammedov , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Introduce qemu_anon_ram_alloc_resizeable() and qemu_anon_ram_resize(). Implement them under POSIX and make them return NULL under WIN32. Under POSIX, we make use of resizeable mmaps. An implementation under WIN32 is theoretically possible AFAIK and can be added later. In qemu_anon_ram_free(), rename the size parameter to max_size, to make it clearer that we have to use the maximum size when freeing resizeable anonymous allocations. Reviewed-by: Peter Xu Cc: Richard Henderson Cc: Paolo Bonzini Cc: "Dr. David Alan Gilbert" Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Stefan Weil Cc: Igor Mammedov Signed-off-by: David Hildenbrand Acked-by: Murilo Opsfelder Araujo --- include/qemu/osdep.h | 6 +++++- util/oslib-posix.c | 37 ++++++++++++++++++++++++++++++++++--- util/oslib-win32.c | 14 ++++++++++++++ util/trace-events | 4 +++- 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 9bd3dcfd13..a1ea9e043d 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -311,8 +311,12 @@ int qemu_daemon(int nochdir, int noclose); void *qemu_try_memalign(size_t alignment, size_t size); void *qemu_memalign(size_t alignment, size_t size); void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared); +void *qemu_anon_ram_alloc_resizeable(size_t size, size_t max_size, + uint64_t *align, bool shared); +bool qemu_anon_ram_resize(void *ptr, size_t old_size, size_t new_size, + bool shared); void qemu_vfree(void *ptr); -void qemu_anon_ram_free(void *ptr, size_t size); +void qemu_anon_ram_free(void *ptr, size_t max_size); #define QEMU_MADV_INVALID -1 diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 897e8f3ba6..34b1ce74b7 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -223,16 +223,47 @@ void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment, bool shared) return ptr; } +void *qemu_anon_ram_alloc_resizeable(size_t size, size_t max_size, + uint64_t *alignment, bool shared) +{ + size_t align = QEMU_VMALLOC_ALIGN; + void *ptr = qemu_ram_mmap_resizeable(-1, size, max_size, align, shared, + false); + + if (ptr == MAP_FAILED) { + return NULL; + } + + if (alignment) { + *alignment = align; + } + + trace_qemu_anon_ram_alloc_resizeable(size, max_size, ptr); + return ptr; +} + +bool qemu_anon_ram_resize(void *ptr, size_t old_size, size_t new_size, + bool shared) +{ + bool resized = qemu_ram_mmap_resize(ptr, -1, old_size, new_size, shared, + false); + + if (resized) { + trace_qemu_anon_ram_resize(old_size, new_size, ptr); + } + return resized; +} + void qemu_vfree(void *ptr) { trace_qemu_vfree(ptr); free(ptr); } -void qemu_anon_ram_free(void *ptr, size_t size) +void qemu_anon_ram_free(void *ptr, size_t max_size) { - trace_qemu_anon_ram_free(ptr, size); - qemu_ram_munmap(-1, ptr, size); + trace_qemu_anon_ram_free(ptr, max_size); + qemu_ram_munmap(-1, ptr, max_size); } void qemu_set_block(int fd) diff --git a/util/oslib-win32.c b/util/oslib-win32.c index e9b14ab178..c034fdfe01 100644 --- a/util/oslib-win32.c +++ b/util/oslib-win32.c @@ -90,6 +90,20 @@ void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared) return ptr; } +void *qemu_anon_ram_alloc_resizeable(size_t size, size_t max_size, + uint64_t *align, bool shared) +{ + /* resizeable ram not implemented yet */ + return NULL; +} + +bool qemu_anon_ram_resize(void *ptr, size_t old_size, size_t new_size, + bool shared) +{ + /* resizeable ram not implemented yet */ + return false; +} + void qemu_vfree(void *ptr) { trace_qemu_vfree(ptr); diff --git a/util/trace-events b/util/trace-events index a4d39eca5e..24a6f1a1e1 100644 --- a/util/trace-events +++ b/util/trace-events @@ -46,8 +46,10 @@ qemu_co_mutex_unlock_return(void *mutex, void *self) "mutex %p self %p" # oslib-posix.c qemu_memalign(size_t alignment, size_t size, void *ptr) "alignment %zu size %zu ptr %p" qemu_anon_ram_alloc(size_t size, void *ptr) "size %zu ptr %p" +qemu_anon_ram_alloc_resizeable(size_t size, size_t max_size, void *ptr) "size %zu max_size %zu ptr %p" +qemu_anon_ram_resize(size_t old_size, size_t new_size, void *ptr) "old_size %zu new_size %zu ptr %p" qemu_vfree(void *ptr) "ptr %p" -qemu_anon_ram_free(void *ptr, size_t size) "ptr %p size %zu" +qemu_anon_ram_free(void *ptr, size_t max_size) "ptr %p max_size %zu" # hbitmap.c hbitmap_iter_skip_words(const void *hb, void *hbi, uint64_t pos, unsigned long cur) "hb %p hbi %p pos %"PRId64" cur 0x%lx" From patchwork Thu Mar 5 14:29:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1249631 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=dnChxLGV; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YCzL2lHQz9sSk for ; Fri, 6 Mar 2020 01:38:22 +1100 (AEDT) Received: from localhost ([::1]:50384 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rdk-0002cN-BZ for incoming@patchwork.ozlabs.org; Thu, 05 Mar 2020 09:38:20 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36120) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rYc-0001a8-I8 for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:33:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9rYb-00045b-EU for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:33:02 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:27490 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j9rYb-00045L-AJ for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:33:01 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583418781; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=57L/YlDgXaMyG4TA+L9+tcRvzuKzcdnDKDPaISIQbWE=; b=dnChxLGVSrsQYmJhsMtw6xOALbYxxXoRSsmxqDLynhkA1+p0cBHdxEFt1jOxRJoGVQCtDq rPPlqRaTruco6EhAuKDi4X3xxldHcJZJBwIw7Cr7UEctELDPlMN1qedIxk8ck/YiQ6bsBF AhkTnGnYHBUwQLRBwFhoM00cuDYQP0g= 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-159-Hbzto47mM66j6dzUIqc9cg-1; Thu, 05 Mar 2020 09:32:48 -0500 X-MC-Unique: Hbzto47mM66j6dzUIqc9cg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 6A825A4310; Thu, 5 Mar 2020 14:32:47 +0000 (UTC) Received: from t480s.redhat.com (ovpn-120-166.rdu2.redhat.com [10.10.120.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id 126F692D20; Thu, 5 Mar 2020 14:32:43 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 14/15] numa: Introduce ram_block_notifiers_support_resize() Date: Thu, 5 Mar 2020 15:29:44 +0100 Message-Id: <20200305142945.216465-15-david@redhat.com> In-Reply-To: <20200305142945.216465-1-david@redhat.com> References: <20200305142945.216465-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.120 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Igor Kotrasinski , David Hildenbrand , "Dr . David Alan Gilbert" , Peter Xu , Murilo Opsfelder Araujo , Igor Mammedov , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" We want to actually use resizeable allocations in resizeable ram blocks (IOW, make everything between used_length and max_length inaccessible) - however, not all ram block notifiers can support that. Introduce a way to detect if any registered notifier does not support resizes - ram_block_notifiers_support_resize() - which we can later use to fallback to legacy handling if a registered notifier (esp., SEV and HAX) does not support actual resizes. Reviewed-by: Peter Xu Cc: Richard Henderson Cc: Paolo Bonzini Cc: "Dr. David Alan Gilbert" Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: "Michael S. Tsirkin" Cc: Igor Mammedov Signed-off-by: David Hildenbrand Acked-by: Murilo Opsfelder Araujo --- hw/core/numa.c | 12 ++++++++++++ include/exec/ramlist.h | 1 + 2 files changed, 13 insertions(+) diff --git a/hw/core/numa.c b/hw/core/numa.c index 37ce175e13..1d5288c22c 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -914,3 +914,15 @@ void ram_block_notify_resize(void *host, size_t old_size, size_t new_size) } } } + +bool ram_block_notifiers_support_resize(void) +{ + RAMBlockNotifier *notifier; + + QLIST_FOREACH(notifier, &ram_list.ramblock_notifiers, next) { + if (!notifier->ram_block_resized) { + return false; + } + } + return true; +} diff --git a/include/exec/ramlist.h b/include/exec/ramlist.h index 293c0ddabe..ac5811be96 100644 --- a/include/exec/ramlist.h +++ b/include/exec/ramlist.h @@ -79,6 +79,7 @@ void ram_block_notifier_remove(RAMBlockNotifier *n); void ram_block_notify_add(void *host, size_t size, size_t max_size); void ram_block_notify_remove(void *host, size_t size, size_t max_size); void ram_block_notify_resize(void *host, size_t old_size, size_t new_size); +bool ram_block_notifiers_support_resize(void); void ram_block_dump(Monitor *mon); From patchwork Thu Mar 5 14:29:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 1249616 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=UjGo08kC; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YCwp0vhlz9sQt for ; Fri, 6 Mar 2020 01:36:10 +1100 (AEDT) Received: from localhost ([::1]:50344 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rbc-0006gn-0d for incoming@patchwork.ozlabs.org; Thu, 05 Mar 2020 09:36:08 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36098) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j9rYZ-0001T9-Or for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:33:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j9rYY-00043Z-0g for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:59 -0500 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:24835 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j9rYX-00043R-Sx for qemu-devel@nongnu.org; Thu, 05 Mar 2020 09:32:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583418777; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OsFV3KXnft3QAx4jh0JvkZ2E+L4aGeQs3QCbGBQNM1E=; b=UjGo08kChPo/R52TV63VHRpfsPq5WzsLD2ear+L6Oov8EePduxYF2HHGWTxVlJ7E1suui7 /UVA8LPPU4jxz4Jd+8J3mYTc5VFcI4KZ/19x9gwBm18Rx9BGOIl0C7IECGudYhEvKDsPsa Tab6b08e7VbOjF8J9tcGUIn4IV7YOmU= 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-329-ObxFzLjVM2WyJBHYKa-EFg-1; Thu, 05 Mar 2020 09:32:53 -0500 X-MC-Unique: ObxFzLjVM2WyJBHYKa-EFg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 32832108BCAE; Thu, 5 Mar 2020 14:32:52 +0000 (UTC) Received: from t480s.redhat.com (ovpn-120-166.rdu2.redhat.com [10.10.120.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id 141E191D7A; Thu, 5 Mar 2020 14:32:47 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Subject: [PATCH v4 15/15] exec: Ram blocks with resizeable anonymous allocations under POSIX Date: Thu, 5 Mar 2020 15:29:45 +0100 Message-Id: <20200305142945.216465-16-david@redhat.com> In-Reply-To: <20200305142945.216465-1-david@redhat.com> References: <20200305142945.216465-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 207.211.31.81 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S . Tsirkin" , Stefan Weil , Igor Kotrasinski , David Hildenbrand , "Dr . David Alan Gilbert" , Peter Xu , Shameerali Kolothum Thodi , Murilo Opsfelder Araujo , Igor Mammedov , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" We can now make use of resizeable anonymous allocations to implement actually resizeable ram blocks. Resizeable anonymous allocations are not implemented under WIN32 yet and are not available when using alternative allocators. Fall back to the existing handling. We also have to fallback to the existing handling in case any ram block notifier does not support resizing (esp., AMD SEV, HAX) yet. Remember in RAM_RESIZEABLE_ALLOC if we are using resizeable anonymous allocations. Try to grow early, as that can easily fail if out of memory. Shrink late and ignore errors (nothing will actually break). Warn only. The benefit of actually resizeable ram blocks is that e.g., under Linux, only the actual size will be reserved (even if "/proc/sys/vm/overcommit_memory" is set to "never"). Additional memory will be reserved when trying to resize, which allows to have ram blocks that start small but can theoretically grow very large. Note1: We are not able to create resizeable ram blocks with pre-allocated memory yet, so prealloc is not affected. Note2: mlock should work as it used to as os_mlock() does a mlockall(MCL_CURRENT | MCL_FUTURE), which includes future mappings. Note3: Nobody should access memory beyond used_length. Memory notifiers already properly take care of this, only ram block notifiers violate this constraint and, therefore, have to be special-cased. Especially, any ram block notifier that might dynamically register at runtime (e.g., vfio) has to support resizes. Add an assert for that. Both, HAX and SEV register early, so they are fine. Reviewed-by: Peter Xu Cc: Richard Henderson Cc: Paolo Bonzini Cc: "Dr. David Alan Gilbert" Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Stefan Weil Cc: Igor Mammedov Cc: Shameerali Kolothum Thodi Signed-off-by: David Hildenbrand Acked-by: Murilo Opsfelder Araujo --- exec.c | 65 ++++++++++++++++++++++++++++++++++++--- hw/core/numa.c | 7 +++++ include/exec/cpu-common.h | 2 ++ include/exec/memory.h | 8 +++++ 4 files changed, 77 insertions(+), 5 deletions(-) diff --git a/exec.c b/exec.c index 9c3cc79193..6c6b6e12d2 100644 --- a/exec.c +++ b/exec.c @@ -2001,6 +2001,16 @@ void qemu_ram_unset_migratable(RAMBlock *rb) rb->flags &= ~RAM_MIGRATABLE; } +bool qemu_ram_is_resizeable(RAMBlock *rb) +{ + return rb->flags & RAM_RESIZEABLE; +} + +bool qemu_ram_is_resizeable_alloc(RAMBlock *rb) +{ + return rb->flags & RAM_RESIZEABLE_ALLOC; +} + /* Called with iothread lock held. */ void qemu_ram_set_idstr(RAMBlock *new_block, const char *name, DeviceState *dev) { @@ -2094,6 +2104,7 @@ static void qemu_ram_apply_settings(void *host, size_t length) */ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp) { + const bool shared = block->flags & RAM_SHARED; const ram_addr_t oldsize = block->used_length; assert(block); @@ -2104,7 +2115,7 @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp) return 0; } - if (!(block->flags & RAM_RESIZEABLE)) { + if (!qemu_ram_is_resizeable(block)) { error_setg_errno(errp, EINVAL, "Length mismatch: %s: 0x" RAM_ADDR_FMT " in != 0x" RAM_ADDR_FMT, block->idstr, @@ -2120,6 +2131,15 @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp) return -EINVAL; } + if (oldsize < newsize && qemu_ram_is_resizeable_alloc(block)) { + if (!qemu_anon_ram_resize(block->host, oldsize, newsize, shared)) { + error_setg_errno(errp, -ENOMEM, "Cannot allocate enough memory."); + return -ENOMEM; + } + /* apply settings for the newly accessible memory */ + qemu_ram_apply_settings(block->host + oldsize, newsize - oldsize); + } + /* Notify before modifying the ram block and touching the bitmaps. */ if (block->host) { ram_block_notify_resize(block->host, oldsize, newsize); @@ -2133,6 +2153,16 @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp) if (block->resized) { block->resized(block->idstr, newsize, block->host); } + + /* + * Shrinking will only fail in rare scenarios (e.g., maximum number of + * mappings reached), and can be ignored. Warn only. + */ + if (newsize < oldsize && qemu_ram_is_resizeable_alloc(block) && + !qemu_anon_ram_resize(block->host, oldsize, newsize, shared)) { + warn_report("Shrinking memory allocation failed."); + } + return 0; } @@ -2211,6 +2241,29 @@ static void dirty_memory_extend(ram_addr_t old_ram_size, } } +static void ram_block_alloc_ram(RAMBlock *rb) +{ + const bool shared = qemu_ram_is_shared(rb); + + assert(!(rb->flags & RAM_RESIZEABLE_ALLOC)); + /* + * If we can, try to allocate actually resizeable ram. Will also fail + * if qemu_anon_ram_alloc_resizeable() is not implemented. + */ + if (phys_mem_alloc == qemu_anon_ram_alloc && + qemu_ram_is_resizeable(rb) && + ram_block_notifiers_support_resize()) { + rb->host = qemu_anon_ram_alloc_resizeable(rb->used_length, + rb->max_length, + &rb->mr->align, shared); + if (rb->host) { + rb->flags |= RAM_RESIZEABLE_ALLOC; + return; + } + } + rb->host = phys_mem_alloc(rb->max_length, &rb->mr->align, shared); +} + static void ram_block_add(RAMBlock *new_block, Error **errp) { RAMBlock *block; @@ -2233,9 +2286,7 @@ static void ram_block_add(RAMBlock *new_block, Error **errp) return; } } else { - new_block->host = phys_mem_alloc(new_block->max_length, - &new_block->mr->align, - qemu_ram_is_shared(new_block)); + ram_block_alloc_ram(new_block); if (!new_block->host) { error_setg_errno(errp, errno, "cannot set up guest memory '%s'", @@ -2280,7 +2331,11 @@ static void ram_block_add(RAMBlock *new_block, Error **errp) DIRTY_CLIENTS_ALL); if (new_block->host) { - qemu_ram_apply_settings(new_block->host, new_block->max_length); + if (qemu_ram_is_resizeable_alloc(new_block)) { + qemu_ram_apply_settings(new_block->host, new_block->used_length); + } else { + qemu_ram_apply_settings(new_block->host, new_block->max_length); + } ram_block_notify_add(new_block->host, new_block->used_length, new_block->max_length); } diff --git a/hw/core/numa.c b/hw/core/numa.c index 1d5288c22c..c547549e49 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -862,6 +862,13 @@ static int ram_block_notify_add_single(RAMBlock *rb, void *opaque) RAMBlockNotifier *notifier = opaque; if (host) { + /* + * Dynamically adding notifiers that don't support resizes is forbidden + * when dealing with resizeable ram blocks that have actually resizeable + * allocations. + */ + g_assert(!qemu_ram_is_resizeable_alloc(rb) || + notifier->ram_block_resized); notifier->ram_block_added(notifier, host, size, max_size); } return 0; diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index 09decb8d93..aacbf33b85 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -66,6 +66,8 @@ void qemu_ram_set_uf_zeroable(RAMBlock *rb); bool qemu_ram_is_migratable(RAMBlock *rb); void qemu_ram_set_migratable(RAMBlock *rb); void qemu_ram_unset_migratable(RAMBlock *rb); +bool qemu_ram_is_resizeable(RAMBlock *rb); +bool qemu_ram_is_resizeable_alloc(RAMBlock *rb); size_t qemu_ram_pagesize(RAMBlock *block); size_t qemu_ram_pagesize_largest(void); diff --git a/include/exec/memory.h b/include/exec/memory.h index b9b9470a56..74805dd448 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -129,6 +129,14 @@ typedef struct IOMMUNotifier IOMMUNotifier; /* RAM is a persistent kind memory */ #define RAM_PMEM (1 << 5) +/* + * Implies RAM_RESIZEABLE. Memory beyond the used_length is inaccessible + * (esp. initially and after resizing). For such memory blocks, only the + * used_length is reserved in the OS - resizing might fail. Will only be + * used with host OS support and if all ram block notifiers support resizing. + */ +#define RAM_RESIZEABLE_ALLOC (1 << 6) + static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn, IOMMUNotifierFlag flags, hwaddr start, hwaddr end,