From nobody Tue Jul 15 05:56:28 2025 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 1486042403918109.78078953427257; Thu, 2 Feb 2017 05:33:23 -0800 (PST) Received: from localhost ([::1]:56584 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cZHVo-0004zk-4C for importer@patchew.org; Thu, 02 Feb 2017 08:33:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46202) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cZHKl-0002cM-OB for qemu-devel@nongnu.org; Thu, 02 Feb 2017 08:21:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cZHKj-0008IA-CS for qemu-devel@nongnu.org; Thu, 02 Feb 2017 08:21:55 -0500 Received: from mailhub.sw.ru ([195.214.232.25]:39024 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cZHKj-0008Fl-1K for qemu-devel@nongnu.org; Thu, 02 Feb 2017 08:21:53 -0500 Received: from kvm.qa.sw.ru. (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v12DLkKc005095; Thu, 2 Feb 2017 16:21:46 +0300 (MSK) From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Thu, 2 Feb 2017 16:21:24 +0300 Message-Id: <20170202132145.168790-4-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170202132145.168790-1-vsementsov@virtuozzo.com> References: <20170202132145.168790-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH 03/24] hbitmap: improve dirty iter 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: kwolf@redhat.com, vsementsov@virtuozzo.com, famz@redhat.com, armbru@redhat.com, mreitz@redhat.com, stefanha@redhat.com, pbonzini@redhat.com, den@openvz.org, jsnow@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" Make dirty iter resistant to resetting bits in corresponding HBitmap. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Max Reitz Reviewed-by: John Snow --- include/qemu/hbitmap.h | 26 ++++---------------------- util/hbitmap.c | 23 ++++++++++++++++++++++- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h index 9239fe515e..6b04391266 100644 --- a/include/qemu/hbitmap.h +++ b/include/qemu/hbitmap.h @@ -256,10 +256,9 @@ void hbitmap_free(HBitmap *hb); * the lowest-numbered bit that is set in @hb, starting at @first. * * Concurrent setting of bits is acceptable, and will at worst cause the - * iteration to miss some of those bits. Resetting bits before the current - * position of the iterator is also okay. However, concurrent resetting of - * bits can lead to unexpected behavior if the iterator has not yet reached - * those bits. + * iteration to miss some of those bits. + * + * The concurrent resetting of bits is OK. */ void hbitmap_iter_init(HBitmapIter *hbi, const HBitmap *hb, uint64_t first= ); =20 @@ -298,24 +297,7 @@ void hbitmap_free_meta(HBitmap *hb); * Return the next bit that is set in @hbi's associated HBitmap, * or -1 if all remaining bits are zero. */ -static inline int64_t hbitmap_iter_next(HBitmapIter *hbi) -{ - unsigned long cur =3D hbi->cur[HBITMAP_LEVELS - 1]; - int64_t item; - - if (cur =3D=3D 0) { - cur =3D hbitmap_iter_skip_words(hbi); - if (cur =3D=3D 0) { - return -1; - } - } - - /* The next call will resume work from the next bit. */ - hbi->cur[HBITMAP_LEVELS - 1] =3D cur & (cur - 1); - item =3D ((uint64_t)hbi->pos << BITS_PER_LEVEL) + ctzl(cur); - - return item << hbi->granularity; -} +int64_t hbitmap_iter_next(HBitmapIter *hbi); =20 /** * hbitmap_iter_next_word: diff --git a/util/hbitmap.c b/util/hbitmap.c index 35088e19c4..0b38817505 100644 --- a/util/hbitmap.c +++ b/util/hbitmap.c @@ -106,8 +106,9 @@ unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi) =20 unsigned long cur; do { - cur =3D hbi->cur[--i]; + i--; pos >>=3D BITS_PER_LEVEL; + cur =3D hbi->cur[i] & hb->levels[i][pos]; } while (cur =3D=3D 0); =20 /* Check for end of iteration. We always use fewer than BITS_PER_LONG @@ -139,6 +140,26 @@ unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi) return cur; } =20 +int64_t hbitmap_iter_next(HBitmapIter *hbi) +{ + unsigned long cur =3D hbi->cur[HBITMAP_LEVELS - 1] & + hbi->hb->levels[HBITMAP_LEVELS - 1][hbi->pos]; + int64_t item; + + if (cur =3D=3D 0) { + cur =3D hbitmap_iter_skip_words(hbi); + if (cur =3D=3D 0) { + return -1; + } + } + + /* The next call will resume work from the next bit. */ + hbi->cur[HBITMAP_LEVELS - 1] =3D cur & (cur - 1); + item =3D ((uint64_t)hbi->pos << BITS_PER_LEVEL) + ctzl(cur); + + return item << hbi->granularity; +} + void hbitmap_iter_init(HBitmapIter *hbi, const HBitmap *hb, uint64_t first) { unsigned i, bit; --=20 2.11.0