From patchwork Tue Mar 13 07:57:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Guangrong X-Patchwork-Id: 885008 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; 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=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="pPhO+Z6h"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 400nKp4sg7z9sSl for ; Tue, 13 Mar 2018 18:58:38 +1100 (AEDT) Received: from localhost ([::1]:37434 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evepQ-0002sq-FV for incoming@patchwork.ozlabs.org; Tue, 13 Mar 2018 03:58:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42932) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eveom-0002r4-4x for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:57:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eveol-0007OM-AW for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:57:56 -0400 Received: from mail-pl0-x241.google.com ([2607:f8b0:400e:c01::241]:44887) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eveol-0007NO-4H for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:57:55 -0400 Received: by mail-pl0-x241.google.com with SMTP id 9-v6so10877769ple.11 for ; Tue, 13 Mar 2018 00:57:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=UC5TJnKBOOx1kQENx1nH1wqP/Tk6n1k1ra1l5ayMmj8=; b=pPhO+Z6hwIQDuBmta7XeFkBGUuBfuHei9NdhaQ71KFt3aMCdb7mWhvy8xBhUyZkyJx sKZGHB7vr2X0aCv8QZuim2HBSSqB8gVph537VluOk/q2zu8Lzs1ijkeXayaMDeSpSoEO /3cKYO6Y9E1rGWaHyjtRRVQuNLKJYJA2VOPx5LGyV4jagk/GExehGjr4BZPHXJc/IYii /TK5A1JQf8GK+xCmPVEbTSdc7GFozO6Meqjf5jw8FbnOf4hDXfbsEqlKz7G3JXgzeAJ2 cJzPX3eHW4RzOsMfLKTturCVqzj98tUKz6ijICHtodpUctKXMIzudJ5KbqCqyrNlVyNL CG8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=UC5TJnKBOOx1kQENx1nH1wqP/Tk6n1k1ra1l5ayMmj8=; b=NkcfrWGdDTDdtF5OJr/d6AzAwtAGfE0x13GjHGcowLomKG0LcLQk4El9dVarHqILGH 42my2KFxfSzpwIq/brxbvtwF+dwBd0Qwmqa5s/LK/gUoo63+pL64DgfUaCk+ywMC8shr q6LfevmaxXEBtu8gDzXZZbIiMM0B+Fb1XJWfCfTIXVZE3hJa6fmekXH0dD67U6ooKFKI ILZW0hqtRgOXfnnDYueHL3+3Mzpq7QyZi3e28OKJ8m7BC/cX1kc8l6nxy0G2Hk/eyCMu SVKE3MVdFE35U94YAOc3fPcDM4ImS1KoZrgWzIop9U/IGxQVpZ7si2X/siP5WXyCIZzE /Y1Q== X-Gm-Message-State: AElRT7FOhJee0/XNsjGTuBGzUWcIVQXRDS1eK+IxWstJgDOT2g80CEIC HkaiqFHY/4uHfW0sZvYLsDtM1g== X-Google-Smtp-Source: AG47ELtVthUISNEphYZA43SlCwIyfJSjrKfk+ZvEnB/8nkEnZtCuSxSQXLoYej4jPQDShINhCUBOgg== X-Received: by 2002:a17:902:be16:: with SMTP id r22-v6mr8222827pls.268.1520927874282; Tue, 13 Mar 2018 00:57:54 -0700 (PDT) Received: from localhost.localdomain ([203.205.141.35]) by smtp.gmail.com with ESMTPSA id x4sm16756537pgv.72.2018.03.13.00.57.51 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Mar 2018 00:57:53 -0700 (PDT) From: guangrong.xiao@gmail.com X-Google-Original-From: xiaoguangrong@tencent.com To: pbonzini@redhat.com, mst@redhat.com, mtosatti@redhat.com Date: Tue, 13 Mar 2018 15:57:32 +0800 Message-Id: <20180313075739.11194-2-xiaoguangrong@tencent.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180313075739.11194-1-xiaoguangrong@tencent.com> References: <20180313075739.11194-1-xiaoguangrong@tencent.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c01::241 Subject: [Qemu-devel] [PATCH 1/8] migration: stop compressing page in migration thread 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: Xiao Guangrong , qemu-devel@nongnu.org, kvm@vger.kernel.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Xiao Guangrong As compression is a heavy work, do not do it in migration thread, instead, we post it out as a normal page Signed-off-by: Xiao Guangrong Reviewed-by: Dr. David Alan Gilbert Reviewed-by: Peter Xu Reviewed-by: Wei Wang --- migration/ram.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/migration/ram.c b/migration/ram.c index 7266351fd0..615693f180 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -1132,7 +1132,7 @@ static int ram_save_compressed_page(RAMState *rs, PageSearchStatus *pss, int pages = -1; uint64_t bytes_xmit = 0; uint8_t *p; - int ret, blen; + int ret; RAMBlock *block = pss->block; ram_addr_t offset = pss->page << TARGET_PAGE_BITS; @@ -1162,23 +1162,23 @@ static int ram_save_compressed_page(RAMState *rs, PageSearchStatus *pss, if (block != rs->last_sent_block) { flush_compressed_data(rs); pages = save_zero_page(rs, block, offset); - if (pages == -1) { - /* Make sure the first page is sent out before other pages */ - bytes_xmit = save_page_header(rs, rs->f, block, offset | - RAM_SAVE_FLAG_COMPRESS_PAGE); - blen = qemu_put_compression_data(rs->f, p, TARGET_PAGE_SIZE, - migrate_compress_level()); - if (blen > 0) { - ram_counters.transferred += bytes_xmit + blen; - ram_counters.normal++; - pages = 1; - } else { - qemu_file_set_error(rs->f, blen); - error_report("compressed data failed!"); - } - } if (pages > 0) { ram_release_pages(block->idstr, offset, pages); + } else { + /* + * Make sure the first page is sent out before other pages. + * + * we post it as normal page as compression will take much + * CPU resource. + */ + ram_counters.transferred += save_page_header(rs, rs->f, block, + offset | RAM_SAVE_FLAG_PAGE); + qemu_put_buffer_async(rs->f, p, TARGET_PAGE_SIZE, + migrate_release_ram() & + migration_in_postcopy()); + ram_counters.transferred += TARGET_PAGE_SIZE; + ram_counters.normal++; + pages = 1; } } else { pages = save_zero_page(rs, block, offset); From patchwork Tue Mar 13 07:57:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Guangrong X-Patchwork-Id: 885014 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; 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=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ivSbIrBu"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 400nNR3Ztxz9sSf for ; Tue, 13 Mar 2018 19:00:55 +1100 (AEDT) Received: from localhost ([::1]:37444 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1everd-0004vy-Ao for incoming@patchwork.ozlabs.org; Tue, 13 Mar 2018 04:00:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42944) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eveoq-0002to-LB for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eveoo-0007SQ-IY for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:00 -0400 Received: from mail-pf0-x241.google.com ([2607:f8b0:400e:c00::241]:42255) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eveoo-0007RO-9G for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:57:58 -0400 Received: by mail-pf0-x241.google.com with SMTP id a16so5531585pfn.9 for ; Tue, 13 Mar 2018 00:57:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nsErO+G2Bef29/2ttcAWcnlTTZT6pnReQgbHdK1wk4o=; b=ivSbIrBu8rcyfiaYcMH3FvXZ9mURJJTJPSu1LyEKrcNMolhE3hqKp3NvcXR2UccFuM 65tBT8V5jpH5PRYzkFvfReuJSrjW6bclPtFQnZqqtXzBfErJ3wS/GtVeNeG2x8ES+msq cAdH9pL9NYdeGf8g7iCflxEdai89nvJbbKEDBPXdXB7WvYREC2CbcCG0OIFR+zEDIEFW 6v6fsdD8LlvF+ubsSLSSRSGjkUMVJcDwrVPrLnzO/Zm9F7UV0Ib4t0MvDGtsSsZABr/f 7yImn+cLew/cxzzAya7n53PFpLnmIcBE4DCubZz14BsMwKfWurhgnOeC5G4xy/8Y0EYl uWiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nsErO+G2Bef29/2ttcAWcnlTTZT6pnReQgbHdK1wk4o=; b=Aa+wIWvspUwvUDYgJ0vX7apNyLLI1uP4edj2rgHXOMlXpAzi3mu7P3X/hYLtbXu4Ou LsFojTJGu8Pya0oJ0kzgxLI70o0DoYqwPtbDifqRgWCMWoDIqqdxesZH9yzqInmL023J kwSUFy4UlJxr21t0QSlgqwW8aqJhAR9JobF16EnNovxVMNWBj+rRMOaEDoww6qQIrkJO LFq12AUA7YFo1QI/CNDG9j0y+nXvokkb4sw75THByLMSwtDsJpxK4RR0W3tfeLtOhwNx yyZMeR5wWZk7WNUg8y/0k1Wd9O0wM2rblbEuM5q4ypcEuzG7N2lYy6o74/seD5D/zjGC UXNQ== X-Gm-Message-State: AElRT7GKZDI2sVum4xJoOIYuYwNHPewaq+ovMr3S2o7AVkKfhLns8FEi fJN4tMDtwmUEjLQ5nhPdKynYFQ== X-Google-Smtp-Source: AG47ELuLL/ws+vX+RkHOArAFXrpRe2nTNuwc/6mRIvXdcl0zLndIxuavG0DF9VCy3wnLwgf8CKBIeA== X-Received: by 10.98.150.82 with SMTP id c79mr10776396pfe.88.1520927877152; Tue, 13 Mar 2018 00:57:57 -0700 (PDT) Received: from localhost.localdomain ([203.205.141.35]) by smtp.gmail.com with ESMTPSA id x4sm16756537pgv.72.2018.03.13.00.57.54 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Mar 2018 00:57:56 -0700 (PDT) From: guangrong.xiao@gmail.com X-Google-Original-From: xiaoguangrong@tencent.com To: pbonzini@redhat.com, mst@redhat.com, mtosatti@redhat.com Date: Tue, 13 Mar 2018 15:57:33 +0800 Message-Id: <20180313075739.11194-3-xiaoguangrong@tencent.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180313075739.11194-1-xiaoguangrong@tencent.com> References: <20180313075739.11194-1-xiaoguangrong@tencent.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::241 Subject: [Qemu-devel] [PATCH 2/8] migration: stop allocating and freeing memory frequently 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: Xiao Guangrong , qemu-devel@nongnu.org, kvm@vger.kernel.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Xiao Guangrong Current code uses compress2()/uncompress() to compress/decompress memory, these two function manager memory allocation and release internally, that causes huge memory is allocated and freed very frequently More worse, frequently returning memory to kernel will flush TLBs and trigger invalidation callbacks on mmu-notification which interacts with KVM MMU, that dramatically reduce the performance of VM So, we maintain the memory by ourselves and reuse it for each compression and decompression Signed-off-by: Xiao Guangrong Reviewed-by: Jiang Biao --- migration/qemu-file.c | 34 ++++++++++-- migration/qemu-file.h | 6 ++- migration/ram.c | 142 +++++++++++++++++++++++++++++++++++++------------- 3 files changed, 140 insertions(+), 42 deletions(-) diff --git a/migration/qemu-file.c b/migration/qemu-file.c index 2ab2bf362d..1ff33a1ffb 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c @@ -658,6 +658,30 @@ uint64_t qemu_get_be64(QEMUFile *f) return v; } +/* return the size after compression, or negative value on error */ +static int qemu_compress_data(z_stream *stream, uint8_t *dest, size_t dest_len, + const uint8_t *source, size_t source_len) +{ + int err; + + err = deflateReset(stream); + if (err != Z_OK) { + return -1; + } + + stream->avail_in = source_len; + stream->next_in = (uint8_t *)source; + stream->avail_out = dest_len; + stream->next_out = dest; + + err = deflate(stream, Z_FINISH); + if (err != Z_STREAM_END) { + return -1; + } + + return stream->next_out - dest; +} + /* Compress size bytes of data start at p with specific compression * level and store the compressed data to the buffer of f. * @@ -668,8 +692,8 @@ uint64_t qemu_get_be64(QEMUFile *f) * data, return -1. */ -ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size, - int level) +ssize_t qemu_put_compression_data(QEMUFile *f, z_stream *stream, + const uint8_t *p, size_t size) { ssize_t blen = IO_BUF_SIZE - f->buf_index - sizeof(int32_t); @@ -683,8 +707,10 @@ ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size, return -1; } } - if (compress2(f->buf + f->buf_index + sizeof(int32_t), (uLongf *)&blen, - (Bytef *)p, size, level) != Z_OK) { + + blen = qemu_compress_data(stream, f->buf + f->buf_index + sizeof(int32_t), + blen, p, size); + if (blen < 0) { error_report("Compress Failed!"); return 0; } diff --git a/migration/qemu-file.h b/migration/qemu-file.h index aae4e5ed36..d123b21ca8 100644 --- a/migration/qemu-file.h +++ b/migration/qemu-file.h @@ -25,6 +25,8 @@ #ifndef MIGRATION_QEMU_FILE_H #define MIGRATION_QEMU_FILE_H +#include + /* Read a chunk of data from a file at the given position. The pos argument * can be ignored if the file is only be used for streaming. The number of * bytes actually read should be returned. @@ -132,8 +134,8 @@ bool qemu_file_is_writable(QEMUFile *f); size_t qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset); size_t qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size); -ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size, - int level); +ssize_t qemu_put_compression_data(QEMUFile *f, z_stream *stream, + const uint8_t *p, size_t size); int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src); /* diff --git a/migration/ram.c b/migration/ram.c index 615693f180..fff3f31e90 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -264,6 +264,7 @@ struct CompressParam { QemuCond cond; RAMBlock *block; ram_addr_t offset; + z_stream stream; }; typedef struct CompressParam CompressParam; @@ -275,6 +276,7 @@ struct DecompressParam { void *des; uint8_t *compbuf; int len; + z_stream stream; }; typedef struct DecompressParam DecompressParam; @@ -294,7 +296,7 @@ static QemuThread *decompress_threads; static QemuMutex decomp_done_lock; static QemuCond decomp_done_cond; -static int do_compress_ram_page(QEMUFile *f, RAMBlock *block, +static int do_compress_ram_page(QEMUFile *f, z_stream *stream, RAMBlock *block, ram_addr_t offset); static void *do_data_compress(void *opaque) @@ -311,7 +313,7 @@ static void *do_data_compress(void *opaque) param->block = NULL; qemu_mutex_unlock(¶m->mutex); - do_compress_ram_page(param->file, block, offset); + do_compress_ram_page(param->file, ¶m->stream, block, offset); qemu_mutex_lock(&comp_done_lock); param->done = true; @@ -352,10 +354,17 @@ static void compress_threads_save_cleanup(void) terminate_compression_threads(); thread_count = migrate_compress_threads(); for (i = 0; i < thread_count; i++) { + /* something in compress_threads_save_setup() is wrong. */ + if (!comp_param[i].stream.opaque) { + break; + } + qemu_thread_join(compress_threads + i); qemu_fclose(comp_param[i].file); qemu_mutex_destroy(&comp_param[i].mutex); qemu_cond_destroy(&comp_param[i].cond); + deflateEnd(&comp_param[i].stream); + comp_param[i].stream.opaque = NULL; } qemu_mutex_destroy(&comp_done_lock); qemu_cond_destroy(&comp_done_cond); @@ -365,12 +374,12 @@ static void compress_threads_save_cleanup(void) comp_param = NULL; } -static void compress_threads_save_setup(void) +static int compress_threads_save_setup(void) { int i, thread_count; if (!migrate_use_compression()) { - return; + return 0; } thread_count = migrate_compress_threads(); compress_threads = g_new0(QemuThread, thread_count); @@ -378,6 +387,12 @@ static void compress_threads_save_setup(void) qemu_cond_init(&comp_done_cond); qemu_mutex_init(&comp_done_lock); for (i = 0; i < thread_count; i++) { + if (deflateInit(&comp_param[i].stream, + migrate_compress_level()) != Z_OK) { + goto exit; + } + comp_param[i].stream.opaque = &comp_param[i]; + /* comp_param[i].file is just used as a dummy buffer to save data, * set its ops to empty. */ @@ -390,6 +405,11 @@ static void compress_threads_save_setup(void) do_data_compress, comp_param + i, QEMU_THREAD_JOINABLE); } + return 0; + +exit: + compress_threads_save_cleanup(); + return -1; } /* Multiple fd's */ @@ -1026,7 +1046,7 @@ static int ram_save_page(RAMState *rs, PageSearchStatus *pss, bool last_stage) return pages; } -static int do_compress_ram_page(QEMUFile *f, RAMBlock *block, +static int do_compress_ram_page(QEMUFile *f, z_stream *stream, RAMBlock *block, ram_addr_t offset) { RAMState *rs = ram_state; @@ -1035,8 +1055,7 @@ static int do_compress_ram_page(QEMUFile *f, RAMBlock *block, bytes_sent = save_page_header(rs, f, block, offset | RAM_SAVE_FLAG_COMPRESS_PAGE); - blen = qemu_put_compression_data(f, p, TARGET_PAGE_SIZE, - migrate_compress_level()); + blen = qemu_put_compression_data(f, stream, p, TARGET_PAGE_SIZE); if (blen < 0) { bytes_sent = 0; qemu_file_set_error(migrate_get_current()->to_dst_file, blen); @@ -2209,9 +2228,14 @@ static int ram_save_setup(QEMUFile *f, void *opaque) RAMState **rsp = opaque; RAMBlock *block; + if (compress_threads_save_setup()) { + return -1; + } + /* migration has already setup the bitmap, reuse it. */ if (!migration_in_colo_state()) { if (ram_init_all(rsp) != 0) { + compress_threads_save_cleanup(); return -1; } } @@ -2231,7 +2255,6 @@ static int ram_save_setup(QEMUFile *f, void *opaque) } rcu_read_unlock(); - compress_threads_save_setup(); ram_control_before_iterate(f, RAM_CONTROL_SETUP); ram_control_after_iterate(f, RAM_CONTROL_SETUP); @@ -2495,6 +2518,30 @@ void ram_handle_compressed(void *host, uint8_t ch, uint64_t size) } } +/* return the size after decompression, or negative value on error */ +static int qemu_uncompress(z_stream *stream, uint8_t *dest, size_t dest_len, + uint8_t *source, size_t source_len) +{ + int err; + + err = inflateReset(stream); + if (err != Z_OK) { + return -1; + } + + stream->avail_in = source_len; + stream->next_in = source; + stream->avail_out = dest_len; + stream->next_out = dest; + + err = inflate(stream, Z_NO_FLUSH); + if (err != Z_STREAM_END) { + return -1; + } + + return stream->total_out; +} + static void *do_data_decompress(void *opaque) { DecompressParam *param = opaque; @@ -2511,13 +2558,13 @@ static void *do_data_decompress(void *opaque) qemu_mutex_unlock(¶m->mutex); pagesize = TARGET_PAGE_SIZE; - /* uncompress() will return failed in some case, especially + /* qemu_uncompress() will return failed in some case, especially * when the page is dirted when doing the compression, it's * not a problem because the dirty page will be retransferred * and uncompress() won't break the data in other pages. */ - uncompress((Bytef *)des, &pagesize, - (const Bytef *)param->compbuf, len); + qemu_uncompress(¶m->stream, des, pagesize, + param->compbuf, len); qemu_mutex_lock(&decomp_done_lock); param->done = true; @@ -2552,30 +2599,6 @@ static void wait_for_decompress_done(void) qemu_mutex_unlock(&decomp_done_lock); } -static void compress_threads_load_setup(void) -{ - int i, thread_count; - - if (!migrate_use_compression()) { - return; - } - thread_count = migrate_decompress_threads(); - decompress_threads = g_new0(QemuThread, thread_count); - decomp_param = g_new0(DecompressParam, thread_count); - qemu_mutex_init(&decomp_done_lock); - qemu_cond_init(&decomp_done_cond); - for (i = 0; i < thread_count; i++) { - qemu_mutex_init(&decomp_param[i].mutex); - qemu_cond_init(&decomp_param[i].cond); - decomp_param[i].compbuf = g_malloc0(compressBound(TARGET_PAGE_SIZE)); - decomp_param[i].done = true; - decomp_param[i].quit = false; - qemu_thread_create(decompress_threads + i, "decompress", - do_data_decompress, decomp_param + i, - QEMU_THREAD_JOINABLE); - } -} - static void compress_threads_load_cleanup(void) { int i, thread_count; @@ -2585,16 +2608,26 @@ static void compress_threads_load_cleanup(void) } thread_count = migrate_decompress_threads(); for (i = 0; i < thread_count; i++) { + if (!decomp_param[i].stream.opaque) { + break; + } + qemu_mutex_lock(&decomp_param[i].mutex); decomp_param[i].quit = true; qemu_cond_signal(&decomp_param[i].cond); qemu_mutex_unlock(&decomp_param[i].mutex); } for (i = 0; i < thread_count; i++) { + if (!decomp_param[i].stream.opaque) { + break; + } + qemu_thread_join(decompress_threads + i); qemu_mutex_destroy(&decomp_param[i].mutex); qemu_cond_destroy(&decomp_param[i].cond); g_free(decomp_param[i].compbuf); + inflateEnd(&decomp_param[i].stream); + decomp_param[i].stream.opaque = NULL; } g_free(decompress_threads); g_free(decomp_param); @@ -2602,6 +2635,40 @@ static void compress_threads_load_cleanup(void) decomp_param = NULL; } +static int compress_threads_load_setup(void) +{ + int i, thread_count; + + if (!migrate_use_compression()) { + return 0; + } + + thread_count = migrate_decompress_threads(); + decompress_threads = g_new0(QemuThread, thread_count); + decomp_param = g_new0(DecompressParam, thread_count); + qemu_mutex_init(&decomp_done_lock); + qemu_cond_init(&decomp_done_cond); + for (i = 0; i < thread_count; i++) { + if (inflateInit(&decomp_param[i].stream) != Z_OK) { + goto exit; + } + decomp_param[i].stream.opaque = &decomp_param[i]; + + qemu_mutex_init(&decomp_param[i].mutex); + qemu_cond_init(&decomp_param[i].cond); + decomp_param[i].compbuf = g_malloc0(compressBound(TARGET_PAGE_SIZE)); + decomp_param[i].done = true; + decomp_param[i].quit = false; + qemu_thread_create(decompress_threads + i, "decompress", + do_data_decompress, decomp_param + i, + QEMU_THREAD_JOINABLE); + } + return 0; +exit: + compress_threads_load_cleanup(); + return -1; +} + static void decompress_data_with_multi_threads(QEMUFile *f, void *host, int len) { @@ -2641,8 +2708,11 @@ static void decompress_data_with_multi_threads(QEMUFile *f, */ static int ram_load_setup(QEMUFile *f, void *opaque) { + if (compress_threads_load_setup()) { + return -1; + } + xbzrle_load_setup(); - compress_threads_load_setup(); ramblock_recv_map_init(); return 0; } From patchwork Tue Mar 13 07:57:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Guangrong X-Patchwork-Id: 885015 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; 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=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Sc65Xp5x"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 400nNT58LMz9sSl for ; Tue, 13 Mar 2018 19:00:57 +1100 (AEDT) Received: from localhost ([::1]:37446 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1everf-0004xr-JL for incoming@patchwork.ozlabs.org; Tue, 13 Mar 2018 04:00:55 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42955) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eveou-0002ut-6c for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eveor-0007VS-2e for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:04 -0400 Received: from mail-pl0-x243.google.com ([2607:f8b0:400e:c01::243]:38937) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eveoq-0007UO-QR for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:01 -0400 Received: by mail-pl0-x243.google.com with SMTP id s13-v6so10882297plq.6 for ; Tue, 13 Mar 2018 00:58:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=AhWu5ni7+B7HBhgDVq+1XMx0LwMo8iKYF+uZn6w/NuE=; b=Sc65Xp5xxcduePddcIb4cTfysahY71i47+Vvo2T/1oPewmJuxAdIrB2D64L4Y9litF nfNxKJqoPcXiVzC+BNECELCFIoadeUrk/rkjjcNG1m1rv2OYQLe0fMdo0Qt7gbBDc0Ui OklHTvd4yo1DEKyUhX7lA3pBBLXwxIH8MXawDtxfWdG8DP17NgxvFoQUyw3LBQ0t+YLq vAjUfn2akGF7tYLxevBRsUkPwd2qwPRFrbLbCbg57WNQBhGGLTckqRhr8k1MhOpjPY0K f8uhAGD+Aep/WGMJlL2+hMMtdwPIMIr7J9wwdX9gn065nlc1mT3K9SXNQK80OIJiKjEh /p4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=AhWu5ni7+B7HBhgDVq+1XMx0LwMo8iKYF+uZn6w/NuE=; b=iks+QOoMsQmdFA6NX6rxrjD849VQy6Zi76P6ziwHkFGUfMQOrFNvUOb60VQBY1kwte W0gQhU42L2nzJjZxpYQ1fK2ZocWF4QbgVoBbqRARTaJf99aRkJXZepH8HG5RZV+vBaTg 8BmKGcnELD4GTcg2L/XctbZOcGo0y22q87+7FLiWljM0urmZ1TCSv2ysBT6dpCO+w//J 8n4DfzEv4H66kr4nKz7AiyEd6rN8/nrCUt+0bn9EJ6ugDb7IDZ/u7DSMoO+2exYxh4WO 0nEVhpd5+jn6Gh1ZybhAhsaVyGpqOFqI7oNbU7OjJ9PZjQZkUyD4QiHAVb0gLB59fZ/U Y+aA== X-Gm-Message-State: AElRT7EK5X5Jnl4LNptZxiwhBa7FLVU80U7rqUCMAX8+TfZCUOdgLcoS EwqosiUDIhNuMdk6rpHoZWI= X-Google-Smtp-Source: AG47ELtZu92sURJonDydm19Xq8vC7GwbrA/2mCFXTdp+95QNlAC3AQtmzcCp2KsDwiNagCuZbT79yg== X-Received: by 2002:a17:902:8c93:: with SMTP id t19-v6mr10702607plo.304.1520927879869; Tue, 13 Mar 2018 00:57:59 -0700 (PDT) Received: from localhost.localdomain ([203.205.141.35]) by smtp.gmail.com with ESMTPSA id x4sm16756537pgv.72.2018.03.13.00.57.57 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Mar 2018 00:57:59 -0700 (PDT) From: guangrong.xiao@gmail.com X-Google-Original-From: xiaoguangrong@tencent.com To: pbonzini@redhat.com, mst@redhat.com, mtosatti@redhat.com Date: Tue, 13 Mar 2018 15:57:34 +0800 Message-Id: <20180313075739.11194-4-xiaoguangrong@tencent.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180313075739.11194-1-xiaoguangrong@tencent.com> References: <20180313075739.11194-1-xiaoguangrong@tencent.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c01::243 Subject: [Qemu-devel] [PATCH 3/8] migration: support to detect compression and decompression errors 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: Xiao Guangrong , qemu-devel@nongnu.org, kvm@vger.kernel.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Xiao Guangrong Currently the page being compressed is allowed to be updated by the VM on the source QEMU, correspondingly the destination QEMU just ignores the decompression error. However, we completely miss the chance to catch real errors, then the VM is corrupted silently To make the migration more robuster, we copy the page to a buffer first to avoid it being written by VM, then detect and handle the errors of both compression and decompression errors properly Signed-off-by: Xiao Guangrong --- migration/qemu-file.c | 4 ++-- migration/ram.c | 29 +++++++++++++++++++---------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/migration/qemu-file.c b/migration/qemu-file.c index 1ff33a1ffb..137bcc8bdc 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c @@ -711,9 +711,9 @@ ssize_t qemu_put_compression_data(QEMUFile *f, z_stream *stream, blen = qemu_compress_data(stream, f->buf + f->buf_index + sizeof(int32_t), blen, p, size); if (blen < 0) { - error_report("Compress Failed!"); - return 0; + return -1; } + qemu_put_be32(f, blen); if (f->ops->writev_buffer) { add_to_iovec(f, f->buf + f->buf_index, blen, false); diff --git a/migration/ram.c b/migration/ram.c index fff3f31e90..c47185d38c 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -273,6 +273,7 @@ struct DecompressParam { bool quit; QemuMutex mutex; QemuCond cond; + QEMUFile *file; void *des; uint8_t *compbuf; int len; @@ -1051,11 +1052,13 @@ static int do_compress_ram_page(QEMUFile *f, z_stream *stream, RAMBlock *block, { RAMState *rs = ram_state; int bytes_sent, blen; - uint8_t *p = block->host + (offset & TARGET_PAGE_MASK); + uint8_t buf[TARGET_PAGE_SIZE], *p; + p = block->host + (offset & TARGET_PAGE_MASK); bytes_sent = save_page_header(rs, f, block, offset | RAM_SAVE_FLAG_COMPRESS_PAGE); - blen = qemu_put_compression_data(f, stream, p, TARGET_PAGE_SIZE); + memcpy(buf, p, TARGET_PAGE_SIZE); + blen = qemu_put_compression_data(f, stream, buf, TARGET_PAGE_SIZE); if (blen < 0) { bytes_sent = 0; qemu_file_set_error(migrate_get_current()->to_dst_file, blen); @@ -2547,7 +2550,7 @@ static void *do_data_decompress(void *opaque) DecompressParam *param = opaque; unsigned long pagesize; uint8_t *des; - int len; + int len, ret; qemu_mutex_lock(¶m->mutex); while (!param->quit) { @@ -2563,8 +2566,12 @@ static void *do_data_decompress(void *opaque) * not a problem because the dirty page will be retransferred * and uncompress() won't break the data in other pages. */ - qemu_uncompress(¶m->stream, des, pagesize, - param->compbuf, len); + ret = qemu_uncompress(¶m->stream, des, pagesize, + param->compbuf, len); + if (ret < 0) { + error_report("decompress data failed"); + qemu_file_set_error(param->file, ret); + } qemu_mutex_lock(&decomp_done_lock); param->done = true; @@ -2581,12 +2588,12 @@ static void *do_data_decompress(void *opaque) return NULL; } -static void wait_for_decompress_done(void) +static int wait_for_decompress_done(QEMUFile *f) { int idx, thread_count; if (!migrate_use_compression()) { - return; + return 0; } thread_count = migrate_decompress_threads(); @@ -2597,6 +2604,7 @@ static void wait_for_decompress_done(void) } } qemu_mutex_unlock(&decomp_done_lock); + return qemu_file_get_error(f); } static void compress_threads_load_cleanup(void) @@ -2635,7 +2643,7 @@ static void compress_threads_load_cleanup(void) decomp_param = NULL; } -static int compress_threads_load_setup(void) +static int compress_threads_load_setup(QEMUFile *f) { int i, thread_count; @@ -2654,6 +2662,7 @@ static int compress_threads_load_setup(void) } decomp_param[i].stream.opaque = &decomp_param[i]; + decomp_param[i].file = f; qemu_mutex_init(&decomp_param[i].mutex); qemu_cond_init(&decomp_param[i].cond); decomp_param[i].compbuf = g_malloc0(compressBound(TARGET_PAGE_SIZE)); @@ -2708,7 +2717,7 @@ static void decompress_data_with_multi_threads(QEMUFile *f, */ static int ram_load_setup(QEMUFile *f, void *opaque) { - if (compress_threads_load_setup()) { + if (compress_threads_load_setup(f)) { return -1; } @@ -3063,7 +3072,7 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) } } - wait_for_decompress_done(); + ret |= wait_for_decompress_done(f); rcu_read_unlock(); trace_ram_load_complete(ret, seq_iter); return ret; From patchwork Tue Mar 13 07:57:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Guangrong X-Patchwork-Id: 885010 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; 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=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="KGkue+2F"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 400nL40QYQz9sSf for ; Tue, 13 Mar 2018 18:58:52 +1100 (AEDT) Received: from localhost ([::1]:37435 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evepd-0002zY-G5 for incoming@patchwork.ozlabs.org; Tue, 13 Mar 2018 03:58:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42973) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eveox-0002x9-Nk for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eveow-0007bm-FJ for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:07 -0400 Received: from mail-pg0-x236.google.com ([2607:f8b0:400e:c05::236]:38483) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eveow-0007aq-6y for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:06 -0400 Received: by mail-pg0-x236.google.com with SMTP id a15so3291909pgn.5 for ; Tue, 13 Mar 2018 00:58:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=IGT4xMwPZE73350UhQUA0wE/NPVG0PQik2HBnTOyd+s=; b=KGkue+2FhcLggapImWY3JP/TEucLhXRVWphzejFHc4enDNF+wdfG3ejQsxtOp5nlld o8YUr4kVEN0UTlZDqNbFs8ZyoY0pv/AFVc5nT8qo3dhAuyHDBdco08XIqzJoOQgGKTb2 YE8UGtuCeY9PtGBoqV1j4sAC7ipC0Tp3ULH42HNbMKnA95giG+jkGlNq6kTAv50tQa8d lGneVd3WNO43q9bIfwCHqrizGgrKBwx1T7ZD/eEPV+Ph8O0jdRPLWVW5DFexwz5G5qVb /CACmXvU/NVy7Jun4ijlz/T7Wx3i3FXKPn0WatRsrdpiARGxcO72SsCIBZlQrun5lHIn +Jmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=IGT4xMwPZE73350UhQUA0wE/NPVG0PQik2HBnTOyd+s=; b=NZ5a51iNJxskL2dBLzkNqQe4WxJiiLCp2wzmFUapRqLWr018LYYnmABEqZ7Z2dXsqt 4LkLJEGLL59xRUxU4jV22fWDbMXv3qBCucoBgVw6kiH59bzh9fEnFAIwVSiCwqFKktyH QLTJKJMb6kHOEhfV5BY2Iuyg2mLDCYyVy8nEpWrsXBqS8/QVqL02JWsPtr/7ZGX6WXQu qfsv51KSb8YJckU5+Vy7VemGz77HJl7j8q9dZPfRfmTrVt5ZDu/qWEfQQTQiCQo+EDGN rf7OnWvnHpGv4t9yDfjuaniGxusqR3nRIDC/Q4liWRbsq1LpaM5ua4derdOxgympaXNL ahtQ== X-Gm-Message-State: AElRT7H14u4KARwYXzED26+vHLsENNkL4SE3BwpoJcyEen3UhvtnKpoy Mq+yQC/Pazn8Q/dyrz/1nkY= X-Google-Smtp-Source: AG47ELuberRsjrM6PLSPxVjqvesSiYjiMsZ01holwjNdmQ7KgraFAH4gCDWphI3BdeEKEVA/zUQ4JA== X-Received: by 10.99.154.18 with SMTP id o18mr9102723pge.344.1520927885195; Tue, 13 Mar 2018 00:58:05 -0700 (PDT) Received: from localhost.localdomain ([203.205.141.35]) by smtp.gmail.com with ESMTPSA id x4sm16756537pgv.72.2018.03.13.00.58.00 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Mar 2018 00:58:04 -0700 (PDT) From: guangrong.xiao@gmail.com X-Google-Original-From: xiaoguangrong@tencent.com To: pbonzini@redhat.com, mst@redhat.com, mtosatti@redhat.com Date: Tue, 13 Mar 2018 15:57:35 +0800 Message-Id: <20180313075739.11194-5-xiaoguangrong@tencent.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180313075739.11194-1-xiaoguangrong@tencent.com> References: <20180313075739.11194-1-xiaoguangrong@tencent.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::236 Subject: [Qemu-devel] [PATCH 4/8] migration: introduce control_save_page() 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: Xiao Guangrong , qemu-devel@nongnu.org, kvm@vger.kernel.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Xiao Guangrong Abstract the common function control_save_page() to cleanup the code, no logic is changed Signed-off-by: Xiao Guangrong Reviewed-by: Dr. David Alan Gilbert Reviewed-by: Peter Xu --- migration/ram.c | 174 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 89 insertions(+), 85 deletions(-) diff --git a/migration/ram.c b/migration/ram.c index c47185d38c..e7b8b14c3c 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -957,6 +957,44 @@ static void ram_release_pages(const char *rbname, uint64_t offset, int pages) ram_discard_range(rbname, offset, pages << TARGET_PAGE_BITS); } +/* + * @pages: the number of pages written by the control path, + * < 0 - error + * > 0 - number of pages written + * + * Return true if the pages has been saved, otherwise false is returned. + */ +static bool control_save_page(RAMState *rs, RAMBlock *block, ram_addr_t offset, + int *pages) +{ + uint64_t bytes_xmit = 0; + int ret; + + *pages = -1; + ret = ram_control_save_page(rs->f, block->offset, offset, TARGET_PAGE_SIZE, + &bytes_xmit); + if (ret == RAM_SAVE_CONTROL_NOT_SUPP) { + return false; + } + + if (bytes_xmit) { + ram_counters.transferred += bytes_xmit; + *pages = 1; + } + + if (ret == RAM_SAVE_CONTROL_DELAYED) { + return true; + } + + if (bytes_xmit > 0) { + ram_counters.normal++; + } else if (bytes_xmit == 0) { + ram_counters.duplicate++; + } + + return true; +} + /** * ram_save_page: send the given page to the stream * @@ -973,56 +1011,36 @@ static void ram_release_pages(const char *rbname, uint64_t offset, int pages) static int ram_save_page(RAMState *rs, PageSearchStatus *pss, bool last_stage) { int pages = -1; - uint64_t bytes_xmit; - ram_addr_t current_addr; uint8_t *p; - int ret; bool send_async = true; RAMBlock *block = pss->block; ram_addr_t offset = pss->page << TARGET_PAGE_BITS; + ram_addr_t current_addr = block->offset + offset; p = block->host + offset; trace_ram_save_page(block->idstr, (uint64_t)offset, p); - /* In doubt sent page as normal */ - bytes_xmit = 0; - ret = ram_control_save_page(rs->f, block->offset, - offset, TARGET_PAGE_SIZE, &bytes_xmit); - if (bytes_xmit) { - ram_counters.transferred += bytes_xmit; - pages = 1; + if (control_save_page(rs, block, offset, &pages)) { + return pages; } XBZRLE_cache_lock(); - - current_addr = block->offset + offset; - - if (ret != RAM_SAVE_CONTROL_NOT_SUPP) { - if (ret != RAM_SAVE_CONTROL_DELAYED) { - if (bytes_xmit > 0) { - ram_counters.normal++; - } else if (bytes_xmit == 0) { - ram_counters.duplicate++; - } - } - } else { - pages = save_zero_page(rs, block, offset); - if (pages > 0) { - /* Must let xbzrle know, otherwise a previous (now 0'd) cached - * page would be stale + pages = save_zero_page(rs, block, offset); + if (pages > 0) { + /* Must let xbzrle know, otherwise a previous (now 0'd) cached + * page would be stale + */ + xbzrle_cache_zero_page(rs, current_addr); + ram_release_pages(block->idstr, offset, pages); + } else if (!rs->ram_bulk_stage && + !migration_in_postcopy() && migrate_use_xbzrle()) { + pages = save_xbzrle_page(rs, &p, current_addr, block, + offset, last_stage); + if (!last_stage) { + /* Can't send this cached data async, since the cache page + * might get updated before it gets to the wire */ - xbzrle_cache_zero_page(rs, current_addr); - ram_release_pages(block->idstr, offset, pages); - } else if (!rs->ram_bulk_stage && - !migration_in_postcopy() && migrate_use_xbzrle()) { - pages = save_xbzrle_page(rs, &p, current_addr, block, - offset, last_stage); - if (!last_stage) { - /* Can't send this cached data async, since the cache page - * might get updated before it gets to the wire - */ - send_async = false; - } + send_async = false; } } @@ -1152,63 +1170,49 @@ static int ram_save_compressed_page(RAMState *rs, PageSearchStatus *pss, bool last_stage) { int pages = -1; - uint64_t bytes_xmit = 0; uint8_t *p; - int ret; RAMBlock *block = pss->block; ram_addr_t offset = pss->page << TARGET_PAGE_BITS; p = block->host + offset; - ret = ram_control_save_page(rs->f, block->offset, - offset, TARGET_PAGE_SIZE, &bytes_xmit); - if (bytes_xmit) { - ram_counters.transferred += bytes_xmit; - pages = 1; + if (control_save_page(rs, block, offset, &pages)) { + return pages; } - if (ret != RAM_SAVE_CONTROL_NOT_SUPP) { - if (ret != RAM_SAVE_CONTROL_DELAYED) { - if (bytes_xmit > 0) { - ram_counters.normal++; - } else if (bytes_xmit == 0) { - ram_counters.duplicate++; - } + + /* When starting the process of a new block, the first page of + * the block should be sent out before other pages in the same + * block, and all the pages in last block should have been sent + * out, keeping this order is important, because the 'cont' flag + * is used to avoid resending the block name. + */ + if (block != rs->last_sent_block) { + flush_compressed_data(rs); + pages = save_zero_page(rs, block, offset); + if (pages > 0) { + ram_release_pages(block->idstr, offset, pages); + } else { + /* + * Make sure the first page is sent out before other pages. + * + * we post it as normal page as compression will take much + * CPU resource. + */ + ram_counters.transferred += save_page_header(rs, rs->f, block, + offset | RAM_SAVE_FLAG_PAGE); + qemu_put_buffer_async(rs->f, p, TARGET_PAGE_SIZE, + migrate_release_ram() & + migration_in_postcopy()); + ram_counters.transferred += TARGET_PAGE_SIZE; + ram_counters.normal++; + pages = 1; } } else { - /* When starting the process of a new block, the first page of - * the block should be sent out before other pages in the same - * block, and all the pages in last block should have been sent - * out, keeping this order is important, because the 'cont' flag - * is used to avoid resending the block name. - */ - if (block != rs->last_sent_block) { - flush_compressed_data(rs); - pages = save_zero_page(rs, block, offset); - if (pages > 0) { - ram_release_pages(block->idstr, offset, pages); - } else { - /* - * Make sure the first page is sent out before other pages. - * - * we post it as normal page as compression will take much - * CPU resource. - */ - ram_counters.transferred += save_page_header(rs, rs->f, block, - offset | RAM_SAVE_FLAG_PAGE); - qemu_put_buffer_async(rs->f, p, TARGET_PAGE_SIZE, - migrate_release_ram() & - migration_in_postcopy()); - ram_counters.transferred += TARGET_PAGE_SIZE; - ram_counters.normal++; - pages = 1; - } + pages = save_zero_page(rs, block, offset); + if (pages == -1) { + pages = compress_page_with_multi_thread(rs, block, offset); } else { - pages = save_zero_page(rs, block, offset); - if (pages == -1) { - pages = compress_page_with_multi_thread(rs, block, offset); - } else { - ram_release_pages(block->idstr, offset, pages); - } + ram_release_pages(block->idstr, offset, pages); } } From patchwork Tue Mar 13 07:57:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Guangrong X-Patchwork-Id: 885021 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; 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=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Bq9FSyJK"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 400nRP1Tm1z9sSf for ; Tue, 13 Mar 2018 19:03:29 +1100 (AEDT) Received: from localhost ([::1]:37462 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eveu7-0006tA-34 for incoming@patchwork.ozlabs.org; Tue, 13 Mar 2018 04:03:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42989) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eveoz-0002yi-Pa for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eveoy-0007f5-Un for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:09 -0400 Received: from mail-pf0-x22d.google.com ([2607:f8b0:400e:c00::22d]:34464) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eveoy-0007eP-Ou for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:08 -0400 Received: by mail-pf0-x22d.google.com with SMTP id j20so5540949pfi.1 for ; Tue, 13 Mar 2018 00:58:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+cgEGzYx+EI4jtofU/Be0YPAm0jsFU8XENuzH7MI8Bs=; b=Bq9FSyJKUackhWGsxDuLgsePvi+ywphA5WALwVytOYnLGE7LhoKt9jtu0XHw3bnuiS IjwNNg+Eg5qXTesgzZIj0oY0G3DlGq30t/jPDJxYKopzi3SMX/b2y4W7fURvyux9y/2e 19Nf75EqHCSWYryJPJbkB5hBSatwH283aVidJoyqAsWocfgma5gkNoyyTZtVjCezg5Sx JsgHkbNCZd2rDVRhKHPUQsQSNWwYYAGIG74efLXpOmJW5EgTb+u80Tkv0zRz6c2EDa6A aALMfKR9IYoPyrKNcLBU90Bs9SrHxkxnb0XbEuSF+k3vDqMmDbo312Oc/YIuQM8cwObm BQPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+cgEGzYx+EI4jtofU/Be0YPAm0jsFU8XENuzH7MI8Bs=; b=FuhhMlNaE+V0yptS/QdRYxWwL+dpbXFAuNYoqNqX2IqzHEvWEbRPBo9/dvkXbhHXD6 CbFYxq7SAGzmmHrzCAFwc1RzS0jgpXkjIEIhW26rFoKdN92mejFRJ2/7EBYPHQb3tXbL AiuGE2BInD58j/ansnx9sHRLYm6SKECawhfH351GVluH4AAZuKXdNqTrJ5CENVgCgp1K YgLorO9dPCwW10Ck0NrQODvP5+eHnqerFcY0fMHOhWdywVkTvAVlgApGjCo2vu88uibP BfJAM1zmKV64JsWN6MRTePONVEtKJ6xJ77WayqwBwNFqrNWMlnG59wOT4WKoIc8+1+W9 TDdA== X-Gm-Message-State: AElRT7FayLARvMHrFFakAKWMM+b2L/EVKxxZpEW7aNs0W4jo9PmwmRqG l61IzNfTKUqttAQF90um1wA= X-Google-Smtp-Source: AG47ELud9LMLtGgZLWvFHvs5oV8fGRcNYCr3yeWXvSLUFHzwISVbcsWS3YbiNO9A+NeanTHo4C79qw== X-Received: by 10.99.111.130 with SMTP id k124mr9170164pgc.236.1520927887868; Tue, 13 Mar 2018 00:58:07 -0700 (PDT) Received: from localhost.localdomain ([203.205.141.35]) by smtp.gmail.com with ESMTPSA id x4sm16756537pgv.72.2018.03.13.00.58.05 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Mar 2018 00:58:07 -0700 (PDT) From: guangrong.xiao@gmail.com X-Google-Original-From: xiaoguangrong@tencent.com To: pbonzini@redhat.com, mst@redhat.com, mtosatti@redhat.com Date: Tue, 13 Mar 2018 15:57:36 +0800 Message-Id: <20180313075739.11194-6-xiaoguangrong@tencent.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180313075739.11194-1-xiaoguangrong@tencent.com> References: <20180313075739.11194-1-xiaoguangrong@tencent.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::22d Subject: [Qemu-devel] [PATCH 5/8] migration: move calling control_save_page to the common place 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: Xiao Guangrong , qemu-devel@nongnu.org, kvm@vger.kernel.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Xiao Guangrong The function is called by both ram_save_page and ram_save_target_page, so move it to the common caller to cleanup the code Signed-off-by: Xiao Guangrong Reviewed-by: Peter Xu --- migration/ram.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/migration/ram.c b/migration/ram.c index e7b8b14c3c..839665d866 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -1020,10 +1020,6 @@ static int ram_save_page(RAMState *rs, PageSearchStatus *pss, bool last_stage) p = block->host + offset; trace_ram_save_page(block->idstr, (uint64_t)offset, p); - if (control_save_page(rs, block, offset, &pages)) { - return pages; - } - XBZRLE_cache_lock(); pages = save_zero_page(rs, block, offset); if (pages > 0) { @@ -1176,10 +1172,6 @@ static int ram_save_compressed_page(RAMState *rs, PageSearchStatus *pss, p = block->host + offset; - if (control_save_page(rs, block, offset, &pages)) { - return pages; - } - /* When starting the process of a new block, the first page of * the block should be sent out before other pages in the same * block, and all the pages in last block should have been sent @@ -1472,6 +1464,13 @@ static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss, /* Check the pages is dirty and if it is send it */ if (migration_bitmap_clear_dirty(rs, pss->block, pss->page)) { + RAMBlock *block = pss->block; + ram_addr_t offset = pss->page << TARGET_PAGE_BITS; + + if (control_save_page(rs, block, offset, &res)) { + goto page_saved; + } + /* * If xbzrle is on, stop using the data compression after first * round of migration even if compression is enabled. In theory, @@ -1484,6 +1483,7 @@ static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss, res = ram_save_page(rs, pss, last_stage); } +page_saved: if (res < 0) { return res; } From patchwork Tue Mar 13 07:57:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Guangrong X-Patchwork-Id: 885019 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; 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=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ouk+9VSa"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 400nQ05JmGz9sSl for ; Tue, 13 Mar 2018 19:02:16 +1100 (AEDT) Received: from localhost ([::1]:37456 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evesw-0005vl-Jt for incoming@patchwork.ozlabs.org; Tue, 13 Mar 2018 04:02:14 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43011) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evep3-00031W-0P for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1evep1-0007if-Mf for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:13 -0400 Received: from mail-pf0-x22f.google.com ([2607:f8b0:400e:c00::22f]:36850) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1evep1-0007hZ-E3 for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:11 -0400 Received: by mail-pf0-x22f.google.com with SMTP id 68so5534434pfx.3 for ; Tue, 13 Mar 2018 00:58:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Sy0QgZyuQbOLpLoSQmr/2TpPuWfOE10HoH7QZAwRxmo=; b=ouk+9VSauBsLZF3tdqUb+SUFoFHVKj2X2FvVtn346DgyAHWD2ZfuyCenfK7f+i1PR3 H0Rm1qSnxd7oSG5wHa0bMWJ3y7w8RG60LFT30LWJZXQW29s3RjQJ3haTt64Q/BJJbLKj fRDaA4FJ375NFR2C7gKhb+2CDVyitbqmCnm368JIuioC22Gtsilm0qble1k/6Va5b9nk eQy8VbdNjILTdhgJ+T9mCM++JrE+4gtpO5D9d6UvxXcXAZ7mF3eG0VPPhMWW4dEdSEnr e5GNdSmfEhdw7SmDG3s2MBPcLxFAsXlBgHlGPM7OFThHEZYvOFZDaRsb4DkostPCr4CG Vntw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Sy0QgZyuQbOLpLoSQmr/2TpPuWfOE10HoH7QZAwRxmo=; b=ajxwdLk4lC+2BBlAShcye3potdhcm7RC05/GHWmAxeUzd1eMvd5S+phXPPN1DgETva Tzm3EoANA080Tpje2hfV3puTXAeQdfnxbzq2w3MUJGF24m/uGHsuViY1ypLv3yQQxPqN ajYFq4YKhTlPmS78tRmIIrskyF7zr9CfdwL3yPW6RWAUqbWmK5jPHTpeXiCBknITA3st N7mEiAHSlActkq8q2TIbB2zclNeeIVbgHflTLL/JrzuSe+66aJ9F1ugTZgo5NdUp44/P wqHooHNc4sOE+4XfYo/twvWA3S08d2YUlLX+DOvmmqMBMVka++IdABy7P0AMhaXZDsJs yyTg== X-Gm-Message-State: AElRT7HPI4S/NR8UwsazKtx93DHEHjMBfIp+/Bjd/ZsxH+m6crmO4fk2 0XlvS7gFvuESslGXoyIcM2ZP7A== X-Google-Smtp-Source: AG47ELtPvlz46blcov7/6si/Q6hz/C0t+a+AkQIZJ4xYQdF+KygoFZmGBXSSUrCghvj1VvrNRy6RUQ== X-Received: by 10.98.220.207 with SMTP id c76mr10691333pfl.159.1520927890438; Tue, 13 Mar 2018 00:58:10 -0700 (PDT) Received: from localhost.localdomain ([203.205.141.35]) by smtp.gmail.com with ESMTPSA id x4sm16756537pgv.72.2018.03.13.00.58.08 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Mar 2018 00:58:10 -0700 (PDT) From: guangrong.xiao@gmail.com X-Google-Original-From: xiaoguangrong@tencent.com To: pbonzini@redhat.com, mst@redhat.com, mtosatti@redhat.com Date: Tue, 13 Mar 2018 15:57:37 +0800 Message-Id: <20180313075739.11194-7-xiaoguangrong@tencent.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180313075739.11194-1-xiaoguangrong@tencent.com> References: <20180313075739.11194-1-xiaoguangrong@tencent.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::22f Subject: [Qemu-devel] [PATCH 6/8] migration: move calling save_zero_page to the common place 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: Xiao Guangrong , qemu-devel@nongnu.org, kvm@vger.kernel.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Xiao Guangrong save_zero_page() is always our first approach to try, move it to the common place before calling ram_save_compressed_page and ram_save_page Signed-off-by: Xiao Guangrong Reviewed-by: Dr. David Alan Gilbert Reviewed-by: Peter Xu --- migration/ram.c | 106 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 46 deletions(-) diff --git a/migration/ram.c b/migration/ram.c index 839665d866..9627ce18e9 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -1021,15 +1021,8 @@ static int ram_save_page(RAMState *rs, PageSearchStatus *pss, bool last_stage) trace_ram_save_page(block->idstr, (uint64_t)offset, p); XBZRLE_cache_lock(); - pages = save_zero_page(rs, block, offset); - if (pages > 0) { - /* Must let xbzrle know, otherwise a previous (now 0'd) cached - * page would be stale - */ - xbzrle_cache_zero_page(rs, current_addr); - ram_release_pages(block->idstr, offset, pages); - } else if (!rs->ram_bulk_stage && - !migration_in_postcopy() && migrate_use_xbzrle()) { + if (!rs->ram_bulk_stage && !migration_in_postcopy() && + migrate_use_xbzrle()) { pages = save_xbzrle_page(rs, &p, current_addr, block, offset, last_stage); if (!last_stage) { @@ -1172,40 +1165,23 @@ static int ram_save_compressed_page(RAMState *rs, PageSearchStatus *pss, p = block->host + offset; - /* When starting the process of a new block, the first page of - * the block should be sent out before other pages in the same - * block, and all the pages in last block should have been sent - * out, keeping this order is important, because the 'cont' flag - * is used to avoid resending the block name. - */ if (block != rs->last_sent_block) { - flush_compressed_data(rs); - pages = save_zero_page(rs, block, offset); - if (pages > 0) { - ram_release_pages(block->idstr, offset, pages); - } else { - /* - * Make sure the first page is sent out before other pages. - * - * we post it as normal page as compression will take much - * CPU resource. - */ - ram_counters.transferred += save_page_header(rs, rs->f, block, - offset | RAM_SAVE_FLAG_PAGE); - qemu_put_buffer_async(rs->f, p, TARGET_PAGE_SIZE, - migrate_release_ram() & - migration_in_postcopy()); - ram_counters.transferred += TARGET_PAGE_SIZE; - ram_counters.normal++; - pages = 1; - } + /* + * Make sure the first page is sent out before other pages. + * + * we post it as normal page as compression will take much + * CPU resource. + */ + ram_counters.transferred += save_page_header(rs, rs->f, block, + offset | RAM_SAVE_FLAG_PAGE); + qemu_put_buffer_async(rs->f, p, TARGET_PAGE_SIZE, + migrate_release_ram() & + migration_in_postcopy()); + ram_counters.transferred += TARGET_PAGE_SIZE; + ram_counters.normal++; + pages = 1; } else { - pages = save_zero_page(rs, block, offset); - if (pages == -1) { - pages = compress_page_with_multi_thread(rs, block, offset); - } else { - ram_release_pages(block->idstr, offset, pages); - } + pages = compress_page_with_multi_thread(rs, block, offset); } return pages; @@ -1447,6 +1423,25 @@ err: return -1; } +static bool save_page_use_compression(RAMState *rs) +{ + if (!migrate_use_compression()) { + return false; + } + + /* + * If xbzrle is on, stop using the data compression after first + * round of migration even if compression is enabled. In theory, + * xbzrle can do better than compression. + */ + if (rs->ram_bulk_stage || !migrate_use_xbzrle()) { + return true; + } + + return false; + +} + /** * ram_save_target_page: save one target page * @@ -1472,12 +1467,31 @@ static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss, } /* - * If xbzrle is on, stop using the data compression after first - * round of migration even if compression is enabled. In theory, - * xbzrle can do better than compression. + * When starting the process of a new block, the first page of + * the block should be sent out before other pages in the same + * block, and all the pages in last block should have been sent + * out, keeping this order is important, because the 'cont' flag + * is used to avoid resending the block name. */ - if (migrate_use_compression() && - (rs->ram_bulk_stage || !migrate_use_xbzrle())) { + if (block != rs->last_sent_block && save_page_use_compression(rs)) { + flush_compressed_data(rs); + } + + res = save_zero_page(rs, block, offset); + if (res > 0) { + /* Must let xbzrle know, otherwise a previous (now 0'd) cached + * page would be stale + */ + if (!save_page_use_compression(rs)) { + XBZRLE_cache_lock(); + xbzrle_cache_zero_page(rs, block->offset + offset); + XBZRLE_cache_unlock(); + } + ram_release_pages(block->idstr, offset, res); + goto page_saved; + } + + if (save_page_use_compression(rs)) { res = ram_save_compressed_page(rs, pss, last_stage); } else { res = ram_save_page(rs, pss, last_stage); From patchwork Tue Mar 13 07:57:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Guangrong X-Patchwork-Id: 885024 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; 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=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ZpqB8vUU"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 400nSX5KGWz9sSf for ; Tue, 13 Mar 2018 19:04:28 +1100 (AEDT) Received: from localhost ([::1]:37464 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evev4-0007pe-KJ for incoming@patchwork.ozlabs.org; Tue, 13 Mar 2018 04:04:26 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43041) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evep5-00033m-AO for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1evep4-0007m1-8J for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:15 -0400 Received: from mail-pf0-x22f.google.com ([2607:f8b0:400e:c00::22f]:45515) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1evep4-0007ku-1G for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:14 -0400 Received: by mail-pf0-x22f.google.com with SMTP id h19so5528900pfd.12 for ; Tue, 13 Mar 2018 00:58:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qkT2r6VMWNa5M5xGmgnsqhXnO84NtFGGtYAS9Fyu7MM=; b=ZpqB8vUUaannXYmYYFFWxWknnwTdepYPGRxD5KQQWmFbcbWJgYLqKUszClDOcRD9GZ XIx/kHRFb36vR7QrWk8OZpf9KdSs/dtQKTKBKohAuYEYcfArVwrt2IsUHRAxCyk0semJ 4q401PahwaFPIaaQTBnJ2lR9ZzsMF9wdwDPGs4t1M7MNF6V4THaOUvnWv4G+UX7ADW7Q rSOZXetIvqV6SUzeSEdhikENhadZJS+O7w7d9qxR/wUt4+JkA6F+/j3RIRSHEHcHXftj IYxEIi9bYPMX12/u1CfXJVH3Wxps3RP/yjtbnLya6f5TKQ0aIwGqUjZfJ1jvXflpLsKa f9VQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=qkT2r6VMWNa5M5xGmgnsqhXnO84NtFGGtYAS9Fyu7MM=; b=AGAvuE4KAqtAwF4dYeJ1qeE11zUrxpIn0aa58d3nWLZyhAidU9FQ9+Y3iE8zutNuBi 4q259XMkOW51tmlZLiNXQhir0IjWkRuzDQybcQuw6sAzGXC69bvlMVvlBdHg7Y8wyN2k gR9vXxfhh8Ueo4ZjZHULpmh9HKX4cxudMQ5exSka2CCIuTwK4yUmXzhdGD29ITLECTyy SQZnyy3uFw+ccNsBtdrJjPQBUQuTdPnFFWoEUkk1352lF8VHGo5orqz1L88SHHNS8hH8 NT22oKFXCjLA6wqWA/jkau5HZ4LUtdkpv1kvAzBrHB3shRe2AEDF/7YI/RR+MtVd5/O+ h+LA== X-Gm-Message-State: AElRT7HkgdUKu2xZiGzNJGTscEg5EnXDeuYGMJRnmwQQDDuJ0vPiYeHt oi81sqbJ56yvKQdf/OCO2O8= X-Google-Smtp-Source: AG47ELsByyLEIp1SldNNLVudsdRa2Jck0fNkaVYYRM46MQKWTGmwwNJy0ZyYHGkzr/Ysmso2xDwDRw== X-Received: by 10.98.232.6 with SMTP id c6mr10686037pfi.242.1520927893157; Tue, 13 Mar 2018 00:58:13 -0700 (PDT) Received: from localhost.localdomain ([203.205.141.35]) by smtp.gmail.com with ESMTPSA id x4sm16756537pgv.72.2018.03.13.00.58.10 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Mar 2018 00:58:12 -0700 (PDT) From: guangrong.xiao@gmail.com X-Google-Original-From: xiaoguangrong@tencent.com To: pbonzini@redhat.com, mst@redhat.com, mtosatti@redhat.com Date: Tue, 13 Mar 2018 15:57:38 +0800 Message-Id: <20180313075739.11194-8-xiaoguangrong@tencent.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180313075739.11194-1-xiaoguangrong@tencent.com> References: <20180313075739.11194-1-xiaoguangrong@tencent.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::22f Subject: [Qemu-devel] [PATCH 7/8] migration: introduce save_normal_page() 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: Xiao Guangrong , qemu-devel@nongnu.org, kvm@vger.kernel.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Xiao Guangrong It directly sends the page to the stream neither checking zero nor using xbzrle or compression Signed-off-by: Xiao Guangrong Reviewed-by: Dr. David Alan Gilbert Reviewed-by: Peter Xu --- migration/ram.c | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/migration/ram.c b/migration/ram.c index 9627ce18e9..f778627992 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -995,6 +995,34 @@ static bool control_save_page(RAMState *rs, RAMBlock *block, ram_addr_t offset, return true; } +/* + * directly send the page to the stream + * + * Returns the number of pages written. + * + * @rs: current RAM state + * @block: block that contains the page we want to send + * @offset: offset inside the block for the page + * @buf: the page to be sent + * @async: send to page asyncly + */ +static int save_normal_page(RAMState *rs, RAMBlock *block, ram_addr_t offset, + uint8_t *buf, bool async) +{ + ram_counters.transferred += save_page_header(rs, rs->f, block, + offset | RAM_SAVE_FLAG_PAGE); + if (async) { + qemu_put_buffer_async(rs->f, buf, TARGET_PAGE_SIZE, + migrate_release_ram() & + migration_in_postcopy()); + } else { + qemu_put_buffer(rs->f, buf, TARGET_PAGE_SIZE); + } + ram_counters.transferred += TARGET_PAGE_SIZE; + ram_counters.normal++; + return 1; +} + /** * ram_save_page: send the given page to the stream * @@ -1035,18 +1063,7 @@ static int ram_save_page(RAMState *rs, PageSearchStatus *pss, bool last_stage) /* XBZRLE overflow or normal page */ if (pages == -1) { - ram_counters.transferred += - save_page_header(rs, rs->f, block, offset | RAM_SAVE_FLAG_PAGE); - if (send_async) { - qemu_put_buffer_async(rs->f, p, TARGET_PAGE_SIZE, - migrate_release_ram() & - migration_in_postcopy()); - } else { - qemu_put_buffer(rs->f, p, TARGET_PAGE_SIZE); - } - ram_counters.transferred += TARGET_PAGE_SIZE; - pages = 1; - ram_counters.normal++; + pages = save_normal_page(rs, block, offset, p, send_async); } XBZRLE_cache_unlock(); @@ -1172,14 +1189,7 @@ static int ram_save_compressed_page(RAMState *rs, PageSearchStatus *pss, * we post it as normal page as compression will take much * CPU resource. */ - ram_counters.transferred += save_page_header(rs, rs->f, block, - offset | RAM_SAVE_FLAG_PAGE); - qemu_put_buffer_async(rs->f, p, TARGET_PAGE_SIZE, - migrate_release_ram() & - migration_in_postcopy()); - ram_counters.transferred += TARGET_PAGE_SIZE; - ram_counters.normal++; - pages = 1; + pages = save_normal_page(rs, block, offset, p, true); } else { pages = compress_page_with_multi_thread(rs, block, offset); } From patchwork Tue Mar 13 07:57:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Guangrong X-Patchwork-Id: 885026 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; 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=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="vPjimVCT"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 400nTg0LNbz9sSf for ; Tue, 13 Mar 2018 19:05:27 +1100 (AEDT) Received: from localhost ([::1]:37468 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evew0-0008UK-UP for incoming@patchwork.ozlabs.org; Tue, 13 Mar 2018 04:05:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43055) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evep8-000348-N6 for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1evep7-0007pq-8D for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:18 -0400 Received: from mail-pf0-x243.google.com ([2607:f8b0:400e:c00::243]:42258) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1evep7-0007p5-2c for qemu-devel@nongnu.org; Tue, 13 Mar 2018 03:58:17 -0400 Received: by mail-pf0-x243.google.com with SMTP id a16so5531824pfn.9 for ; Tue, 13 Mar 2018 00:58:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=CSKV4ZsjZA8tRrRtQklVjRu5ljpTR9hU0naEcvkbxu8=; b=vPjimVCT/qraJAgjygypUUfvV/cqe88sKlNsm07kVf02QGFAP6/ZIHKl3zOmmz9uRm NCjkwGLQDYIZ0csg5FVtTXJwtt92tsmOiyKEjRzbhFDmqHm8YPA/7Od2uuWUZhcsj7NN af4wswjAfoBGndRM22KsUpDJYR0/Z2QU7xilOdwt+kvilVTnbb1SYsiBwx7+niS3tsaV UbZ5mfTihcxnG0JUgixPmjWL2Adsr8RvLdt/gRm/ErvicEDFeBnnaTfmNB4WDIUmgbI8 qWnieFzpBnaaDOGF8tBbkLUcysrtE0lYxOGFhiK5nSXpQqiXwitBf4KdvAjME59V9gf/ 42eg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=CSKV4ZsjZA8tRrRtQklVjRu5ljpTR9hU0naEcvkbxu8=; b=tckEYEP3u+ar1VLR4+xrpCQ0j8UO1zBYczNJgsivXNjIXF0bYugViuGToXxKj7+C+p Y34Uork6FwQvWG5EY7ig/FJX5/a7kH1unoceSukNMkjcA7QnkI2IRqF0hMkZHd+abDjh KXDbVx4Nlt9j95DuwBETBTTfHLsV7Te6aR+COQasyKG71PJ1EedAk7kbG27uf+tDs/sY fQAoNPN+x44iVHjly8pL/pkCTH32+jnwcjxffkH3NfvITLirj0EWnL4EDQNqunB1l3Yh SlqO5nDIO+GFhfuLD2fXk5FkrTXY/JxHg8oh2sRq86zrkyFjTdhgICj9Wo7s3MI+FOIW fXmg== X-Gm-Message-State: AElRT7GjJDKEMvCIaO2oqS7kwKcsIW9AKNhOmPb8hkiFrDv/vdn6ae0a asDFMZ+SIL2WUhFDmxhIBwY= X-Google-Smtp-Source: AG47ELtqSFbLKqHbc55tTWz2UzabCSOIVPx8llKX9L8P5IA6kN7JjEluN9lw15D2SaZ2NMsKExSkOg== X-Received: by 10.98.254.6 with SMTP id z6mr10747909pfh.155.1520927896160; Tue, 13 Mar 2018 00:58:16 -0700 (PDT) Received: from localhost.localdomain ([203.205.141.35]) by smtp.gmail.com with ESMTPSA id x4sm16756537pgv.72.2018.03.13.00.58.13 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Mar 2018 00:58:15 -0700 (PDT) From: guangrong.xiao@gmail.com X-Google-Original-From: xiaoguangrong@tencent.com To: pbonzini@redhat.com, mst@redhat.com, mtosatti@redhat.com Date: Tue, 13 Mar 2018 15:57:39 +0800 Message-Id: <20180313075739.11194-9-xiaoguangrong@tencent.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180313075739.11194-1-xiaoguangrong@tencent.com> References: <20180313075739.11194-1-xiaoguangrong@tencent.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::243 Subject: [Qemu-devel] [PATCH 8/8] migration: remove ram_save_compressed_page() 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: Xiao Guangrong , qemu-devel@nongnu.org, kvm@vger.kernel.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Xiao Guangrong Now, we can reuse the path in ram_save_page() to post the page out as normal, then the only thing remained in ram_save_compressed_page() is compression that we can move it out to the caller Signed-off-by: Xiao Guangrong Reviewed-by: Dr. David Alan Gilbert Reviewed-by: Peter Xu --- migration/ram.c | 45 ++++++++------------------------------------- 1 file changed, 8 insertions(+), 37 deletions(-) diff --git a/migration/ram.c b/migration/ram.c index f778627992..8f4f8aca86 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -1162,41 +1162,6 @@ static int compress_page_with_multi_thread(RAMState *rs, RAMBlock *block, return pages; } -/** - * ram_save_compressed_page: compress the given page and send it to the stream - * - * Returns the number of pages written. - * - * @rs: current RAM state - * @block: block that contains the page we want to send - * @offset: offset inside the block for the page - * @last_stage: if we are at the completion stage - */ -static int ram_save_compressed_page(RAMState *rs, PageSearchStatus *pss, - bool last_stage) -{ - int pages = -1; - uint8_t *p; - RAMBlock *block = pss->block; - ram_addr_t offset = pss->page << TARGET_PAGE_BITS; - - p = block->host + offset; - - if (block != rs->last_sent_block) { - /* - * Make sure the first page is sent out before other pages. - * - * we post it as normal page as compression will take much - * CPU resource. - */ - pages = save_normal_page(rs, block, offset, p, true); - } else { - pages = compress_page_with_multi_thread(rs, block, offset); - } - - return pages; -} - /** * find_dirty_block: find the next dirty page and update any state * associated with the search process. @@ -1501,8 +1466,14 @@ static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss, goto page_saved; } - if (save_page_use_compression(rs)) { - res = ram_save_compressed_page(rs, pss, last_stage); + /* + * Make sure the first page is sent out before other pages. + * + * we post it as normal page as compression will take much + * CPU resource. + */ + if (block == rs->last_sent_block && save_page_use_compression(rs)) { + res = compress_page_with_multi_thread(rs, block, offset); } else { res = ram_save_page(rs, pss, last_stage); }