WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] [OCaml] Release the global lock during some hypercal

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] [OCaml] Release the global lock during some hypercalls
From: Jonathan Davies <jonathan.davies@xxxxxxxxxx>
Date: Mon, 14 Nov 2011 11:06:15 +0000
Cc: jonathan.davies@xxxxxxxxxx
Delivery-date: Mon, 14 Nov 2011 03:07:34 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.7.5
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.

Signed-off-by: Jonathan Davies <jonathan.davies@xxxxxxxxxx>

diff -r 0844b17df7a9 -r 10758a9aa01c tools/ocaml/libs/xc/xenctrl_stubs.c
--- a/tools/ocaml/libs/xc/xenctrl_stubs.c       Fri Nov 11 18:14:35 2011 +0000
+++ b/tools/ocaml/libs/xc/xenctrl_stubs.c       Mon Nov 14 11:03:04 2011 +0000
@@ -115,7 +115,10 @@ CAMLprim value stub_xc_interface_open(vo
 {
        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(v
 {
        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(val
                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
 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(va
 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_getinfolis
 
        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(valu
 
        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_unbo
                                             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(v
 {
        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 xc
        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 x
        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 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_inc
                                                           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(v
        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_i
        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(va
        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(va
 
        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_
        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_
 
        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_ge
        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_se
        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));
 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] [OCaml] Release the global lock during some hypercalls, Jonathan Davies <=