|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] x86/bitops: Replace __scanbit() with a simpler tzcnt()
There are 4 remaining users of __scanbit(), and they're capable of dealing
with max being BITS_PER_LONG. Switch to a simpler tzcnt() helper, which also
removed some alternatives from behind the scenes.
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <jbeulich@xxxxxxxx>
CC: Roger Pau Monné <roger@xxxxxxxxxxxxxx>
CC: Teddy Astie <teddy.astie@xxxxxxxxxx>
Supercedes "x86/bitops: Improve code generation for __scanbit()"
Bloat-o-meter shows rather less churn:
add/remove: 1/0 grow/shrink: 9/18 up/down: 244/-279 (-35)
Function old new delta
is_cpu_primary - 88 +88
vmap_size 38 91 +53
get_outstanding_claims 198 214 +16
csched2_unit_insert 413 429 +16
csched2_schedule 5371 5387 +16
__cpu_disable 583 599 +16
memory_add 4036 4049 +13
csched2_alloc_domdata 476 487 +11
numa_init_array 153 161 +8
dump_execstate 221 228 +7
dump_numa 471 469 -2
csched2_res_pick 1351 1349 -2
csched_schedule 3790 3786 -4
fixup_irqs 1655 1650 -5
dump_numa.cold 977 970 -7
cpupool_assign_cpu_locked 410 403 -7
_assign_irq_vector 1571 1564 -7
vmx_sync_exit_bitmap 73 65 -8
numa_emulation 487 479 -8
__find_next_zero_bit 145 137 -8
get_free_buddy 1014 1005 -9
runq_tickle 1753 1737 -16
node_to_scrub 533 517 -16
dom0_compute_nr_pages 1424 1408 -16
sched_init_vcpu 1811 1791 -20
microcode_nmi_callback 300 260 -40
heap_init_late 1659 1611 -48
do_microcode_update 1014 958 -56
Total: Before=2013616, After=2013581, chg -0.00%
add/remove: 0/0 grow/shrink: 3/0 up/down: 36/0 (36)
Data old new delta
symbols_names 134797 134817 +20
symbols_sorted_offsets 69368 69376 +8
symbols_offsets 53456 53464 +8
For things like vmap_size() what has happened is that vm_size() has now been
inlined.
---
xen/arch/x86/bitops.c | 4 ++--
xen/arch/x86/include/asm/bitops.h | 31 ++++++++++++++++++-------------
2 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/xen/arch/x86/bitops.c b/xen/arch/x86/bitops.c
index 22cfb6d8ec3a..348e51202465 100644
--- a/xen/arch/x86/bitops.c
+++ b/xen/arch/x86/bitops.c
@@ -35,7 +35,7 @@ unsigned int __find_next_bit(
if ( bit != 0 )
{
/* Look for a bit in the first word. */
- set = __scanbit(*p >> bit, BITS_PER_LONG);
+ set = tzcnt(*p >> bit);
if ( set < BITS_PER_LONG )
return (offset + set);
offset += BITS_PER_LONG - bit;
@@ -85,7 +85,7 @@ unsigned int __find_next_zero_bit(
if ( bit != 0 )
{
/* Look for zero in the first word. */
- set = __scanbit(~*p >> bit, BITS_PER_LONG);
+ set = tzcnt(~*p >> bit);
if ( set < BITS_PER_LONG )
return (offset + set);
offset += BITS_PER_LONG - bit;
diff --git a/xen/arch/x86/include/asm/bitops.h
b/xen/arch/x86/include/asm/bitops.h
index 557cee03baeb..f880d16a982f 100644
--- a/xen/arch/x86/include/asm/bitops.h
+++ b/xen/arch/x86/include/asm/bitops.h
@@ -320,18 +320,23 @@ extern unsigned int __find_first_zero_bit(
extern unsigned int __find_next_zero_bit(
const unsigned long *addr, unsigned int size, unsigned int offset);
-static always_inline unsigned int __scanbit(unsigned long val, unsigned int
max)
+/*
+ * Search for the first set bit in @x, returning BITS_PER_LONG if @x was 0.
+ * See arch_ffs() for safety discussions.
+ */
+static always_inline unsigned int tzcnt(unsigned long x)
{
- if ( __builtin_constant_p(max) && max == BITS_PER_LONG )
- alternative_io("bsf %[in],%[out]; cmovz %[max],%k[out]",
- "rep; bsf %[in],%[out]",
- X86_FEATURE_BMI1,
- [out] "=&r" (val),
- [in] "r" (val), [max] "r" (max));
- else
- asm ( "bsf %1,%0 ; cmovz %2,%k0"
- : "=&r" (val) : "r" (val), "r" (max) );
- return (unsigned int)val;
+ unsigned int r;
+
+ /*
+ * The destination register still needs pre-loading for older CPUs which
+ * will execute TZCNT as BSF.
+ */
+ asm ( "tzcnt %[x], %q[r]"
+ : [r] "=r" (r)
+ : [x] "rm" (x), "[r]" (BITS_PER_LONG) );
+
+ return r;
}
/**
@@ -358,7 +363,7 @@ static always_inline unsigned int __scanbit(unsigned long
val, unsigned int max)
if ( o__ >= s__ ) \
r__ = s__; \
else if ( __builtin_constant_p(size) && s__ <= BITS_PER_LONG ) \
- r__ = o__ + __scanbit(*a__ >> o__, s__); \
+ r__ = o__ + tzcnt(*a__ >> o__); \
else if ( __builtin_constant_p(off) && !o__ ) \
r__ = __find_first_bit(a__, s__); \
else \
@@ -390,7 +395,7 @@ static always_inline unsigned int __scanbit(unsigned long
val, unsigned int max)
if ( o__ >= s__ ) \
r__ = s__; \
else if ( __builtin_constant_p(size) && s__ <= BITS_PER_LONG ) \
- r__ = o__ + __scanbit(~*a__ >> o__, s__); \
+ r__ = o__ + tzcnt(~*a__ >> o__); \
else if ( __builtin_constant_p(off) && !o__ ) \
r__ = __find_first_zero_bit(a__, s__); \
else \
base-commit: 204e45847d5a743b611de989835f651fcfd6ddc0
--
2.39.5
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |