From nobody Sun May 5 17:11:03 2024 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 1488961779193705.7336247981411; Wed, 8 Mar 2017 00:29:39 -0800 (PST) Received: from localhost ([::1]:54825 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1clWyX-0007Dr-PE for importer@patchew.org; Wed, 08 Mar 2017 03:29:37 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56204) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1clWy5-0007DG-HR for qemu-devel@nongnu.org; Wed, 08 Mar 2017 03:29:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1clWy1-0006nv-I6 for qemu-devel@nongnu.org; Wed, 08 Mar 2017 03:29:09 -0500 Received: from [59.151.112.132] (port=52016 helo=heian.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1clWxz-0006mn-Pe for qemu-devel@nongnu.org; Wed, 08 Mar 2017 03:29:05 -0500 Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 08 Mar 2017 16:28:43 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id 800814871CE1; Wed, 8 Mar 2017 16:28:39 +0800 (CST) Received: from localhost (10.167.226.75) by G08CNEXCHPEKD01.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server id 14.3.319.2; Wed, 8 Mar 2017 16:28:39 +0800 X-IronPort-AV: E=Sophos;i="5.22,518,1449504000"; d="scan'208";a="16330432" From: Chao Fan To: , , , , Date: Wed, 8 Mar 2017 16:28:19 +0800 Message-ID: <20170308082819.12196-1-fanc.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.9.3 MIME-Version: 1.0 X-yoursite-MailScanner-ID: 800814871CE1.A9C1A X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: fanc.fnst@cn.fujitsu.com X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 59.151.112.132 Subject: [Qemu-devel] [PATCH v2] Add inst_dirty_pages_rate in 'info migrate' 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: douly.fnst@cn.fujitsu.com, caoj.fnst@cn.fujitsu.com, Chao Fan , maozy.fnst@cn.fujitsu.com, lizhijian@cn.fujitsu.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 Content-Type: text/plain; charset="utf-8" Auto-converge aims to accelerate migration by slowing down the generation of dirty pages. But user doesn't know how to determine the throttle value, so, a new item "inst-dirty-pages-rate" in "info migrate" would be helpful for user's determination. Signed-off-by: Chao Fan --- v2: Update the way to caculate the time. Add tag '(since 2.9)' in documentation of qapi-schema.json --- hmp.c | 4 ++++ include/migration/migration.h | 1 + include/qemu/bitmap.h | 17 ++++++++++++++++ migration/migration.c | 2 ++ migration/ram.c | 45 +++++++++++++++++++++++++++++++++++++++= ++++ qapi-schema.json | 4 ++++ 6 files changed, 73 insertions(+) diff --git a/hmp.c b/hmp.c index 2bc4f06..c7892ea 100644 --- a/hmp.c +++ b/hmp.c @@ -219,6 +219,10 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict) monitor_printf(mon, "dirty pages rate: %" PRIu64 " pages\n", info->ram->dirty_pages_rate); } + if (info->ram->inst_dirty_pages_rate) { + monitor_printf(mon, "inst dirty pages rate: %" PRIu64 " bytes/= s\n", + info->ram->inst_dirty_pages_rate); + } if (info->ram->postcopy_requests) { monitor_printf(mon, "postcopy request count: %" PRIu64 "\n", info->ram->postcopy_requests); diff --git a/include/migration/migration.h b/include/migration/migration.h index 1735d66..95f0453 100644 --- a/include/migration/migration.h +++ b/include/migration/migration.h @@ -164,6 +164,7 @@ struct MigrationState int64_t downtime; int64_t expected_downtime; int64_t dirty_pages_rate; + int64_t inst_dirty_pages_rate; int64_t dirty_bytes_rate; bool enabled_capabilities[MIGRATION_CAPABILITY__MAX]; int64_t xbzrle_cache_size; diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h index 63ea2d0..dc99f9b 100644 --- a/include/qemu/bitmap.h +++ b/include/qemu/bitmap.h @@ -235,4 +235,21 @@ static inline unsigned long *bitmap_zero_extend(unsign= ed long *old, return new; } =20 +static inline unsigned long bitmap_weight(const unsigned long *src, long n= bits) +{ + unsigned long i, count =3D 0, nlong =3D nbits / BITS_PER_LONG; + + if (small_nbits(nbits)) { + return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits)); + } + for (i =3D 0; i < nlong; i++) { + count +=3D hweight_long(src[i]); + } + if (nbits % BITS_PER_LONG) { + count +=3D hweight_long(src[i] & BITMAP_LAST_WORD_MASK(nbits)); + } + + return count; +} + #endif /* BITMAP_H */ diff --git a/migration/migration.c b/migration/migration.c index c6ae69d..18fc2ec 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -644,6 +644,7 @@ static void populate_ram_info(MigrationInfo *info, Migr= ationState *s) if (s->state !=3D MIGRATION_STATUS_COMPLETED) { info->ram->remaining =3D ram_bytes_remaining(); info->ram->dirty_pages_rate =3D s->dirty_pages_rate; + info->ram->inst_dirty_pages_rate =3D s->inst_dirty_pages_rate; } } =20 @@ -1099,6 +1100,7 @@ MigrationState *migrate_init(const MigrationParams *p= arams) s->downtime =3D 0; s->expected_downtime =3D 0; s->dirty_pages_rate =3D 0; + s->inst_dirty_pages_rate =3D 0; s->dirty_bytes_rate =3D 0; s->setup_time =3D 0; s->dirty_sync_count =3D 0; diff --git a/migration/ram.c b/migration/ram.c index f289fcd..7b440fd 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -44,6 +44,7 @@ #include "exec/ram_addr.h" #include "qemu/rcu_queue.h" #include "migration/colo.h" +#include "hw/boards.h" =20 static int dirty_rate_high_cnt; =20 @@ -590,6 +591,7 @@ static int64_t bytes_xfer_prev; static int64_t num_dirty_pages_period; static uint64_t xbzrle_cache_miss_prev; static uint64_t iterations_prev; +static int64_t dirty_pages_time_prev; =20 static void migration_bitmap_sync_init(void) { @@ -598,6 +600,47 @@ static void migration_bitmap_sync_init(void) num_dirty_pages_period =3D 0; xbzrle_cache_miss_prev =3D 0; iterations_prev =3D 0; + dirty_pages_time_prev =3D 0; +} + +static void migration_inst_rate(void) +{ + int64_t dirty_pages_time_now; + if (!dirty_pages_time_prev) { + dirty_pages_time_prev =3D qemu_clock_get_ms(QEMU_CLOCK_REALTIME); + } + dirty_pages_time_now =3D qemu_clock_get_ms(QEMU_CLOCK_REALTIME); + if (dirty_pages_time_now > dirty_pages_time_prev + 1000) { + RAMBlock *block; + MigrationState *s =3D migrate_get_current(); + int64_t inst_dirty_pages =3D 0; + int64_t i; + unsigned long *num; + unsigned long len =3D 0; + + rcu_read_lock(); + DirtyMemoryBlocks *blocks =3D atomic_rcu_read( + &ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION]); + QLIST_FOREACH_RCU(block, &ram_list.blocks, next) { + if (len =3D=3D 0) { + len =3D block->offset; + } + len +=3D block->used_length; + } + ram_addr_t idx =3D (len >> TARGET_PAGE_BITS) / DIRTY_MEMORY_BLOCK_= SIZE; + if (((len >> TARGET_PAGE_BITS) % DIRTY_MEMORY_BLOCK_SIZE) !=3D 0) { + idx++; + } + for (i =3D 0; i < idx; i++) { + num =3D blocks->blocks[i]; + inst_dirty_pages +=3D bitmap_weight(num, DIRTY_MEMORY_BLOCK_SI= ZE); + } + rcu_read_unlock(); + + s->inst_dirty_pages_rate =3D inst_dirty_pages * TARGET_PAGE_SIZE * + 1000 / (dirty_pages_time_now - dirty_pages_time_prev); + } + dirty_pages_time_prev =3D dirty_pages_time_now; } =20 static void migration_bitmap_sync(void) @@ -621,6 +664,8 @@ static void migration_bitmap_sync(void) trace_migration_bitmap_sync_start(); memory_global_dirty_log_sync(); =20 + migration_inst_rate(); + qemu_mutex_lock(&migration_bitmap_mutex); rcu_read_lock(); QLIST_FOREACH_RCU(block, &ram_list.blocks, next) { diff --git a/qapi-schema.json b/qapi-schema.json index e9a6364..bf00717 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -575,12 +575,16 @@ # @postcopy-requests: The number of page requests received from the destin= ation # (since 2.7) # +# @inst-dirty-pages-rate: The number of bytes new dirtied pages by second. +# (since 2.9) +# # Since: 0.14.0 ## { 'struct': 'MigrationStats', 'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' , 'duplicate': 'int', 'skipped': 'int', 'normal': 'int', 'normal-bytes': 'int', 'dirty-pages-rate' : 'int', + 'inst-dirty-pages-rate' : 'int', 'mbps' : 'number', 'dirty-sync-count' : 'int', 'postcopy-requests' : 'int' } } =20 --=20 2.9.3