[openib-general] Re: [PATCH] Fix ib_pack/unpack for 64 bits

Roland Dreier roland at topspin.com
Thu Jun 23 09:41:09 PDT 2005


    Roland> It's odd that you saw the expession end up as 0.  It seems
    Roland> that on every system I have, 1ull << 64 is 0, and 0 - 1 ==
    Roland> -1 == 0xffffffffffffffff.  So although it isn't correct C,
    Roland> it should work.

Oh, I see.  A constant left shift of 64 is evaluated to 0 at compile
time.  But a variable left shift that ends up as 64 indeed gives the
wrong answer.  So you're right, packer will get the wrong answer.

I think this should fix it properly:

--- core/packer.c	(revision 2665)
+++ core/packer.c	(working copy)
@@ -96,7 +96,7 @@ void ib_pack(const struct ib_field      
 			else
 				val = 0;
 
-			mask = cpu_to_be64(((1ull << desc[i].size_bits) - 1) << shift);
+			mask = cpu_to_be64((~0ull >> (64 - desc[i].size_bits)) << shift);
 			addr = (__be64 *) ((__be32 *) buf + desc[i].offset_words);
 			*addr = (*addr & ~mask) | (cpu_to_be64(val) & mask);
 		} else {
@@ -176,7 +176,7 @@ void ib_unpack(const struct ib_field    
 			__be64 *addr;
 
 			shift = 64 - desc[i].offset_bits - desc[i].size_bits;
-			mask = ((1ull << desc[i].size_bits) - 1) << shift;
+			mask = (~0ull >> (64 - desc[i].size_bits)) << shift;
 			addr = (__be64 *) buf + desc[i].offset_words;
 			val = (be64_to_cpup(addr) & mask) >> shift;
 			value_write(desc[i].struct_offset_bytes,



More information about the general mailing list