From patchwork Wed Jun 28 12:49:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Perevalov X-Patchwork-Id: 781679 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3wyNHD4H8Vz9s0g for ; Wed, 28 Jun 2017 23:02:16 +1000 (AEST) Received: from localhost ([::1]:33258 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dQCbm-00068Y-9R for incoming@patchwork.ozlabs.org; Wed, 28 Jun 2017 09:02:14 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48367) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dQCSY-0005sT-H8 for qemu-devel@nongnu.org; Wed, 28 Jun 2017 08:52:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dQCST-00033C-Kl for qemu-devel@nongnu.org; Wed, 28 Jun 2017 08:52:42 -0400 Received: from mailout2.w1.samsung.com ([210.118.77.12]:33719) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dQCST-00032b-Cc for qemu-devel@nongnu.org; Wed, 28 Jun 2017 08:52:37 -0400 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout2.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OS900F9CD3LTK30@mailout2.w1.samsung.com> for qemu-devel@nongnu.org; Wed, 28 Jun 2017 13:52:33 +0100 (BST) Received: from eusmges4.samsung.com (unknown [203.254.199.244]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170628125232eucas1p2e7430ff9efac491dbd0c6139ba26d29c~MSjGdSmUl1018210182eucas1p2p; Wed, 28 Jun 2017 12:52:32 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges4.samsung.com (EUCPMTA) with SMTP id 78.92.04729.096A3595; Wed, 28 Jun 2017 13:52:32 +0100 (BST) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170628125232eucas1p1af5a7b0d734c7af25a20981e25812ee2~MSjFqYtIz2933029330eucas1p1Z; Wed, 28 Jun 2017 12:52:32 +0000 (GMT) X-AuditID: cbfec7f4-f79806d000001279-73-5953a690210f Received: from eusync2.samsung.com ( [203.254.199.212]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 7A.1D.20206.F86A3595; Wed, 28 Jun 2017 13:52:31 +0100 (BST) Received: from minion.rnd.samsung.ru ([106.109.131.134]) by eusync2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OS900J3VD2QR510@eusync2.samsung.com>; Wed, 28 Jun 2017 13:52:31 +0100 (BST) From: Alexey Perevalov To: qemu-devel@nongnu.org Date: Wed, 28 Jun 2017 08:49:32 -0400 Message-id: <1498654172-26570-4-git-send-email-a.perevalov@samsung.com> X-Mailer: git-send-email 1.8.3.1 In-reply-to: <1498654172-26570-1-git-send-email-a.perevalov@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrLIsWRmVeSWpSXmKPExsWy7djP87oTlgVHGqx4rGkx9+55FovebffY La60/2S32LL/G7vF8d4dLBZ3tvQxObB5PLm2mcnj/b6rbB59W1YxBjBHcdmkpOZklqUW6dsl cGXsae1gL1jnWLG5bTt7A+NLwy5GTg4JAROJExe2M0LYYhIX7q1n62Lk4hASWMoo8fPhAWYI 5zOjRP+cI+wwHZdnbWCESCxjlHje2csE4TQwSdybMgOon4ODTcBAYt89W5AGEQFJid9dp8Em MQu0Mkq09z1iBkkIC9hLnJ7/mhXEZhFQlVjaMgUszivgLrFu8leomxQkpjx8DxbnFPCQOLxg ASvIIAmB+2wSfVveMYEskxCQldh0gBmi3kXi+5NONghbWOLV8S1QV8tIXJ7czQLR284o0b2z E2rQBEaJM9P/QlXZS5y6eZUJxGYW4JOYtG06M8QCXomONiGIEg+JSZtesUDYjhJPHz+HBths RokFTyexTmCUWcDIsIpRJLW0ODc9tdhErzgxt7g0L10vOT93EyMwUk//O/5lB+PiY1aHGAU4 GJV4eFeIBEcKsSaWFVfmHmKU4GBWEuFtXQgU4k1JrKxKLcqPLyrNSS0+xCjNwaIkzst16lqE kEB6YklqdmpqQWoRTJaJg1OqgXHyW67o3g9B0+cE78xZseKB6H4boZqPz54Fvy+59etxd/S3 IxwR11/vz9/AOCXr7QGdTQ87UzLday6fqznOMb0y6t16Xp7rZrot+u39L7gUnwh8Fgo+ma/+ +9S8G4sK39xKfCLPME0+QLpElF1XkbtkaceLJmmuHXH1PmeYY/YVvQu/Pa9Xm0eJpTgj0VCL uag4EQCO6E5E0AIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrNLMWRmVeSWpSXmKPExsVy+t/xK7r9y4IjDX5sMbGYe/c8i0Xvtnvs Flfaf7JbbNn/jd3ieO8OFos7W/qYHNg8nlzbzOTxft9VNo++LasYA5ij3GwyUhNTUosUUvOS 81My89JtlUJD3HQtlBTyEnNTbZUidH1DgpQUyhJzSoE8IwM04OAc4B6spG+X4Jaxp7WDvWCd Y8Xmtu3sDYwvDbsYOTkkBEwkLs/awAhhi0lcuLeerYuRi0NIYAmjxI8rixkhnCYmif7/h5i6 GDk42AQMJPbdswVpEBGQlPjddZoZpIZZoJVR4knjLHaQhLCAvcTp+a9ZQWwWAVWJpS1TmEFs XgF3iXWTv0JtU5CY8vA9WJxTwEPi8IIFYPVCQDXP99xinMDIu4CRYRWjSGppcW56brGRXnFi bnFpXrpecn7uJkZgwG479nPLDsaud8GHGAU4GJV4eFeIBEcKsSaWFVfmHmKU4GBWEuFtXQgU 4k1JrKxKLcqPLyrNSS0+xGgKdNREZinR5HxgNOWVxBuaGJpbGhoZW1iYGxkpifNO/XAlXEgg PbEkNTs1tSC1CKaPiYNTqoFxKmuENN8T5uCNnl38kg8fPP3Wn2B41vOc2YYCbmXWGSbW8gXq Zz+dnxbNNSHz3rRreqGTF7cFFaofSDvJqSg4a1VZ/Vpe1bxt4fbV612MslOtt8h11a3VKnmy t8CSJ7HxyaK1vy812XIfYU7SZldRVTvS9WFlWcXZE79iveQYvgce4p/6YLUSS3FGoqEWc1Fx IgDGAR/PbgIAAA== X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170628125232eucas1p1af5a7b0d734c7af25a20981e25812ee2 X-Msg-Generator: CA X-Sender-IP: 182.198.249.180 X-Local-Sender: =?UTF-8?B?QWxleGV5IFBlcmV2YWxvdhtTUlItVmlydHVhbGl6YXRpb24g?= =?UTF-8?B?TGFiG+yCvOyEseyghOyekBtTZW5pb3IgRW5naW5lZXI=?= X-Global-Sender: =?UTF-8?B?QWxleGV5IFBlcmV2YWxvdhtTUlItVmlydHVhbGl6YXRpb24g?= =?UTF-8?B?TGFiG1NhbXN1bmcgRWxlY3Ryb25pY3MbU2VuaW9yIEVuZ2luZWVy?= X-Sender-Code: =?UTF-8?B?QzEwG0NJU0hRG0MxMEdEMDFHRDAxMDE1NA==?= CMS-TYPE: 201P X-HopCount: 7 X-CMS-RootMailID: 20170628125232eucas1p1af5a7b0d734c7af25a20981e25812ee2 X-RootMTR: 20170628125232eucas1p1af5a7b0d734c7af25a20981e25812ee2 References: <1498654172-26570-1-git-send-email-a.perevalov@samsung.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 210.118.77.12 Subject: [Qemu-devel] [PATCH v6 3/3] migration: add bitmap for received 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: i.maximets@samsung.com, dgilbert@redhat.com, Alexey Perevalov , peterx@redhat.com, quintela@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch adds ability to track down already received pages, it's necessary for calculation vCPU block time in postcopy migration feature, maybe for restore after postcopy migration failure. Also it's necessary to solve shared memory issue in postcopy livemigration. Information about received pages will be transferred to the software virtual bridge (e.g. OVS-VSWITCHD), to avoid fallocate (unmap) for already received pages. fallocate syscall is required for remmaped shared memory, due to remmaping itself blocks ioctl(UFFDIO_COPY, ioctl in this case will end with EEXIT error (struct page is exists after remmap). Bitmap is placed into RAMBlock as another postcopy/precopy related bitmaps. Signed-off-by: Alexey Perevalov --- include/exec/ram_addr.h | 10 ++++++++++ migration/migration.c | 1 + migration/postcopy-ram.c | 16 +++++++++++----- migration/ram.c | 42 +++++++++++++++++++++++++++++++++++++++--- migration/ram.h | 6 ++++++ 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index 140efa8..4170656 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -47,6 +47,8 @@ struct RAMBlock { * of the postcopy phase */ unsigned long *unsentmap; + /* bitmap of already received pages in postcopy */ + unsigned long *receivedmap; }; static inline bool offset_in_ramblock(RAMBlock *b, ram_addr_t offset) @@ -60,6 +62,14 @@ static inline void *ramblock_ptr(RAMBlock *block, ram_addr_t offset) return (char *)block->host + offset; } +static inline unsigned long int ramblock_recv_bitmap_offset(void *host_addr, + RAMBlock *rb) +{ + uint64_t host_addr_offset = + (uint64_t)(uintptr_t)(host_addr - (void *)rb->host); + return host_addr_offset >> TARGET_PAGE_BITS; +} + long qemu_getrampagesize(void); unsigned long last_ram_page(void); RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr, diff --git a/migration/migration.c b/migration/migration.c index 71e38bc..63ded8c 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -363,6 +363,7 @@ void migration_fd_process_incoming(QEMUFile *f) Coroutine *co = qemu_coroutine_create(process_incoming_migration_co, f); qemu_file_set_blocking(f, false); + ramblock_recv_map_init(); qemu_coroutine_enter(co); } diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c index 293db97..f980d93 100644 --- a/migration/postcopy-ram.c +++ b/migration/postcopy-ram.c @@ -562,22 +562,27 @@ int postcopy_ram_enable_notify(MigrationIncomingState *mis) } static int qemu_ufd_copy_ioctl(int userfault_fd, void *host_addr, - void *from_addr, uint64_t pagesize) + void *from_addr, uint64_t pagesize, RAMBlock *rb) { + int ret; if (from_addr) { struct uffdio_copy copy_struct; copy_struct.dst = (uint64_t)(uintptr_t)host_addr; copy_struct.src = (uint64_t)(uintptr_t)from_addr; copy_struct.len = pagesize; copy_struct.mode = 0; - return ioctl(userfault_fd, UFFDIO_COPY, ©_struct); + ret = ioctl(userfault_fd, UFFDIO_COPY, ©_struct); } else { struct uffdio_zeropage zero_struct; zero_struct.range.start = (uint64_t)(uintptr_t)host_addr; zero_struct.range.len = pagesize; zero_struct.mode = 0; - return ioctl(userfault_fd, UFFDIO_ZEROPAGE, &zero_struct); + ret = ioctl(userfault_fd, UFFDIO_ZEROPAGE, &zero_struct); + } + if (!ret) { + ramblock_recv_bitmap_set(host_addr, rb); } + return ret; } /* @@ -594,7 +599,7 @@ int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from, * which would be slightly cheaper, but we'd have to be careful * of the order of updating our page state. */ - if (qemu_ufd_copy_ioctl(mis->userfault_fd, host, from, pagesize)) { + if (qemu_ufd_copy_ioctl(mis->userfault_fd, host, from, pagesize, rb)) { int e = errno; error_report("%s: %s copy host: %p from: %p (size: %zd)", __func__, strerror(e), host, from, pagesize); @@ -616,7 +621,8 @@ int postcopy_place_page_zero(MigrationIncomingState *mis, void *host, trace_postcopy_place_page_zero(host); if (qemu_ram_pagesize(rb) == getpagesize()) { - if (qemu_ufd_copy_ioctl(mis->userfault_fd, host, NULL, getpagesize())) { + if (qemu_ufd_copy_ioctl(mis->userfault_fd, host, NULL, getpagesize(), + rb)) { int e = errno; error_report("%s: %s zero host: %p", __func__, strerror(e), host); diff --git a/migration/ram.c b/migration/ram.c index f50479d..95962a0 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -151,6 +151,32 @@ out: return ret; } +void ramblock_recv_map_init(void) +{ + RAMBlock *rb; + + RAMBLOCK_FOREACH(rb) { + assert(!rb->receivedmap); + rb->receivedmap = bitmap_new(rb->max_length >> TARGET_PAGE_BITS); + } +} + +int ramblock_recv_bitmap_test(void *host_addr, RAMBlock *rb) +{ + return test_bit(ramblock_recv_bitmap_offset(host_addr, rb), + rb->receivedmap); +} + +void ramblock_recv_bitmap_set(void *host_addr, RAMBlock *rb) +{ + set_bit_atomic(ramblock_recv_bitmap_offset(host_addr, rb), rb->receivedmap); +} + +void ramblock_recv_bitmap_clear(void *host_addr, RAMBlock *rb) +{ + clear_bit(ramblock_recv_bitmap_offset(host_addr, rb), rb->receivedmap); +} + /* * An outstanding page request, on the source, having been received * and queued @@ -1797,6 +1823,8 @@ int ram_discard_range(const char *rbname, uint64_t start, size_t length) goto err; } + bitmap_clear(rb->receivedmap, start >> TARGET_PAGE_BITS, + length >> TARGET_PAGE_BITS); ret = ram_block_discard_range(rb, start, length); err: @@ -2324,8 +2352,14 @@ static int ram_load_setup(QEMUFile *f, void *opaque) static int ram_load_cleanup(void *opaque) { + RAMBlock *rb; xbzrle_load_cleanup(); compress_threads_load_cleanup(); + + RAMBLOCK_FOREACH(rb) { + g_free(rb->receivedmap); + rb->receivedmap = NULL; + } return 0; } @@ -2513,6 +2547,7 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) ram_addr_t addr, total_ram_bytes; void *host = NULL; uint8_t ch; + RAMBlock *rb = NULL; addr = qemu_get_be64(f); flags = addr & ~TARGET_PAGE_MASK; @@ -2520,15 +2555,16 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE | RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE)) { - RAMBlock *block = ram_block_from_stream(f, flags); + rb = ram_block_from_stream(f, flags); - host = host_from_ram_block_offset(block, addr); + host = host_from_ram_block_offset(rb, addr); if (!host) { error_report("Illegal RAM offset " RAM_ADDR_FMT, addr); ret = -EINVAL; break; } - trace_ram_load_loop(block->idstr, (uint64_t)addr, flags, host); + ramblock_recv_bitmap_set(host, rb); + trace_ram_load_loop(rb->idstr, (uint64_t)addr, flags, host); } switch (flags & ~RAM_SAVE_FLAG_CONTINUE) { diff --git a/migration/ram.h b/migration/ram.h index c081fde..98d68df 100644 --- a/migration/ram.h +++ b/migration/ram.h @@ -52,4 +52,10 @@ int ram_discard_range(const char *block_name, uint64_t start, size_t length); int ram_postcopy_incoming_init(MigrationIncomingState *mis); void ram_handle_compressed(void *host, uint8_t ch, uint64_t size); + +void ramblock_recv_map_init(void); +int ramblock_recv_bitmap_test(void *host_addr, RAMBlock *rb); +void ramblock_recv_bitmap_set(void *host_addr, RAMBlock *rb); +void ramblock_recv_bitmap_clear(void *host_addr, RAMBlock *rb); + #endif