diff options
author | Keir Fraser <keir@xen.org> | 2011-01-14 14:19:55 +0000 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2011-01-14 14:19:55 +0000 |
commit | 00e9c7bcb6397e85a8596cda619997982b6411e7 (patch) | |
tree | 883da4d5780df6f5278cf3b88b97f05a1798aba5 /xen/arch/x86/platform_hypercall.c | |
parent | 9d9af7dca878fb6f85ddf3cf3cb43df273f6b5a0 (diff) | |
download | xen-00e9c7bcb6397e85a8596cda619997982b6411e7.tar.gz xen-00e9c7bcb6397e85a8596cda619997982b6411e7.tar.bz2 xen-00e9c7bcb6397e85a8596cda619997982b6411e7.zip |
x86: On CPU online/offline from dom0, try flushing RCU work on EBUSY.
Although the caller should react appropriately to EBUSY, if the error
is due to pending RCU work then we can help things along by executing
rcu_barrier() and then retrying. To this end, this changeset is an
optimisation only.
Signed-off-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/platform_hypercall.c')
-rw-r--r-- | xen/arch/x86/platform_hypercall.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index 812df80228..2733fc3b9e 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -55,11 +55,9 @@ static long cpu_frequency_change_helper(void *data) return cpu_frequency_change(this_cpu(freq)); } -static long cpu_down_helper(void *data) -{ - int cpu = (unsigned long)data; - return cpu_down(cpu); -} +/* from sysctl.c */ +long cpu_up_helper(void *data); +long cpu_down_helper(void *data); ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) { @@ -443,40 +441,43 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) case XENPF_cpu_online: { - int cpu; + int cpu = op->u.cpu_ol.cpuid; - cpu = op->u.cpu_ol.cpuid; - if (!cpu_present(cpu)) + if ( !cpu_present(cpu) ) { ret = -EINVAL; break; } - else if (cpu_online(cpu)) + + if ( cpu_online(cpu) ) { ret = 0; break; } - ret = cpu_up(cpu); + ret = continue_hypercall_on_cpu( + 0, cpu_up_helper, (void *)(unsigned long)cpu); break; } case XENPF_cpu_offline: { - int cpu; + int cpu = op->u.cpu_ol.cpuid; - cpu = op->u.cpu_ol.cpuid; - if (!cpu_present(cpu)) + if ( !cpu_present(cpu) ) { ret = -EINVAL; break; - } else if (!cpu_online(cpu)) + } + + if ( !cpu_online(cpu) ) { ret = 0; break; } + ret = continue_hypercall_on_cpu( - 0, cpu_down_helper, (void *)(unsigned long)cpu); + 0, cpu_down_helper, (void *)(unsigned long)cpu); break; } break; |