mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
tools/ocaml: Release the global lock during some hypercalls
Since libxc is re-entrant, there is no need for the OCaml bindings to
prevent more than one thread from entering libxc concurrently.
Previously, the OCaml bindings had prevented re-entrancy by not using
caml_{enter,leave}_blocking_section in the C stubs. The absence of
these calls meant that the global lock remained held during
hypercalls. This caused multi-threaded applications to completely lock
up during long-running hypercalls.
Calls to these functions were present but commented out in the OCaml
bindings some years ago when libxc was not fully re-entrant.
Instead, we now do call caml_{enter,leave}_blocking_section in all the
places it used to be commented out, meaning that the global lock is
released during those hypercalls. We also no longer assert the
XC_OPENFLAG_NON_REENTRANT flag when calling xc_interface_open because
the caller no longer does re-entrancy prevention at those places.
This patch has now gone through a XenRT nightly test; no problems were
observed.
Signed-off-by: Jonathan Davies <jonathan.davies@citrix.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
This commit is contained in:
1 parent
943730ecff
commit
02e34c504d
1 file changed
+56
-47
@@ -115,7 +115,10 @@ CAMLprim value stub_xc_interface_open(void)
|
||||
{
|
||||
CAMLparam0();
|
||||
xc_interface *xch;
|
||||
xch = xc_interface_open(NULL, NULL, XC_OPENFLAG_NON_REENTRANT);
|
||||
|
||||
/* Don't assert XC_OPENFLAG_NON_REENTRANT because these bindings
|
||||
* do not prevent re-entrancy to libxc */
|
||||
xch = xc_interface_open(NULL, NULL, 0);
|
||||
if (xch == NULL)
|
||||
failwith_xc(NULL);
|
||||
CAMLreturn((value)xch);
|
||||
@@ -133,9 +136,9 @@ CAMLprim value stub_xc_interface_close(value xch)
|
||||
{
|
||||
CAMLparam1(xch);
|
||||
|
||||
// caml_enter_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
xc_interface_close(_H(xch));
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
|
||||
CAMLreturn(Val_unit);
|
||||
}
|
||||
@@ -170,9 +173,9 @@ CAMLprim value stub_xc_domain_create(value xch, value ssidref,
|
||||
c_flags |= domain_create_flag_table[v];
|
||||
}
|
||||
|
||||
// caml_enter_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
result = xc_domain_create(_H(xch), c_ssidref, h, c_flags, &domid);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
|
||||
if (result < 0)
|
||||
failwith_xc(_H(xch));
|
||||
@@ -217,12 +220,13 @@ value stub_xc_domain_sethandle(value xch, value domid, value handle)
|
||||
static value dom_op(value xch, value domid, int (*fn)(xc_interface *, uint32_t))
|
||||
{
|
||||
CAMLparam2(xch, domid);
|
||||
int result;
|
||||
|
||||
uint32_t c_domid = _D(domid);
|
||||
|
||||
// caml_enter_blocking_section();
|
||||
int result = fn(_H(xch), c_domid);
|
||||
// caml_leave_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
result = fn(_H(xch), c_domid);
|
||||
caml_leave_blocking_section();
|
||||
if (result)
|
||||
failwith_xc(_H(xch));
|
||||
CAMLreturn(Val_unit);
|
||||
@@ -247,12 +251,13 @@ CAMLprim value stub_xc_domain_destroy(value xch, value domid)
|
||||
CAMLprim value stub_xc_domain_resume_fast(value xch, value domid)
|
||||
{
|
||||
CAMLparam2(xch, domid);
|
||||
int result;
|
||||
|
||||
uint32_t c_domid = _D(domid);
|
||||
|
||||
// caml_enter_blocking_section();
|
||||
int result = xc_domain_resume(_H(xch), c_domid, 1);
|
||||
// caml_leave_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
result = xc_domain_resume(_H(xch), c_domid, 1);
|
||||
caml_leave_blocking_section();
|
||||
if (result)
|
||||
failwith_xc(_H(xch));
|
||||
CAMLreturn(Val_unit);
|
||||
@@ -324,10 +329,10 @@ CAMLprim value stub_xc_domain_getinfolist(value xch, value first_domain, value n
|
||||
|
||||
c_first_domain = _D(first_domain);
|
||||
c_max_domains = Int_val(nb);
|
||||
// caml_enter_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
retval = xc_domain_getinfolist(_H(xch), c_first_domain,
|
||||
c_max_domains, info);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
|
||||
if (retval < 0) {
|
||||
free(info);
|
||||
@@ -372,10 +377,10 @@ CAMLprim value stub_xc_vcpu_getinfo(value xch, value domid, value vcpu)
|
||||
|
||||
uint32_t c_domid = _D(domid);
|
||||
uint32_t c_vcpu = Int_val(vcpu);
|
||||
// caml_enter_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
retval = xc_vcpu_getinfo(_H(xch), c_domid,
|
||||
c_vcpu, &info);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
if (retval < 0)
|
||||
failwith_xc(_H(xch));
|
||||
|
||||
@@ -492,14 +497,15 @@ CAMLprim value stub_xc_evtchn_alloc_unbound(value xch,
|
||||
value remote_domid)
|
||||
{
|
||||
CAMLparam3(xch, local_domid, remote_domid);
|
||||
int result;
|
||||
|
||||
uint32_t c_local_domid = _D(local_domid);
|
||||
uint32_t c_remote_domid = _D(remote_domid);
|
||||
|
||||
// caml_enter_blocking_section();
|
||||
int result = xc_evtchn_alloc_unbound(_H(xch), c_local_domid,
|
||||
caml_enter_blocking_section();
|
||||
result = xc_evtchn_alloc_unbound(_H(xch), c_local_domid,
|
||||
c_remote_domid);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
|
||||
if (result < 0)
|
||||
failwith_xc(_H(xch));
|
||||
@@ -525,12 +531,13 @@ CAMLprim value stub_xc_readconsolering(value xch)
|
||||
{
|
||||
unsigned int size = RING_SIZE - 1;
|
||||
char *ring_ptr = ring;
|
||||
int retval;
|
||||
|
||||
CAMLparam1(xch);
|
||||
|
||||
// caml_enter_blocking_section();
|
||||
int retval = xc_readconsolering(_H(xch), ring_ptr, &size, 0, 0, NULL);
|
||||
// caml_leave_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
retval = xc_readconsolering(_H(xch), ring_ptr, &size, 0, 0, NULL);
|
||||
caml_leave_blocking_section();
|
||||
|
||||
if (retval)
|
||||
failwith_xc(_H(xch));
|
||||
@@ -557,9 +564,9 @@ CAMLprim value stub_xc_physinfo(value xch)
|
||||
xc_physinfo_t c_physinfo;
|
||||
int r;
|
||||
|
||||
// caml_enter_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
r = xc_physinfo(_H(xch), &c_physinfo);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
|
||||
if (r)
|
||||
failwith_xc(_H(xch));
|
||||
@@ -603,9 +610,9 @@ CAMLprim value stub_xc_pcpu_info(value xch, value nr_cpus)
|
||||
if (!info)
|
||||
caml_raise_out_of_memory();
|
||||
|
||||
// caml_enter_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
r = xc_getcpuinfo(_H(xch), Int_val(nr_cpus), info, &size);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
|
||||
if (r) {
|
||||
free(info);
|
||||
@@ -629,13 +636,14 @@ CAMLprim value stub_xc_domain_setmaxmem(value xch, value domid,
|
||||
value max_memkb)
|
||||
{
|
||||
CAMLparam3(xch, domid, max_memkb);
|
||||
int retval;
|
||||
|
||||
uint32_t c_domid = _D(domid);
|
||||
unsigned int c_max_memkb = Int64_val(max_memkb);
|
||||
// caml_enter_blocking_section();
|
||||
int retval = xc_domain_setmaxmem(_H(xch), c_domid,
|
||||
caml_enter_blocking_section();
|
||||
retval = xc_domain_setmaxmem(_H(xch), c_domid,
|
||||
c_max_memkb);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
if (retval)
|
||||
failwith_xc(_H(xch));
|
||||
CAMLreturn(Val_unit);
|
||||
@@ -661,14 +669,15 @@ CAMLprim value stub_xc_domain_memory_increase_reservation(value xch,
|
||||
value mem_kb)
|
||||
{
|
||||
CAMLparam3(xch, domid, mem_kb);
|
||||
int retval;
|
||||
|
||||
unsigned long nr_extents = ((unsigned long)(Int64_val(mem_kb))) >> (PAGE_SHIFT - 10);
|
||||
|
||||
uint32_t c_domid = _D(domid);
|
||||
// caml_enter_blocking_section();
|
||||
int retval = xc_domain_increase_reservation_exact(_H(xch), c_domid,
|
||||
caml_enter_blocking_section();
|
||||
retval = xc_domain_increase_reservation_exact(_H(xch), c_domid,
|
||||
nr_extents, 0, 0, NULL);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
|
||||
if (retval)
|
||||
failwith_xc(_H(xch));
|
||||
@@ -796,10 +805,10 @@ CAMLprim value stub_xc_version_version(value xch)
|
||||
long packed;
|
||||
int retval;
|
||||
|
||||
// caml_enter_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
packed = xc_version(_H(xch), XENVER_version, NULL);
|
||||
retval = xc_version(_H(xch), XENVER_extraversion, &extra);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
|
||||
if (retval)
|
||||
failwith_xc(_H(xch));
|
||||
@@ -821,9 +830,9 @@ CAMLprim value stub_xc_version_compile_info(value xch)
|
||||
xen_compile_info_t ci;
|
||||
int retval;
|
||||
|
||||
// caml_enter_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
retval = xc_version(_H(xch), XENVER_compile_info, &ci);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
|
||||
if (retval)
|
||||
failwith_xc(_H(xch));
|
||||
@@ -844,9 +853,9 @@ static value xc_version_single_string(value xch, int code, void *info)
|
||||
CAMLparam1(xch);
|
||||
int retval;
|
||||
|
||||
// caml_enter_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
retval = xc_version(_H(xch), code, info);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
|
||||
if (retval)
|
||||
failwith_xc(_H(xch));
|
||||
@@ -895,11 +904,11 @@ CAMLprim value stub_map_foreign_range(value xch, value dom,
|
||||
|
||||
c_dom = _D(dom);
|
||||
c_mfn = Nativeint_val(mfn);
|
||||
// caml_enter_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
intf->addr = xc_map_foreign_range(_H(xch), c_dom,
|
||||
intf->len, PROT_READ|PROT_WRITE,
|
||||
c_mfn);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
if (!intf->addr)
|
||||
caml_failwith("xc_map_foreign_range error");
|
||||
CAMLreturn(result);
|
||||
@@ -912,9 +921,9 @@ CAMLprim value stub_sched_credit_domain_get(value xch, value domid)
|
||||
struct xen_domctl_sched_credit c_sdom;
|
||||
int ret;
|
||||
|
||||
// caml_enter_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
ret = xc_sched_credit_domain_get(_H(xch), _D(domid), &c_sdom);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
if (ret != 0)
|
||||
failwith_xc(_H(xch));
|
||||
|
||||
@@ -934,9 +943,9 @@ CAMLprim value stub_sched_credit_domain_set(value xch, value domid,
|
||||
|
||||
c_sdom.weight = Int_val(Field(sdom, 0));
|
||||
c_sdom.cap = Int_val(Field(sdom, 1));
|
||||
// caml_enter_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
ret = xc_sched_credit_domain_set(_H(xch), _D(domid), &c_sdom);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
if (ret != 0)
|
||||
failwith_xc(_H(xch));
|
||||
|
||||
@@ -950,11 +959,11 @@ CAMLprim value stub_shadow_allocation_get(value xch, value domid)
|
||||
unsigned long c_mb;
|
||||
int ret;
|
||||
|
||||
// caml_enter_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
ret = xc_shadow_control(_H(xch), _D(domid),
|
||||
XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION,
|
||||
NULL, 0, &c_mb, 0, NULL);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
if (ret != 0)
|
||||
failwith_xc(_H(xch));
|
||||
|
||||
@@ -970,11 +979,11 @@ CAMLprim value stub_shadow_allocation_set(value xch, value domid,
|
||||
int ret;
|
||||
|
||||
c_mb = Int_val(mb);
|
||||
// caml_enter_blocking_section();
|
||||
caml_enter_blocking_section();
|
||||
ret = xc_shadow_control(_H(xch), _D(domid),
|
||||
XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION,
|
||||
NULL, 0, &c_mb, 0, NULL);
|
||||
// caml_leave_blocking_section();
|
||||
caml_leave_blocking_section();
|
||||
if (ret != 0)
|
||||
failwith_xc(_H(xch));
|
||||
|
||||
|
||||