From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59381) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y9KmI-0008UZ-Fn for qemu-devel@nongnu.org; Thu, 08 Jan 2015 16:38:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Y9KmF-0008K3-7I for qemu-devel@nongnu.org; Thu, 08 Jan 2015 16:38:02 -0500 Received: from mx1.redhat.com ([209.132.183.28]:40692) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y9KmE-0008Js-UC for qemu-devel@nongnu.org; Thu, 08 Jan 2015 16:37:59 -0500 Message-ID: <54AEF8AE.7070607@redhat.com> Date: Thu, 08 Jan 2015 22:37:50 +0100 From: Paolo Bonzini MIME-Version: 1.0 References: <1418307457-25996-1-git-send-email-vsementsov@parallels.com> <1418307457-25996-5-git-send-email-vsementsov@parallels.com> <54AEF4E8.5070106@redhat.com> In-Reply-To: <54AEF4E8.5070106@redhat.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit Subject: Re: [Qemu-devel] [PATCH 4/9] hbitmap: store / restore List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: John Snow , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org Cc: kwolf@redhat.com, den@openvz.org, stefanha@redhat.com On 08/01/2015 22:21, John Snow wrote: > Why are the conversions to little endian, though? Shouldn't we be > serializing to a Big Endian format? Because reading two 32-bit little-endian longs or a 64-bit little-endian long gives the same value. This is not true for big-endian. Take the following two 32-bit values: 0x04030201 0x08070605 representing offsets 0 and 32 in the bitmap. Parse them back as one 64-bit little endian value: 0x0807060504030201 = 0x04030201 + 0x08070605 * 2^32 Now parse them as as one 64-bit big endian value: 0x0403020108070605 => 0x08070605 + 0x04030201 * 2^32 so the values are swapped. >> +void hbitmap_restore_data(HBitmap *hb, uint8_t *buf, >> + uint64_t start, uint64_t count) >> +{ >> + uint64_t last = start + count - 1; >> + unsigned long *in = (unsigned long *)buf; >> + >> + if (count == 0) { >> + return; >> + } >> + >> + start = (start >> hb->granularity) >> BITS_PER_LEVEL; >> + last = (last >> hb->granularity) >> BITS_PER_LEVEL; >> + count = last - start + 1; >> + >> +#ifdef __BIG_ENDIAN_BITFIELD >> + for (i = start; i <= last; ++i) { >> + hb->levels[HBITMAP_LEVELS - 1][i] = >> + (BITS_PER_LONG == 32 ? be32_to_cpu(in[i]) : >> be64_to_cpu(in[i])); >> + } >> +#else >> + memcpy(&hb->levels[HBITMAP_LEVELS - 1][start], in, >> + count * sizeof(unsigned long)); >> +#endif >> +} >> + > > ...? We're storing as LE but restoring from BE? I'm confused. > > I'm also not clear on the __BIG_ENDIAN_BITFIELD macro. Why do we want to > pack differently based on how C-bitfields are packed by the compiler? I > don't think that has any impact on how longs are stored (always in the > host native format.) I agree. Paolo