preempt.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  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. #include <linux/sched.h>
  12. #include <xen/xen-ops.h>
  13. #ifndef CONFIG_PREEMPT
  14. /*
  15. * Some hypercalls issued by the toolstack can take many 10s of
  16. * seconds. Allow tasks running hypercalls via the privcmd driver to
  17. * be voluntarily preempted even if full kernel preemption is
  18. * disabled.
  19. *
  20. * Such preemptible hypercalls are bracketed by
  21. * xen_preemptible_hcall_begin() and xen_preemptible_hcall_end()
  22. * calls.
  23. */
  24. DEFINE_PER_CPU(bool, xen_in_preemptible_hcall);
  25. EXPORT_SYMBOL_GPL(xen_in_preemptible_hcall);
  26. asmlinkage __visible void xen_maybe_preempt_hcall(void)
  27. {
  28. if (unlikely(__this_cpu_read(xen_in_preemptible_hcall)
  29. && need_resched())) {
  30. /*
  31. * Clear flag as we may be rescheduled on a different
  32. * cpu.
  33. */
  34. __this_cpu_write(xen_in_preemptible_hcall, false);
  35. local_irq_enable();
  36. cond_resched();
  37. local_irq_disable();
  38. __this_cpu_write(xen_in_preemptible_hcall, true);
  39. }
  40. }
  41. #endif /* CONFIG_PREEMPT */