From nobody Tue Feb 10 00:23:54 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1498466352742462.53094931190003; Mon, 26 Jun 2017 01:39:12 -0700 (PDT) Received: from localhost ([::1]:45308 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dPPY6-0003hR-U0 for importer@patchew.org; Mon, 26 Jun 2017 04:39:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42078) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dPPV2-0001F7-M6 for qemu-devel@nongnu.org; Mon, 26 Jun 2017 04:36:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dPPUz-0003Ep-7k for qemu-devel@nongnu.org; Mon, 26 Jun 2017 04:36:00 -0400 Received: from mailout2.w1.samsung.com ([210.118.77.12]:49445) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dPPUy-0003EG-Uj for qemu-devel@nongnu.org; Mon, 26 Jun 2017 04:35:57 -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 <0OS5004HWBVU5Y70@mailout2.w1.samsung.com> for qemu-devel@nongnu.org; Mon, 26 Jun 2017 09:35:54 +0100 (BST) Received: from eusmges2.samsung.com (unknown [203.254.199.241]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170626083553eucas1p285e225b9c6cdc41dcf43bfb6bdbe9d5e~LnwcHdBgl1270512705eucas1p2H; Mon, 26 Jun 2017 08:35:53 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges2.samsung.com (EUCPMTA) with SMTP id 15.33.04459.967C0595; Mon, 26 Jun 2017 09:35:53 +0100 (BST) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170626083552eucas1p2db6a8bd9188a95d72aad188d6b633dd9~Lnwba-nT02007020070eucas1p2U; Mon, 26 Jun 2017 08:35:52 +0000 (GMT) Received: from eusync3.samsung.com ( [203.254.199.213]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id EB.ED.20206.867C0595; Mon, 26 Jun 2017 09:35:52 +0100 (BST) Received: from aperevalov-ubuntu.rnd.samsung.ru ([106.109.129.199]) by eusync3.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OS500G3ZBVGGX60@eusync3.samsung.com>; Mon, 26 Jun 2017 09:35:52 +0100 (BST) X-AuditID: cbfec7f1-f796e6d00000116b-22-5950c7695873 From: Alexey Perevalov To: qemu-devel@nongnu.org Date: Mon, 26 Jun 2017 11:35:20 +0300 Message-id: <1498466120-5836-4-git-send-email-a.perevalov@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1498466120-5836-1-git-send-email-a.perevalov@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrNIsWRmVeSWpSXmKPExsWy7djP87qZxwMiDT7M5bWYe/c8i0Xvtnvs Flfaf7JbbNn/jd3ieO8OFos7W/qYHNg8nlzbzOTxft9VNo++LasYA5ijuGxSUnMyy1KL9O0S uDIWdN9lL/jmX7Hu817GBsZd1l2MnBwSAiYSUzvmsEDYYhIX7q1n62Lk4hASWMoosa1rOhOE 85lR4ual5awwHR9aXrNAJJYxSnTue8UI4XQzScyZ9Yu9i5GDg03AQGLfPVuQBhEBSYnfXaeZ QWqYBVoZJdr7HjGD1AgL2EvsXsALUsMioCpxZctLdhCbV8BN4s2bJVDL5CROHpvMClLOKeAu MX0vN8gYCYH7bBJL2t6ygcQlBGQlNh1ghih3kbgxYT8jhC0s8er4FnYIW0bi8uRuFojedkaJ 7p2drBDOBEaJM9P/QlXZS5y6eZUJxGYW4JOYtG06M8QCXomONiGIEg+J24chSiQEHCVud+yD BsQsRoktT6cwTWCUWcDIsIpRJLW0ODc9tdhIrzgxt7g0L10vOT93EyMwSk//O/5xB+P7E1aH GAU4GJV4eA9YB0QKsSaWFVfmHmKU4GBWEuHduA0oxJuSWFmVWpQfX1Sak1p8iFGag0VJnJfr 1LUIIYH0xJLU7NTUgtQimCwTB6dUA6OJ8ntllZ8nItvSZnb/XanX+7vdudzj/It+0Xq2Kf94 eu5EvQ7QtYj/uzNu7/74CjVDnpPillaZf4Jv6+bPaFn/s2Svx+mlX3ZaFSh68jzKSqook/6X p+6Uv9/j8hEv4QUxfyuVZC6cs2yeeLx2H+9C3t38Ji5uz+dZBr9kymqewtcxRexktRJLcUai oRZzUXEiAOBiIATOAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrJLMWRmVeSWpSXmKPExsVy+t/xq7oZxwMiDfa/UrKYe/c8i0Xvtnvs Flfaf7JbbNn/jd3ieO8OFos7W/qYHNg8nlzbzOTxft9VNo++LasYA5ij3GwyUhNTUosUUvOS 81My89JtlUJD3HQtlBTyEnNTbZUidH1DgpQUyhJzSoE8IwM04OAc4B6spG+X4JaxoPsue8E3 /4p1n/cyNjDusu5i5OSQEDCR+NDymgXCFpO4cG89WxcjF4eQwBJGiTt9r6CcXiaJqVOPATkc HGwCBhL77tmCNIgISEr87jrNDFLDLNDKKPGkcRY7SI2wgL3E7gW8IDUsAqoSV7a8ZAexeQXc JN68WcIKsUxO4uSxyawg5ZwC7hLT93KDhIWASh6s2so6gZF3ASPDKkaR1NLi3PTcYiO94sTc 4tK8dL3k/NxNjMBg3Xbs55YdjF3vgg8xCnAwKvHwHrAOiBRiTSwrrsw9xCjBwawkwrtxG1CI NyWxsiq1KD++qDQntfgQoynQTROZpUST84GRlFcSb2hiaG5paGRsYWFuZKQkzjv1w5VwIYH0 xJLU7NTUgtQimD4mDk6pBkaVAPUAZu22twLPZxSonDB8pvggaNZRh0NfbwYst9myv7Hx3JKJ +6e1Mh4/NK+NSy55Ivetazf2ZBYdeW7Z03Hh7EXLR6v7e/eYyZoeVDxU1KetLnGJ3XrZQlmL pzWpTou/1vqG8L+axmjO/XXD2pDz9yNEJZ/NddjzJkdonVt7nL95zy3bdSZKLMUZiYZazEXF iQDkmYlFbAIAAA== X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170626083552eucas1p2db6a8bd9188a95d72aad188d6b633dd9 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: 20170626083552eucas1p2db6a8bd9188a95d72aad188d6b633dd9 X-RootMTR: 20170626083552eucas1p2db6a8bd9188a95d72aad188d6b633dd9 References: <1498466120-5836-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 v4 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+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 | 20 ++++++++++++---- migration/ram.c | 59 ++++++++++++++++++++++++++++++++++++++++++++= +--- migration/ram.h | 6 +++++ 5 files changed, 88 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; }; =20 static inline bool offset_in_ramblock(RAMBlock *b, ram_addr_t offset) @@ -60,6 +62,14 @@ static inline void *ramblock_ptr(RAMBlock *block, ram_ad= dr_t offset) return (char *)block->host + offset; } =20 +static inline unsigned long int ramblock_recv_bitmap_offset(void *host_add= r, + RAMBlock *rb) +{ + uint64_t host_addr_offset =3D + (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..53fbd41 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -143,6 +143,7 @@ MigrationIncomingState *migration_incoming_get_current(= void) qemu_mutex_init(&mis_current.rp_mutex); qemu_event_init(&mis_current.main_thread_load_event, false); once =3D true; + ramblock_recv_map_init(); } return &mis_current; } diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c index 293db97..372c691 100644 --- a/migration/postcopy-ram.c +++ b/migration/postcopy-ram.c @@ -562,22 +562,31 @@ int postcopy_ram_enable_notify(MigrationIncomingState= *mis) } =20 static int qemu_ufd_copy_ioctl(int userfault_fd, void *host_addr, - void *from_addr, uint64_t pagesize) + void *from_addr, uint64_t pagesize, RAMBloc= k *rb) { + int ret; if (from_addr) { struct uffdio_copy copy_struct; copy_struct.dst =3D (uint64_t)(uintptr_t)host_addr; copy_struct.src =3D (uint64_t)(uintptr_t)from_addr; copy_struct.len =3D pagesize; copy_struct.mode =3D 0; - return ioctl(userfault_fd, UFFDIO_COPY, ©_struct); + ret =3D ioctl(userfault_fd, UFFDIO_COPY, ©_struct); } else { struct uffdio_zeropage zero_struct; zero_struct.range.start =3D (uint64_t)(uintptr_t)host_addr; zero_struct.range.len =3D pagesize; zero_struct.mode =3D 0; - return ioctl(userfault_fd, UFFDIO_ZEROPAGE, &zero_struct); + ret =3D ioctl(userfault_fd, UFFDIO_ZEROPAGE, &zero_struct); + } + /* received page isn't feature of blocktime calculation, + * it's more general entity, so keep it here, + * but gup betwean two following operation could be high, + * and in this case blocktime for such small interval will be lost */ + if (!ret) { + ramblock_recv_bitmap_set(host_addr, rb); } + return ret; } =20 /* @@ -594,7 +603,7 @@ int postcopy_place_page(MigrationIncomingState *mis, vo= id *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 =3D errno; error_report("%s: %s copy host: %p from: %p (size: %zd)", __func__, strerror(e), host, from, pagesize); @@ -616,7 +625,8 @@ int postcopy_place_page_zero(MigrationIncomingState *mi= s, void *host, trace_postcopy_place_page_zero(host); =20 if (qemu_ram_pagesize(rb) =3D=3D 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 =3D errno; error_report("%s: %s zero host: %p", __func__, strerror(e), host); diff --git a/migration/ram.c b/migration/ram.c index f50479d..37299ed 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -151,6 +151,34 @@ out: return ret; } =20 +void ramblock_recv_map_init(void) +{ + RAMBlock *rb; + + RAMBLOCK_FOREACH(rb) { + unsigned long pages; + pages =3D rb->max_length >> TARGET_PAGE_BITS; + assert(!rb->receivedmap); + rb->receivedmap =3D bitmap_new(pages); + } +} + +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->receive= dmap); +} + +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 @@ -1773,6 +1801,18 @@ int ram_postcopy_send_discard_bitmap(MigrationState = *ms) return ret; } =20 +static void ramblock_recv_bitmap_clear_range(uint64_t start, size_t length, + RAMBlock *rb) +{ + int i, range_count; + long nr_bit =3D start >> TARGET_PAGE_BITS; + range_count =3D length >> TARGET_PAGE_BITS; + for (i =3D 0; i < range_count; i++) { + clear_bit(nr_bit, rb->receivedmap); + nr_bit +=3D 1; + } +} + /** * ram_discard_range: discard dirtied pages at the beginning of postcopy * @@ -1797,6 +1837,7 @@ int ram_discard_range(const char *rbname, uint64_t st= art, size_t length) goto err; } =20 + ramblock_recv_bitmap_clear_range(start, length, rb); ret =3D ram_block_discard_range(rb, start, length); =20 err: @@ -2324,8 +2365,14 @@ static int ram_load_setup(QEMUFile *f, void *opaque) =20 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 =3D NULL; + } return 0; } =20 @@ -2513,6 +2560,7 @@ static int ram_load(QEMUFile *f, void *opaque, int ve= rsion_id) ram_addr_t addr, total_ram_bytes; void *host =3D NULL; uint8_t ch; + RAMBlock *rb =3D NULL; =20 addr =3D qemu_get_be64(f); flags =3D addr & ~TARGET_PAGE_MASK; @@ -2520,15 +2568,15 @@ static int ram_load(QEMUFile *f, void *opaque, int = version_id) =20 if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE | RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE)) { - RAMBlock *block =3D ram_block_from_stream(f, flags); + rb =3D ram_block_from_stream(f, flags); =20 - host =3D host_from_ram_block_offset(block, addr); + host =3D host_from_ram_block_offset(rb, addr); if (!host) { error_report("Illegal RAM offset " RAM_ADDR_FMT, addr); ret =3D -EINVAL; break; } - trace_ram_load_loop(block->idstr, (uint64_t)addr, flags, host); + trace_ram_load_loop(rb->idstr, (uint64_t)addr, flags, host); } =20 switch (flags & ~RAM_SAVE_FLAG_CONTINUE) { @@ -2582,10 +2630,12 @@ static int ram_load(QEMUFile *f, void *opaque, int = version_id) =20 case RAM_SAVE_FLAG_ZERO: ch =3D qemu_get_byte(f); + ramblock_recv_bitmap_set(host, rb); ram_handle_compressed(host, ch, TARGET_PAGE_SIZE); break; =20 case RAM_SAVE_FLAG_PAGE: + ramblock_recv_bitmap_set(host, rb); qemu_get_buffer(f, host, TARGET_PAGE_SIZE); break; =20 @@ -2596,10 +2646,13 @@ static int ram_load(QEMUFile *f, void *opaque, int = version_id) ret =3D -EINVAL; break; } + + ramblock_recv_bitmap_set(host, rb); decompress_data_with_multi_threads(f, host, len); break; =20 case RAM_SAVE_FLAG_XBZRLE: + ramblock_recv_bitmap_set(host, rb); if (load_xbzrle(f, addr, host) < 0) { error_report("Failed to decompress XBZRLE page at " RAM_ADDR_FMT, addr); 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 s= tart, size_t length); int ram_postcopy_incoming_init(MigrationIncomingState *mis); =20 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 --=20 1.9.1