From patchwork Mon Jan 16 15:51:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Butsykin X-Patchwork-Id: 9519847 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 82D5A6020B for ; Tue, 17 Jan 2017 03:26:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 651582840B for ; Tue, 17 Jan 2017 03:26:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 56C3F2848E; Tue, 17 Jan 2017 03:26:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAD_ENC_HEADER,BAYES_00, DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 5874B2840B for ; Tue, 17 Jan 2017 03:26:48 +0000 (UTC) Received: from localhost ([::1]:60992 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cTKQ3-0005ya-C4 for patchwork-qemu-devel@patchwork.kernel.org; Mon, 16 Jan 2017 22:26:47 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52038) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cTKPg-0005yK-Pu for qemu-devel@nongnu.org; Mon, 16 Jan 2017 22:26:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cTKPd-0001BV-Hp for qemu-devel@nongnu.org; Mon, 16 Jan 2017 22:26:24 -0500 Received: from mail-db5eur01on0102.outbound.protection.outlook.com ([104.47.2.102]:58294 helo=EUR01-DB5-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cTKPc-0001B9-Ob for qemu-devel@nongnu.org; Mon, 16 Jan 2017 22:26:21 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=JRdVc6ReDcf6jdZct2BdpG/P3os9DCR6KPhVxdRjPVU=; b=Jyr/inPhMS5o2xZzJ6hFozliwuuxI8a+AiqNq4fLrP+LmtQqVhrNZvG+qYYC9KNI/oMYKORYQPq5P3s8kEdJE9ugWJBdVDWU9+JL7Rkdxugp2myWO4M963qSl7EvJpHnbQ/QDqQhhlKPDpiYyED9qXA8OVgNjjnREFPQu+nhvQ8= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=pbutsykin@virtuozzo.com; Received: from pavelb-Z68P-DS3.sw.ru (195.214.232.6) by VI1PR0802MB2557.eurprd08.prod.outlook.com (10.172.255.135) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.845.12; Mon, 16 Jan 2017 15:51:35 +0000 From: Pavel Butsykin To: Date: Mon, 16 Jan 2017 18:51:12 +0300 Message-ID: <20170116155113.21034-2-pbutsykin@virtuozzo.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170116155113.21034-1-pbutsykin@virtuozzo.com> References: <20170116155113.21034-1-pbutsykin@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: VI1PR0501CA0012.eurprd05.prod.outlook.com (10.172.9.150) To VI1PR0802MB2557.eurprd08.prod.outlook.com (10.172.255.135) X-MS-Office365-Filtering-Correlation-Id: 3155f4f0-de37-4b12-5ad8-08d43e278d15 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:VI1PR0802MB2557; X-Microsoft-Exchange-Diagnostics: 1; VI1PR0802MB2557; 3:z69dCLoEsQS8+TvOqy9pfPDgGU/3ye0URpsF+y7v+yrsYD2nNDVXIKQTHFeR77mAUCTg04tLc7y8Uewi3kJkKfX5tJxU6UgUfJpKJIxIZMmoknY7/Ro7+XIgi7XsFJRcRQKjeJm0D42h35x3bWQZIU5trrAN4r1a2oQ4OzlH0iO1jCswB8KwHIsmdEMeYnqSLYn54anN/FOx6G3idwR9fHfFJZeBgQqw4xFxRJm9cvC2aZKEtzfyYO8+YVV0j+KuRQNzrTnpDuKMV3IgYsmuGg== X-Microsoft-Exchange-Diagnostics: 1; VI1PR0802MB2557; 25:xVymo5Hae/ygYvKDGODq6JWyBWyclt1hzhNuFvzVm0wiYl6FOfD8Y8dZPv0nYg/OKtoenzOdYRwxmMYfZjjUrkzSkyJiwKJ2gcQzSQvtZteQwL5oUqY/5z3JJwBajf3rcoRk5gDmyv+qPpraolwYtXzHXpzKFWnIz17fYXkU/3pQX0UhvOnZhkr82uc3LxjagA5JScJxqVWCn+a28dLAHDAXvv9emxaRnK3yF/ON2lKbbw7t7/XYaPs+NWfGWN8gjqp+CXYWUiosIeBPRktV0B+CY5ONtX+4ui/JGqLXunhVe8/+28rtsViQteSSuLeuxU2vLe6QMSeyqpe8Wo5k7YHWkjZWa4kdxS4MjVfvL5BI43dpUIGP07FciJgJbBEk/c/wTdCcFiwH1MHlHGqehfchaK8dTWpHAsJGSXwlkm8yry3EXcP4R1uc/4WQ5fsWvD38zFmuoexVSPM6yFlw+J0mD62Uf3TMO/ccngK6DW/v6ctSDrdllFkVjkyY411Va5tU2L7IWdopbS3FSHXOexIZg1RLj5t79isrhlt2DyMqb4EKJpuKyfHsiAvKMk6B10uokckkfjANv+idUTW1AbJxGrzpRLkcjAOD7UzV8WHAhNI2TM8UJiBZFNpSA7iI8ryGYz/fcONPIuUGSa/hQbkmqcGO+9NleennVjxs6v9tTDGQHYNNO8u/OrpYWDGvWouYGfQ+dPQW4mr6eULzngNMFoAFubzNi6WAZ+OQV2WAL07dRai3hZKDI07yvqNY X-Microsoft-Exchange-Diagnostics: 1; VI1PR0802MB2557; 31:la2qsRJJJDOOfC8BQZv6jxBPu5kUbmGLBcSAIWKfvm4gsp7G/ROXYD/cqf940RrBPT0+Akx5+D4sXa9DSdoZ4s0CdcgWx797kDwconWk8t3/O8iGg3xKz0/pXaW+Hz3BFB8G6lewHegRDT93XTpOMbzWBW+esVkzY/2T87gVY/Jud2OHUBytS+1YgxxQ5UclqWY2J4023WbBFKrs1FLp1KK5vVzuK6nls8juphegqwT40L2Ugr65xzvYLgcjSBIk; 20:Mxf70qHGP9+unMPZ3GU6leRgtMR3TcNGWYIpbPYvQ+2cNyinz0pfdRe4bHxEAuy6Q8DWwIAiXPkC0TrEOP1EcVsJefYdjX+OY89hxx+rzps2sh7BaU6CYz6xwLt3hosy2t0CTJWqrX407MoTNLH34rPj9faEeAleNhUnmLrZZC/8nppCqyPN//DmmpXrnTh805TOr2qR2hEn1CZoiOkuG+lOdwTDJ74VgU87HiLTiczq3jI71vFxgTjeQN7i7r0S X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6041248)(20161123560025)(20161123558021)(20161123555025)(20161123562025)(20161123564025)(6072148); SRVR:VI1PR0802MB2557; BCL:0; PCL:0; RULEID:; SRVR:VI1PR0802MB2557; X-Microsoft-Exchange-Diagnostics: 1; VI1PR0802MB2557; 4:Vr+PMdYdYBA2DlP7/WaNDQyr2pMRqEsm75HToHOE/kVa25B7G1bSA5P7BRlrtMh/oxnr/7Y7p/KpGDABHgKjuH1BWO5PAd/jRKD5KAHPyKSnhHHpo3Vwq8RdItnO5HTTV0uBvsi7QEKYuDWR90WqkrplTWOjqmlwfqPRKBqVeT3A5Rwh4zl4K1Iyokk0+2rcyBGrNhXnaE2lq2BkTBHAuo/6p/Dx4XJAEGlq4806ubZF1I/aPVVPWAmtvaKddV/k/jmHba2JuZViuk76FLYkQIwecXBpb3ORG4WajcV+gCKKfWyVUZ+ont/M1Qq4rbbeIpt5w4TB30RthiX7tFxZWvdcm5JEjhmOyKuIhsR59MxxUAWEqrQw8GXS7OpT+NxCBnwWUSfI1i4ff7umaSm3ozTKKUGwf5ARyPWUpvvLiKYRZcnqBgRt51Roy1aegHuzifJzzjUUSVhWNzFtrDPS5dCIbOBdxyJEr9qI+MSmFkfhYoBh6saGmX8LSXkCte2tNXZ2JvcNcEm0xjPkgaIR32PlHW02b9zSiI38sclpRvsiHDVlKe3n55m5h+q/fv12T7SS9vyyL/4zzixauepGR/ETi7SnJyopKmWQ7zerm7M= X-Forefront-PRVS: 01894AD3B8 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(7916002)(39450400003)(39830400002)(39410400002)(189002)(199003)(50226002)(5003940100001)(36756003)(54906002)(305945005)(8676002)(6506006)(105586002)(81156014)(81166006)(42186005)(2351001)(7736002)(53416004)(48376002)(97736004)(27001)(6916009)(2950100002)(110136003)(4001430100002)(92566002)(47776003)(69596002)(1076002)(68736007)(6116002)(3846002)(107886002)(4326007)(2906002)(101416001)(189998001)(5660300001)(33646002)(6486002)(106356001)(66066001)(6512007)(6666003)(50466002)(86362001)(575784001)(50986999)(76176999)(25786008)(38730400001); DIR:OUT; SFP:1102; SCL:1; SRVR:VI1PR0802MB2557; H:pavelb-Z68P-DS3.sw.ru; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; VI1PR0802MB2557; 23:QGyEsPMvYjbPxDfsFREIivCPDnuZNQSCMzRmkZQ?= =?us-ascii?Q?9OoncQI+L+/xm4Kpst/KiuK32HCJRrJX/PV8hF/dcFCeYyzCsuG5nhh3PNR4?= =?us-ascii?Q?Uf7FEpQygjaVnKZHrbUOZ5Og6kvEePs1k1z5alOHZ7tyJ/Szm/3bFyk8rXt6?= =?us-ascii?Q?LhK6aFYHod+gh6iO0UJspZ6JJL7m4k6vL8VdhQRb3utuHGjIbUxkl4GfqdZA?= =?us-ascii?Q?pOrXg838wu/vZ4+KfjRshOQhof9Tkq3X/FAJCuAFVwkAeL+UB0Syw6zkptfs?= =?us-ascii?Q?mX0F7dtVlmzrmtSsOTX5Rgw9ys2sDUcRQqUE5CYS/8hmea4y4uueJchrU+Im?= =?us-ascii?Q?xR5Ex45SBag6fzWlADCPTrDGxQDp/DqEG6FyThIOG2Gk+/yRFZt2qZVGlyTL?= =?us-ascii?Q?jbBUxIbDxGh6ggrseQ2tTJRJOf54YYCnSQpu7w2cYpnblOxcHrzyS/sBkUkb?= =?us-ascii?Q?9jd//WXYELtBOla+OuWJOGkO3sI+aOk1McKBD3qKvYcvT6SB8Uq7n+YED7+l?= =?us-ascii?Q?aitCxgfSm5DO5RjBofI3YnUOishKYJ2afFu63+Dkcn7zMc+B6l+4dZLerX4a?= =?us-ascii?Q?SznbS/s/h4C39UBuRmcljyS010QvbFUkgJ1xreUXOcX29LzZ6y5MvsWVfZMA?= =?us-ascii?Q?665LOsV51SMn6/tU25PypOwBhydVMawo+mUIbXcM8qScOiZW6AAMrDxbvG1G?= =?us-ascii?Q?+0bLKH8RBHt2YRBgPFLC1JR+2n7A5O2ODHEWl1fim+R9NlJYURka6CMP6+fH?= =?us-ascii?Q?TmepvrsgC8KkFeuI6wamc6fgKsia03PG4JLpjfaR5NInCzxQLa0LPKydLXgf?= =?us-ascii?Q?Zp/RymulSdFJrz1hUJ6pDQGwHMvllozBVs1FpEzpi2E42x5ew1XTcrknLVdW?= =?us-ascii?Q?daC3HC0PbnAuEA2LYe/p/8tX/tIs2iRWKH7El/O/FtQtT5g+jsEKxtrB4Gbt?= =?us-ascii?Q?DmYLLi/Gsobq6d2w+k3KSBCi/T07XBn5WDFpu6QS/G3dkTj8kWBG3ZpOF0M4?= =?us-ascii?Q?uC4sMSMTmwj1kyfZU2TZOY4/bORiiv3nsTTGpqKLhciCX2X5SuZnfRoK9lro?= =?us-ascii?Q?vToc2Dgkt6QN3JxvLDVaN33w4JCZArAHmp0/8Ugtbar9dT1eQthbjkeH2sGE?= =?us-ascii?Q?Pe0jeWIg47dKTEzUy0uLDARPrDomB/gL73ZcDjQHHfmOOVDh3BMyp2deCcjq?= =?us-ascii?Q?6rTBiz3najfLcooWXpARFE1bZbvX2ecvG+BgpItisoy0zU3ETERq/yAgwXW9?= =?us-ascii?Q?LjXPSCWbeVmOcvm70S1qgyhOzUMIX9MBri+sKZGqPw/TOg2sKVUNj1wDGcCQ?= =?us-ascii?Q?eG35U2uy+PoNIfabV5ynU58c=3D?= X-Microsoft-Exchange-Diagnostics: 1; VI1PR0802MB2557; 6:ukYlrpFMYFqLyKoU/3MisLZgMl5DeDDLbFw8G7HVJngJAU3eZgHRvqZi0Hn7yUa34hi/zI8DuE8OEHsJaQwTxpKplppy/h2YIatpxJ5OF4x7fHILxmP5ihUJAgPbmDH3s90ivIbK2TxuhITWfaXLd321S5QxBzY1kG52dNqYc+YeXsro6HQzZx5MBUPmTJYKqnRfW3X/INnHgEGtjdxybI1rBA4moRoObHamgr0Bn7WRR1gmb3krRF+E3V0PHvbsmQe3aaY5fRC4vw0MFaAz90HB3/LR6HbGwHv9D90YAe+19YUwD1hfpqswn1zJSfSgWphysR8SiacG1OplsGnKc4R76f/Xt2WY2UNCQUIQUjwEMQSuAqDDByBdPdRlUISI6QvCezAdyv0585HVuM2HmhoGfWclg7egqtWc8i2tRQ0=; 5:pHQy/oCFqMVZLKepVnXLrS0jJr37aAazDCEZFSR7zgPtOIcjfAnCMh+rfSExXJhOWh2h6NzYerxyX92RIgu8I5ol4ur0M57npocrmbl1MttQigS3b2jrfQ+YhddM/5VEOPZ8lS0v5YSnTbQC+YK/OA==; 24:payo/vtADfhhpNDQ00WVKDlmM9nUnz+VoS874coI22NP2FFXmlMCwgBhudxcvktBeikqxVgGx6ftc43r8wIkSROi4zCWhVcdZ8jkk1mgd/0= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; VI1PR0802MB2557; 7:1Jay/M5fZ/T7FFd0d6rSPSGTrE1e9u5/Dc5JjvPNTf9pLDi6NAh2X9+oats0hb6+UWGl249jbCnPJAe8YxUsiKJxwMoiucOyoNdtm5rUj1uNY4S8tUqusuf8ExvIJ2a6usGId34mYbGy+nlw89GViQLhB/5n6ATKQVnVnnGNdwY0Yq13leLjqPSHUK61qZemvgEn/0jd0OKMUGia2wYqhnw7K0X/OtVBO6/FlEcmWhjdmnt3t1PwUKIhH38JqluE0J4NFX8ca52xNv83Ih0CKBbnSS8m50L5t8uDUVXjSkveZjI3SNuRVdfnuwy4tQwbaYTkcDYtREQEVlESl3gscTXeeooVLHRJt2pQhSvtlDzi5iqyhME3ri3MftAuLQjAVYhqF13v/ar3tnhbOLkMbR2NpreLdj1ATaMkBgdTskI79mps+6n8CDgvZZXmX+F0HWGf+H5/3D6u6WavhJpIJg==; 20:NxHsmSsYuZdU3Tg9MxCw1P8e5Q0dXO5urG72866vvqTDkSDEogufRI2YUCgqylGqloF0Ph4G6R18tpXwcYRuq8i9RZzMVlM4HhYHWo1XoYG1zt1EHumXo8csuci/qL+eFOroGcUWdZnIoJ4HJwgzLrWiCFkUAXUlmDbjHR3cfNQ= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Jan 2017 15:51:35.2641 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0802MB2557 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 104.47.2.102 Subject: [Qemu-devel] [PATCH 1/2] add 'discard-ram' migrate capability X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: pbutsykin@virtuozzo.com, quintela@redhat.com, armbru@redhat.com, amit.shah@redhat.com, den@openvz.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This feature frees the migrated memory on the source during postcopy-ram migration. In the second step of postcopy-ram migration when the source vm is put on pause we can free unnecessary memory. It will allow, in particular, to start relaxing the memory stress on the source host in a load-balancing scenario. Signed-off-by: Pavel Butsykin --- include/migration/migration.h | 1 + include/migration/qemu-file.h | 3 ++- migration/migration.c | 9 +++++++ migration/qemu-file.c | 59 ++++++++++++++++++++++++++++++++++++++----- migration/ram.c | 24 +++++++++++++++++- qapi-schema.json | 5 +++- 6 files changed, 91 insertions(+), 10 deletions(-) diff --git a/include/migration/migration.h b/include/migration/migration.h index c309d23370..d7bd404365 100644 --- a/include/migration/migration.h +++ b/include/migration/migration.h @@ -294,6 +294,7 @@ void migrate_add_blocker(Error *reason); */ void migrate_del_blocker(Error *reason); +bool migrate_discard_ram(void); bool migrate_postcopy_ram(void); bool migrate_zero_blocks(void); diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h index abedd466c9..0cd648a733 100644 --- a/include/migration/qemu-file.h +++ b/include/migration/qemu-file.h @@ -132,7 +132,8 @@ void qemu_put_byte(QEMUFile *f, int v); * put_buffer without copying the buffer. * The buffer should be available till it is sent asynchronously. */ -void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, size_t size); +void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, size_t size, + bool may_free); bool qemu_file_mode_is_not_valid(const char *mode); bool qemu_file_is_writable(QEMUFile *f); diff --git a/migration/migration.c b/migration/migration.c index f498ab84f2..391db6f28b 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1251,6 +1251,15 @@ void qmp_migrate_set_downtime(double value, Error **errp) qmp_migrate_set_parameters(&p, errp); } +bool migrate_discard_ram(void) +{ + MigrationState *s; + + s = migrate_get_current(); + + return s->enabled_capabilities[MIGRATION_CAPABILITY_DISCARD_RAM]; +} + bool migrate_postcopy_ram(void) { MigrationState *s; diff --git a/migration/qemu-file.c b/migration/qemu-file.c index e9fae31158..f85a0ecd9e 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c @@ -30,6 +30,7 @@ #include "qemu/coroutine.h" #include "migration/migration.h" #include "migration/qemu-file.h" +#include "sysemu/sysemu.h" #include "trace.h" #define IO_BUF_SIZE 32768 @@ -49,6 +50,7 @@ struct QEMUFile { int buf_size; /* 0 when writing */ uint8_t buf[IO_BUF_SIZE]; + DECLARE_BITMAP(may_free, MAX_IOV_SIZE); struct iovec iov[MAX_IOV_SIZE]; unsigned int iovcnt; @@ -132,6 +134,40 @@ bool qemu_file_is_writable(QEMUFile *f) return f->ops->writev_buffer; } +static void qemu_iovec_discard_ram(QEMUFile *f) +{ + struct iovec iov; + unsigned long idx; + + if (!migrate_discard_ram() || !runstate_check(RUN_STATE_FINISH_MIGRATE)) { + return; + } + + idx = find_next_bit(f->may_free, f->iovcnt, 0); + if (idx >= f->iovcnt) { + return; + } + iov = f->iov[idx]; + + while ((idx = find_next_bit(f->may_free, f->iovcnt, idx + 1)) < f->iovcnt) { + /* check for adjacent buffer and coalesce them */ + if (iov.iov_base + iov.iov_len == f->iov[idx].iov_base) { + iov.iov_len += f->iov[idx].iov_len; + continue; + } + if (qemu_madvise(iov.iov_base, iov.iov_len, QEMU_MADV_DONTNEED) < 0) { + error_report("migrate: madvise DONTNEED failed %p %ld: %s", + iov.iov_base, iov.iov_len, strerror(errno)); + } + iov = f->iov[idx]; + } + if (qemu_madvise(iov.iov_base, iov.iov_len, QEMU_MADV_DONTNEED) < 0) { + error_report("migrate: madvise DONTNEED failed %p %ld: %s", + iov.iov_base, iov.iov_len, strerror(errno)); + } + memset(f->may_free, 0, sizeof(f->may_free)); +} + /** * Flushes QEMUFile buffer * @@ -151,6 +187,8 @@ void qemu_fflush(QEMUFile *f) if (f->iovcnt > 0) { expect = iov_size(f->iov, f->iovcnt); ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt, f->pos); + + qemu_iovec_discard_ram(f); } if (ret >= 0) { @@ -304,13 +342,19 @@ int qemu_fclose(QEMUFile *f) return ret; } -static void add_to_iovec(QEMUFile *f, const uint8_t *buf, size_t size) +static void add_to_iovec(QEMUFile *f, const uint8_t *buf, size_t size, + bool may_free) { /* check for adjacent buffer and coalesce them */ if (f->iovcnt > 0 && buf == f->iov[f->iovcnt - 1].iov_base + - f->iov[f->iovcnt - 1].iov_len) { + f->iov[f->iovcnt - 1].iov_len && + may_free == test_bit(f->iovcnt - 1, f->may_free)) + { f->iov[f->iovcnt - 1].iov_len += size; } else { + if (may_free) { + set_bit(f->iovcnt, f->may_free); + } f->iov[f->iovcnt].iov_base = (uint8_t *)buf; f->iov[f->iovcnt++].iov_len = size; } @@ -320,14 +364,15 @@ static void add_to_iovec(QEMUFile *f, const uint8_t *buf, size_t size) } } -void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, size_t size) +void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, size_t size, + bool may_free) { if (f->last_error) { return; } f->bytes_xfer += size; - add_to_iovec(f, buf, size); + add_to_iovec(f, buf, size, may_free); } void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size) @@ -345,7 +390,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size) } memcpy(f->buf + f->buf_index, buf, l); f->bytes_xfer += l; - add_to_iovec(f, f->buf + f->buf_index, l); + add_to_iovec(f, f->buf + f->buf_index, l, false); f->buf_index += l; if (f->buf_index == IO_BUF_SIZE) { qemu_fflush(f); @@ -366,7 +411,7 @@ void qemu_put_byte(QEMUFile *f, int v) f->buf[f->buf_index] = v; f->bytes_xfer++; - add_to_iovec(f, f->buf + f->buf_index, 1); + add_to_iovec(f, f->buf + f->buf_index, 1, false); f->buf_index++; if (f->buf_index == IO_BUF_SIZE) { qemu_fflush(f); @@ -647,7 +692,7 @@ ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size, } qemu_put_be32(f, blen); if (f->ops->writev_buffer) { - add_to_iovec(f, f->buf + f->buf_index, blen); + add_to_iovec(f, f->buf + f->buf_index, blen, false); } f->buf_index += blen; if (f->buf_index == IO_BUF_SIZE) { diff --git a/migration/ram.c b/migration/ram.c index a1c8089010..b0322a0b5c 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -27,6 +27,7 @@ */ #include "qemu/osdep.h" #include "qemu-common.h" +#include "sysemu/sysemu.h" #include "cpu.h" #include #include "qapi-event.h" @@ -713,6 +714,18 @@ static int save_zero_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset, return pages; } +static void ram_discard_page(uint8_t *addr, int pages) +{ + if (!migrate_discard_ram() || !runstate_check(RUN_STATE_FINISH_MIGRATE)) { + return; + } + + if (qemu_madvise(addr, pages << TARGET_PAGE_BITS, QEMU_MADV_DONTNEED) < 0) { + error_report("migrate: madvise DONTNEED failed %p %d: %s", + addr, pages << TARGET_PAGE_BITS, strerror(errno)); + } +} + /** * ram_save_page: Send the given page to the stream * @@ -772,6 +785,7 @@ static int ram_save_page(QEMUFile *f, PageSearchStatus *pss, * page would be stale */ xbzrle_cache_zero_page(current_addr); + ram_discard_page(p, pages); } else if (!ram_bulk_stage && !migration_in_postcopy(migrate_get_current()) && migrate_use_xbzrle()) { @@ -791,9 +805,11 @@ static int ram_save_page(QEMUFile *f, PageSearchStatus *pss, *bytes_transferred += save_page_header(f, block, offset | RAM_SAVE_FLAG_PAGE); if (send_async) { - qemu_put_buffer_async(f, p, TARGET_PAGE_SIZE); + qemu_put_buffer_async( + f, p, TARGET_PAGE_SIZE, migrate_discard_ram()); } else { qemu_put_buffer(f, p, TARGET_PAGE_SIZE); + ram_discard_page(p, 1); } *bytes_transferred += TARGET_PAGE_SIZE; pages = 1; @@ -821,6 +837,7 @@ static int do_compress_ram_page(QEMUFile *f, RAMBlock *block, error_report("compressed data failed!"); } else { bytes_sent += blen; + ram_discard_page(p, 1); } return bytes_sent; @@ -959,12 +976,17 @@ static int ram_save_compressed_page(QEMUFile *f, PageSearchStatus *pss, error_report("compressed data failed!"); } } + if (pages > 0) { + ram_discard_page(p, pages); + } } else { offset |= RAM_SAVE_FLAG_CONTINUE; pages = save_zero_page(f, block, offset, p, bytes_transferred); if (pages == -1) { pages = compress_page_with_multi_thread(f, block, offset, bytes_transferred); + } else { + ram_discard_page(p, pages); } } } diff --git a/qapi-schema.json b/qapi-schema.json index ce20f16757..f02b434765 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -588,11 +588,14 @@ # side, this process is called COarse-Grain LOck Stepping (COLO) for # Non-stop Service. (since 2.8) # +# @discard-ram: if enabled, qemu will free the migrated ram pages on the source +# during postcopy-ram migration. (since 2.9) +# # Since: 1.2 ## { 'enum': 'MigrationCapability', 'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks', - 'compress', 'events', 'postcopy-ram', 'x-colo'] } + 'compress', 'events', 'postcopy-ram', 'x-colo', 'discard-ram'] } ## # @MigrationCapabilityStatus: