KVM: x86: lapic: Clean up find_highest_vector() and count_vectors()
authorTakuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Wed, 5 Sep 2012 10:30:01 +0000 (19:30 +0900)
committerMarcelo Tosatti <mtosatti@redhat.com>
Wed, 12 Sep 2012 16:38:23 +0000 (13:38 -0300)
find_highest_vector() and count_vectors():
 - Instead of using magic values, define and use proper macros.

find_highest_vector():
 - Remove likely() which is there only for historical reasons and not
   doing correct branch predictions anymore.  Using such heuristics
   to optimize this function is not worth it now.  Let CPUs predict
   things instead.

 - Stop checking word[0] separately.  This was only needed for doing
   likely() optimization.

 - Use for loop, not while, to iterate over the register array to make
   the code clearer.

Note that we actually confirmed that the likely() did wrong predictions
by inserting debug code.

Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
arch/x86/kvm/lapic.c

index 07ad628dadb7e87517ea2fe524f32f12e583033b..6f9fd633c8884e2ae04dec3bd3c9ef5dc97168a2 100644 (file)
@@ -66,6 +66,7 @@
 #define APIC_DEST_NOSHORT              0x0
 #define APIC_DEST_MASK                 0x800
 #define MAX_APIC_VECTOR                        256
+#define APIC_VECTORS_PER_REG           32
 
 #define VEC_POS(v) ((v) & (32 - 1))
 #define REG_POS(v) (((v) >> 5) << 4)
@@ -208,25 +209,30 @@ static const unsigned int apic_lvt_mask[APIC_LVT_NUM] = {
 
 static int find_highest_vector(void *bitmap)
 {
-       u32 *word = bitmap;
-       int word_offset = MAX_APIC_VECTOR >> 5;
+       int vec;
+       u32 *reg;
 
-       while ((word_offset != 0) && (word[(--word_offset) << 2] == 0))
-               continue;
+       for (vec = MAX_APIC_VECTOR - APIC_VECTORS_PER_REG;
+            vec >= 0; vec -= APIC_VECTORS_PER_REG) {
+               reg = bitmap + REG_POS(vec);
+               if (*reg)
+                       return fls(*reg) - 1 + vec;
+       }
 
-       if (likely(!word_offset && !word[0]))
-               return -1;
-       else
-               return fls(word[word_offset << 2]) - 1 + (word_offset << 5);
+       return -1;
 }
 
 static u8 count_vectors(void *bitmap)
 {
-       u32 *word = bitmap;
-       int word_offset;
+       int vec;
+       u32 *reg;
        u8 count = 0;
-       for (word_offset = 0; word_offset < MAX_APIC_VECTOR >> 5; ++word_offset)
-               count += hweight32(word[word_offset << 2]);
+
+       for (vec = 0; vec < MAX_APIC_VECTOR; vec += APIC_VECTORS_PER_REG) {
+               reg = bitmap + REG_POS(vec);
+               count += hweight32(*reg);
+       }
+
        return count;
 }