diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2010-03-22 10:29:13 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2010-03-22 10:29:13 +0000 |
commit | 21980127e69600d3cbf6a0289989e29317b04c94 (patch) | |
tree | 08b89728e504f2e7b62080614945db2eab5360cc /xen/common/sysctl.c | |
parent | 078632963422644ee3a52f7d0fecb4af1026c235 (diff) | |
download | xen-21980127e69600d3cbf6a0289989e29317b04c94.tar.gz xen-21980127e69600d3cbf6a0289989e29317b04c94.tar.bz2 xen-21980127e69600d3cbf6a0289989e29317b04c94.zip |
Do not spin on locks that may be held by stop_machine_run() callers.
Currently stop_machine_run() will try to bring all CPUs to softirq
context, with some locks held, like xenpf_lock or cpu_add_remove_lock
etc. However, if another CPU is trying to get these locks, it may
cause deadlock.
This patch replace all such spin_lock with spin_trylock. For
xenpf_lock and sysctl_lock, we try to use hypercall_continuation, so
that we will not cause trouble to user space tools. For
cpu_hot_remove_lock, we simply return EBUSY if failure, since it will
only impact small number of user space tools.
In the end, we should try to make the stop_machine_run as spinlock
free.
Signed-off-by: Jiang, Yunhong <yunhong.jiang@intel.com>
Diffstat (limited to 'xen/common/sysctl.c')
-rw-r--r-- | xen/common/sysctl.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c index dbe6fc1083..1799eb3a94 100644 --- a/xen/common/sysctl.c +++ b/xen/common/sysctl.c @@ -48,7 +48,11 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) if ( op->interface_version != XEN_SYSCTL_INTERFACE_VERSION ) return -EACCES; - spin_lock(&sysctl_lock); + /* spin_trylock() avoids deadlock with stop_machine_run(). */ + while ( !spin_trylock(&sysctl_lock) ) + if ( hypercall_preempt_check() ) + return hypercall_create_continuation( + __HYPERVISOR_sysctl, "h", u_sysctl); switch ( op->cmd ) { |