1 /* 2 * Preemptible hypercalls 3 * 4 * Copyright (C) 2014 Citrix Systems R&D ltd. 5 * 6 * This source code is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of the 9 * License, or (at your option) any later version. 10 */ 11 12 #include <linux/sched.h> 13 #include <xen/xen-ops.h> 14 15 #ifndef CONFIG_PREEMPT 16 17 /* 18 * Some hypercalls issued by the toolstack can take many 10s of 19 * seconds. Allow tasks running hypercalls via the privcmd driver to 20 * be voluntarily preempted even if full kernel preemption is 21 * disabled. 22 * 23 * Such preemptible hypercalls are bracketed by 24 * xen_preemptible_hcall_begin() and xen_preemptible_hcall_end() 25 * calls. 26 */ 27 28 DEFINE_PER_CPU(bool, xen_in_preemptible_hcall); 29 EXPORT_SYMBOL_GPL(xen_in_preemptible_hcall); 30 xen_maybe_preempt_hcall(void)31asmlinkage __visible void xen_maybe_preempt_hcall(void) 32 { 33 if (unlikely(__this_cpu_read(xen_in_preemptible_hcall) 34 && need_resched() && !preempt_count())) { 35 /* 36 * Clear flag as we may be rescheduled on a different 37 * cpu. 38 */ 39 __this_cpu_write(xen_in_preemptible_hcall, false); 40 local_irq_enable(); 41 cond_resched(); 42 local_irq_disable(); 43 __this_cpu_write(xen_in_preemptible_hcall, true); 44 } 45 } 46 #endif /* CONFIG_PREEMPT */ 47