mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
smp: convert the cpu maps lock into a rw lock
Most users of the cpu maps just care about the maps not changing while the lock is being held, but don't actually modify the maps. Convert the lock into a rw lock, and take the lock in read mode in get_cpu_maps and in write mode in cpu_hotplug_begin. This will lower the contention around the lock, since plug and unplug operations that take the lock in write mode are not that common. Note that the read lock can be taken recursively (as it's a shared lock), and hence will keep the same behavior as the previously used recursive lock. As for the write lock, it's only used by CPU plug/unplug operations, and the lock is never taken recursively in that case. While there also change get_cpu_maps return type to bool. Reported-by: Julien Grall <julien@xen.org> Suggested-also-by: Jan Beulich <jbeulich@suse.com> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> Reviewed-by: Julien Grall <julien@xen.org> Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
1 parent
132cbe8f35
commit
5872c83b42
2 files changed
+19
-16
No files matched your search
+16
-6
@@ -39,26 +39,36 @@ const unsigned long cpu_bit_bitmap[BITS_PER_LONG+1][BITS_TO_LONGS(NR_CPUS)] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
static DEFINE_SPINLOCK(cpu_add_remove_lock);
|
||||
static DEFINE_RWLOCK(cpu_add_remove_lock);
|
||||
|
||||
bool_t get_cpu_maps(void)
|
||||
bool get_cpu_maps(void)
|
||||
{
|
||||
return spin_trylock_recursive(&cpu_add_remove_lock);
|
||||
return read_trylock(&cpu_add_remove_lock);
|
||||
}
|
||||
|
||||
void put_cpu_maps(void)
|
||||
{
|
||||
spin_unlock_recursive(&cpu_add_remove_lock);
|
||||
read_unlock(&cpu_add_remove_lock);
|
||||
}
|
||||
|
||||
bool cpu_hotplug_begin(void)
|
||||
{
|
||||
return write_trylock(&cpu_add_remove_lock);
|
||||
}
|
||||
|
||||
void cpu_hotplug_done(void)
|
||||
{
|
||||
write_unlock(&cpu_add_remove_lock);
|
||||
}
|
||||
|
||||
static NOTIFIER_HEAD(cpu_chain);
|
||||
|
||||
void __init register_cpu_notifier(struct notifier_block *nb)
|
||||
{
|
||||
if ( !spin_trylock(&cpu_add_remove_lock) )
|
||||
if ( !write_trylock(&cpu_add_remove_lock) )
|
||||
BUG(); /* Should never fail as we are called only during boot. */
|
||||
notifier_chain_register(&cpu_chain, nb);
|
||||
spin_unlock(&cpu_add_remove_lock);
|
||||
write_unlock(&cpu_add_remove_lock);
|
||||
}
|
||||
|
||||
static int cpu_notifier_call_chain(unsigned int cpu, unsigned long action,
|
||||
|
||||
+3
-10
@@ -6,19 +6,12 @@
|
||||
#include <xen/notifier.h>
|
||||
|
||||
/* Safely access cpu_online_map, cpu_present_map, etc. */
|
||||
bool_t get_cpu_maps(void);
|
||||
bool get_cpu_maps(void);
|
||||
void put_cpu_maps(void);
|
||||
|
||||
/* Safely perform CPU hotplug and update cpu_online_map, etc. */
|
||||
static inline bool cpu_hotplug_begin(void)
|
||||
{
|
||||
return get_cpu_maps();
|
||||
}
|
||||
|
||||
static inline void cpu_hotplug_done(void)
|
||||
{
|
||||
put_cpu_maps();
|
||||
}
|
||||
bool cpu_hotplug_begin(void);
|
||||
void cpu_hotplug_done(void);
|
||||
|
||||
/* Receive notification of CPU hotplug events. */
|
||||
void register_cpu_notifier(struct notifier_block *nb);
|
||||
|
||||