xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: David Scott <dave.scott@eu.citrix.com>
To: Rob Hoes <rob.hoes@citrix.com>, xen-devel@lists.xen.org
Cc: ian.jackson@citrix.com, Ian Jackson <ian.jackson@eu.citrix.com>,
	ian.campbell@citrix.com
Subject: Re: [PATCH v5 08/12] libxl: ocaml: drop the ocaml heap lock before calling into libxl
Date: Tue, 26 Nov 2013 18:27:24 +0000	[thread overview]
Message-ID: <5294E80C.4020902@eu.citrix.com> (raw)
In-Reply-To: <1385488371-28875-9-git-send-email-rob.hoes@citrix.com>

On 26/11/13 17:52, Rob Hoes wrote:
> Ocaml has a heap lock which must be held whenever ocaml code is running. Ocaml
> usually drops this lock when it enters a potentially blocking low-level
> function, such as writing to a file. Libxl has its own lock, which it may
> acquire when being called.
>
> Things get interesting when libxl calls back into ocaml code. There is a risk
> of ending up in a deadlock when a thread holds both locks at the same time,
> then temporarily drop the ocaml lock, while another thread calls another libxl
> function.
>
> To avoid deadlocks, we drop the ocaml heap lock before entering libxl, and
> reacquire it in callbacks to ocaml. This way, the ocaml heap lock is never held
> together with the libxl lock, except in osevent registration callbacks, and
> xentoollog callbacks. If we guarantee to not call any libxl functions inside
> those callbacks, we can avoid deadlocks.
>
> This patch handle the dropping and reacquiring of the ocaml heap lock by the
> caml_enter_blocking_section and caml_leave_blocking_section functions, and
> related macros. We are also careful to not call any functions that access the
> ocaml heap while the ocaml heap lock is dropped. This often involves copying
> ocaml values to C before dropping the ocaml lock.

I think the approach sounds good. One or two questions inline: (I think 
only the last comment about Poll_events_val is significant)


>
> Signed-off-by: Rob Hoes <rob.hoes@citrix.com>
> CC: Ian Campbell <ian.campbell@citrix.com>
> CC: Ian Jackson <ian.jackson@eu.citrix.com>
> CC: Dave Scott <dave.scott@eu.citrix.com>
> ---
>   tools/ocaml/libs/xentoollog/Makefile           |    3 +
>   tools/ocaml/libs/xentoollog/xentoollog_stubs.c |   12 +-
>   tools/ocaml/libs/xl/Makefile                   |    5 +-
>   tools/ocaml/libs/xl/xenlight_stubs.c           |  255 +++++++++++++++++++-----
>   4 files changed, 221 insertions(+), 54 deletions(-)
>
> diff --git a/tools/ocaml/libs/xentoollog/Makefile b/tools/ocaml/libs/xentoollog/Makefile
> index e535ba5..471b428 100644
> --- a/tools/ocaml/libs/xentoollog/Makefile
> +++ b/tools/ocaml/libs/xentoollog/Makefile
> @@ -2,6 +2,9 @@ TOPLEVEL=$(CURDIR)/../..
>   XEN_ROOT=$(TOPLEVEL)/../..
>   include $(TOPLEVEL)/common.make
>
> +# allow mixed declarations and code
> +CFLAGS += -Wno-declaration-after-statement
> +
>   CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest)
>   OCAMLINCLUDE +=
>
> diff --git a/tools/ocaml/libs/xentoollog/xentoollog_stubs.c b/tools/ocaml/libs/xentoollog/xentoollog_stubs.c
> index 3b2f91b..87ea53e 100644
> --- a/tools/ocaml/libs/xentoollog/xentoollog_stubs.c
> +++ b/tools/ocaml/libs/xentoollog/xentoollog_stubs.c
> @@ -31,6 +31,10 @@
>
>   #include "caml_xentoollog.h"
>
> +#define CAMLdone do{ \
> +caml_local_roots = caml__frame; \
> +}while (0)

Might be worth a comment explaining that this is intended to be 
"CAMLreturn" without the return.

> +
>   #define XTL ((xentoollog_logger *) Xtl_val(handle))
>
>   static char * dup_String_val(value s)
> @@ -81,6 +85,7 @@ static void stub_xtl_ocaml_vmessage(struct xentoollog_logger *logger,
>   	const char *format,
>   	va_list al)
>   {
> +	caml_leave_blocking_section();
>   	CAMLparam0();
>   	CAMLlocalN(args, 4);
>   	struct caml_xtl *xtl = (struct caml_xtl*)logger;
> @@ -103,7 +108,8 @@ static void stub_xtl_ocaml_vmessage(struct xentoollog_logger *logger,
>   	free(msg);
>
>   	caml_callbackN(*func, 4, args);
> -	CAMLreturn0;
> +	CAMLdone;
> +	caml_enter_blocking_section();
>   }
>
>   static void stub_xtl_ocaml_progress(struct xentoollog_logger *logger,
> @@ -111,6 +117,7 @@ static void stub_xtl_ocaml_progress(struct xentoollog_logger *logger,
>   	const char *doing_what /* no \r,\n */,
>   	int percent, unsigned long done, unsigned long total)
>   {
> +	caml_leave_blocking_section();
>   	CAMLparam0();
>   	CAMLlocalN(args, 5);
>   	struct caml_xtl *xtl = (struct caml_xtl*)logger;
> @@ -129,7 +136,8 @@ static void stub_xtl_ocaml_progress(struct xentoollog_logger *logger,
>   	args[4] = caml_copy_int64(total);
>
>   	caml_callbackN(*func, 5, args);
> -	CAMLreturn0;
> +	CAMLdone;
> +	caml_enter_blocking_section();
>   }
>
>   static void xtl_destroy(struct xentoollog_logger *logger)
> diff --git a/tools/ocaml/libs/xl/Makefile b/tools/ocaml/libs/xl/Makefile
> index 0408cc2..61eb44c 100644
> --- a/tools/ocaml/libs/xl/Makefile
> +++ b/tools/ocaml/libs/xl/Makefile
> @@ -2,8 +2,9 @@ TOPLEVEL=$(CURDIR)/../..
>   XEN_ROOT=$(TOPLEVEL)/../..
>   include $(TOPLEVEL)/common.make
>
> -# ignore unused generated functions
> -CFLAGS += -Wno-unused
> +# ignore unused generated functions and allow mixed declarations and code
> +CFLAGS += -Wno-unused -Wno-declaration-after-statement
> +
>   CFLAGS += $(CFLAGS_libxenlight)
>   CFLAGS += -I ../xentoollog
>
> diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c b/tools/ocaml/libs/xl/xenlight_stubs.c
> index 88cca20..01ba3fe 100644
> --- a/tools/ocaml/libs/xl/xenlight_stubs.c
> +++ b/tools/ocaml/libs/xl/xenlight_stubs.c
> @@ -34,6 +34,10 @@
>
>   #include "caml_xentoollog.h"
>
> +#define CAMLdone do{ \
> +caml_local_roots = caml__frame; \
> +}while (0)
> +
>   #define Ctx_val(x)(*((libxl_ctx **) Data_custom_val(x)))
>   #define CTX ((libxl_ctx *) Ctx_val(ctx))
>
> @@ -374,6 +378,7 @@ static char *String_option_val(value v)
>
>   void async_callback(libxl_ctx *ctx, int rc, void *for_callback)
>   {
> +	caml_leave_blocking_section();
>   	CAMLparam0();
>   	CAMLlocal1(error);
>   	int *task = (int *) for_callback;
> @@ -390,19 +395,22 @@ void async_callback(libxl_ctx *ctx, int rc, void *for_callback)
>   		error = Val_some(Val_error(rc));
>
>   	caml_callback2(*func, error, (value) for_callback);
> +	CAMLdone;
> +	caml_enter_blocking_section();
>   }
>
> -static libxl_asyncop_how *aohow_val(value async, libxl_asyncop_how *ao_how)
> +static libxl_asyncop_how *aohow_val(value async)
>   {
>   	CAMLparam1(async);
> +	libxl_asyncop_how *ao_how = NULL;
>
>   	if (async != Val_none) {
> +		libxl_asyncop_how *ao_how = malloc(sizeof(*ao_how));
>   		ao_how->callback = async_callback;
>   		ao_how->u.for_callback = (void *) Some_val(async);
> -		CAMLreturnT(libxl_asyncop_how *, ao_how);
>   	}
> -	else
> -		CAMLreturnT(libxl_asyncop_how *, NULL);
> +
> +	CAMLreturnT(libxl_asyncop_how *, ao_how);
>   }
>
>   value stub_libxl_domain_create_new(value ctx, value domain_config, value async, value unit)
> @@ -411,7 +419,7 @@ value stub_libxl_domain_create_new(value ctx, value domain_config, value async,
>   	int ret;
>   	libxl_domain_config c_dconfig;
>   	uint32_t c_domid;
> -	libxl_asyncop_how ao_how;
> +	libxl_asyncop_how *ao_how;
>
>   	libxl_domain_config_init(&c_dconfig);
>   	ret = domain_config_val(CTX, &c_dconfig, domain_config);
> @@ -420,9 +428,14 @@ value stub_libxl_domain_create_new(value ctx, value domain_config, value async,
>   		failwith_xl(ret, "domain_create_new");
>   	}
>
> -	ret = libxl_domain_create_new(CTX, &c_dconfig, &c_domid,
> -		aohow_val(async, &ao_how), NULL);
> +	ao_how = aohow_val(async);
>
> +	caml_enter_blocking_section();
> +	ret = libxl_domain_create_new(CTX, &c_dconfig, &c_domid, ao_how, NULL);
> +	caml_leave_blocking_section();
> +
> +	if (ao_how)
> +		free(ao_how);
>   	libxl_domain_config_dispose(&c_dconfig);
>
>   	if (ret != 0)
> @@ -439,7 +452,8 @@ value stub_libxl_domain_create_restore(value ctx, value domain_config, value par
>   	libxl_domain_config c_dconfig;
>   	libxl_domain_restore_params c_params;
>   	uint32_t c_domid;
> -	libxl_asyncop_how ao_how;
> +	libxl_asyncop_how *ao_how;
> +	int restore_fd;
>
>   	libxl_domain_config_init(&c_dconfig);
>   	ret = domain_config_val(CTX, &c_dconfig, domain_config);
> @@ -455,9 +469,16 @@ value stub_libxl_domain_create_restore(value ctx, value domain_config, value par
>   		failwith_xl(ret, "domain_create_restore");
>   	}
>
> -	ret = libxl_domain_create_restore(CTX, &c_dconfig, &c_domid, Int_val(Field(params, 0)),
> -		&c_params, aohow_val(async, &ao_how), NULL);
> +	ao_how = aohow_val(async);
> +	restore_fd = Int_val(Field(params, 0));
> +
> +	caml_enter_blocking_section();
> +	ret = libxl_domain_create_restore(CTX, &c_dconfig, &c_domid, restore_fd,
> +		&c_params, ao_how, NULL);
> +	caml_leave_blocking_section();
>
> +	if (ao_how)
> +		free(ao_how);
>   	libxl_domain_config_dispose(&c_dconfig);
>   	libxl_domain_restore_params_dispose(&c_params);
>
> @@ -471,8 +492,12 @@ value stub_libxl_domain_shutdown(value ctx, value domid)
>   {
>   	CAMLparam2(ctx, domid);
>   	int ret;
> +	uint32_t c_domid = Int_val(domid);
> +
> +	caml_enter_blocking_section();
> +	ret = libxl_domain_shutdown(CTX, c_domid);
> +	caml_leave_blocking_section();
>
> -	ret = libxl_domain_shutdown(CTX, Int_val(domid));
>   	if (ret != 0)
>   		failwith_xl(ret, "domain_shutdown");
>
> @@ -483,8 +508,12 @@ value stub_libxl_domain_reboot(value ctx, value domid)
>   {
>   	CAMLparam2(ctx, domid);
>   	int ret;
> +	uint32_t c_domid = Int_val(domid);
> +
> +	caml_enter_blocking_section();
> +	ret = libxl_domain_reboot(CTX, c_domid);
> +	caml_leave_blocking_section();
>
> -	ret = libxl_domain_reboot(CTX, Int_val(domid));
>   	if (ret != 0)
>   		failwith_xl(ret, "domain_reboot");
>
> @@ -495,9 +524,16 @@ value stub_libxl_domain_destroy(value ctx, value domid, value async, value unit)
>   {
>   	CAMLparam4(ctx, domid, async, unit);
>   	int ret;
> -	libxl_asyncop_how ao_how;
> +	uint32_t c_domid = Int_val(domid);
> +	libxl_asyncop_how *ao_how = aohow_val(async);
> +
> +	caml_enter_blocking_section();
> +	ret = libxl_domain_destroy(CTX, c_domid, ao_how);
> +	caml_leave_blocking_section();
> +
> +	if (ao_how)
> +		free(ao_how);
>
> -	ret = libxl_domain_destroy(CTX, Int_val(domid), aohow_val(async, &ao_how));
>   	if (ret != 0)
>   		failwith_xl(ret, "domain_destroy");
>
> @@ -508,10 +544,17 @@ value stub_libxl_domain_suspend(value ctx, value domid, value fd, value async, v
>   {
>   	CAMLparam5(ctx, domid, fd, async, unit);
>   	int ret;
> -	libxl_asyncop_how ao_how;
> +	uint32_t c_domid = Int_val(domid);
> +	int c_fd = Int_val(fd);
> +	libxl_asyncop_how *ao_how = aohow_val(async);
> +
> +	caml_enter_blocking_section();
> +	ret = libxl_domain_suspend(CTX, c_domid, c_fd, 0, ao_how);
> +	caml_leave_blocking_section();
> +
> +	if (ao_how)
> +		free(ao_how);
>
> -	ret = libxl_domain_suspend(CTX, Int_val(domid), Int_val(fd), 0,
> -		aohow_val(async, &ao_how));
>   	if (ret != 0)
>   		failwith_xl(ret, "domain_suspend");
>
> @@ -522,8 +565,12 @@ value stub_libxl_domain_pause(value ctx, value domid)
>   {
>   	CAMLparam2(ctx, domid);
>   	int ret;
> +	uint32_t c_domid = Int_val(domid);
> +
> +	caml_enter_blocking_section();
> +	ret = libxl_domain_pause(CTX, c_domid);
> +	caml_leave_blocking_section();
>
> -	ret = libxl_domain_pause(CTX, Int_val(domid));
>   	if (ret != 0)
>   		failwith_xl(ret, "domain_pause");
>
> @@ -534,8 +581,12 @@ value stub_libxl_domain_unpause(value ctx, value domid)
>   {
>   	CAMLparam2(ctx, domid);
>   	int ret;
> +	uint32_t c_domid = Int_val(domid);
> +
> +	caml_enter_blocking_section();
> +	ret = libxl_domain_unpause(CTX, c_domid);
> +	caml_leave_blocking_section();
>
> -	ret = libxl_domain_unpause(CTX, Int_val(domid));
>   	if (ret != 0)
>   		failwith_xl(ret, "domain_unpause");
>
> @@ -552,13 +603,17 @@ value stub_xl_device_##type##_##op(value ctx, value info, value domid,	\
>   	CAMLparam5(ctx, info, domid, async, unit);			\
>   	libxl_device_##type c_info;					\
>   	int ret, marker_var;						\
> -	libxl_asyncop_how ao_how;					\
> +	uint32_t c_domid = Int_val(domid);					\
> +	libxl_asyncop_how *ao_how = aohow_val(async);			\
>   									\
>   	device_##type##_val(CTX, &c_info, info);			\
>   									\
> -	ret = libxl_##fn##_##op(CTX, Int_val(domid), &c_info,		\
> -		aohow_val(async, &ao_how));				\
> +	caml_enter_blocking_section();					\
> +	ret = libxl_##fn##_##op(CTX, c_domid, &c_info, ao_how);		\
> +	caml_leave_blocking_section();					\
>   									\
> +	if (ao_how)							\
> +		free(ao_how);						\
>   	libxl_device_##type##_dispose(&c_info);				\
>   									\
>   	if (ret != 0)							\
> @@ -584,9 +639,16 @@ value stub_xl_device_nic_of_devid(value ctx, value domid, value devid)
>   	CAMLparam3(ctx, domid, devid);
>   	CAMLlocal1(nic);
>   	libxl_device_nic c_nic;
> -	libxl_devid_to_device_nic(CTX, Int_val(domid), Int_val(devid), &c_nic);
> +	uint32_t c_domid = Int_val(domid);
> +	int c_devid = Int_val(devid);
> +
> +	caml_enter_blocking_section();
> +	libxl_devid_to_device_nic(CTX, c_domid, c_devid, &c_nic);
> +	caml_leave_blocking_section();
> +
>   	nic = Val_device_nic(&c_nic);
>   	libxl_device_nic_dispose(&c_nic);
> +
>   	CAMLreturn(nic);
>   }
>
> @@ -596,11 +658,12 @@ value stub_xl_device_nic_list(value ctx, value domid)
>   	CAMLlocal2(list, temp);
>   	libxl_device_nic *c_list;
>   	int i, nb;
> -	uint32_t c_domid;
> -
> -	c_domid = Int_val(domid);
> +	uint32_t c_domid = Int_val(domid);
>
> +	caml_enter_blocking_section();
>   	c_list = libxl_device_nic_list(CTX, c_domid, &nb);
> +	caml_leave_blocking_section();
> +
>   	if (!c_list)
>   		failwith_xl(ERROR_FAIL, "nic_list");
>
> @@ -624,11 +687,12 @@ value stub_xl_device_disk_list(value ctx, value domid)
>   	CAMLlocal2(list, temp);
>   	libxl_device_disk *c_list;
>   	int i, nb;
> -	uint32_t c_domid;
> -
> -	c_domid = Int_val(domid);
> +	uint32_t c_domid = Int_val(domid);
>
> +	caml_enter_blocking_section();
>   	c_list = libxl_device_disk_list(CTX, c_domid, &nb);
> +	caml_leave_blocking_section();
> +
>   	if (!c_list)
>   		failwith_xl(ERROR_FAIL, "disk_list");
>
> @@ -651,9 +715,20 @@ value stub_xl_device_disk_of_vdev(value ctx, value domid, value vdev)
>   	CAMLparam3(ctx, domid, vdev);
>   	CAMLlocal1(disk);
>   	libxl_device_disk c_disk;
> -	libxl_vdev_to_device_disk(CTX, Int_val(domid), String_val(vdev), &c_disk);
> +	char *c_vdev;
> +	uint32_t c_domid = Int_val(domid);
> +
> +	c_vdev = malloc((caml_string_length(vdev) + 1) * sizeof(char *));
> +	strcpy(c_vdev, String_val(vdev));

Perhaps this would be clearer as strdup(String_val(vdev))?

> +
> +	caml_enter_blocking_section();
> +	libxl_vdev_to_device_disk(CTX, c_domid, c_vdev, &c_disk);
> +	caml_leave_blocking_section();
> +
>   	disk = Val_device_disk(&c_disk);
>   	libxl_device_disk_dispose(&c_disk);
> +	free(c_vdev);
> +
>   	CAMLreturn(disk);
>   }
>
> @@ -663,11 +738,12 @@ value stub_xl_device_pci_list(value ctx, value domid)
>   	CAMLlocal2(list, temp);
>   	libxl_device_pci *c_list;
>   	int i, nb;
> -	uint32_t c_domid;
> -
> -	c_domid = Int_val(domid);
> +	uint32_t c_domid = Int_val(domid);
>
> +	caml_enter_blocking_section();
>   	c_list = libxl_device_pci_list(CTX, c_domid, &nb);
> +	caml_leave_blocking_section();
> +
>   	if (!c_list)
>   		failwith_xl(ERROR_FAIL, "pci_list");
>
> @@ -690,10 +766,13 @@ value stub_xl_device_pci_assignable_add(value ctx, value info, value rebind)
>   	CAMLparam3(ctx, info, rebind);
>   	libxl_device_pci c_info;
>   	int ret, marker_var;
> +	int c_rebind = (int) Bool_val(rebind);
>
>   	device_pci_val(CTX, &c_info, info);
>
> -	ret = libxl_device_pci_assignable_add(CTX, &c_info, (int) Bool_val(rebind));
> +	caml_enter_blocking_section();
> +	ret = libxl_device_pci_assignable_add(CTX, &c_info, c_rebind);
> +	caml_leave_blocking_section();
>
>   	libxl_device_pci_dispose(&c_info);
>
> @@ -708,10 +787,13 @@ value stub_xl_device_pci_assignable_remove(value ctx, value info, value rebind)
>   	CAMLparam3(ctx, info, rebind);
>   	libxl_device_pci c_info;
>   	int ret, marker_var;
> +	int c_rebind = (int) Bool_val(rebind);
>
>   	device_pci_val(CTX, &c_info, info);
>
> -	ret = libxl_device_pci_assignable_remove(CTX, &c_info, (int) Bool_val(rebind));
> +	caml_enter_blocking_section();
> +	ret = libxl_device_pci_assignable_remove(CTX, &c_info, c_rebind);
> +	caml_leave_blocking_section();
>
>   	libxl_device_pci_dispose(&c_info);
>
> @@ -729,7 +811,10 @@ value stub_xl_device_pci_assignable_list(value ctx)
>   	int i, nb;
>   	uint32_t c_domid;
>
> +	caml_enter_blocking_section();
>   	c_list = libxl_device_pci_assignable_list(CTX, &nb);
> +	caml_leave_blocking_section();
> +
>   	if (!c_list)
>   		failwith_xl(ERROR_FAIL, "pci_assignable_list");
>
> @@ -754,7 +839,9 @@ value stub_xl_physinfo_get(value ctx)
>   	libxl_physinfo c_physinfo;
>   	int ret;
>
> +	caml_enter_blocking_section();
>   	ret = libxl_get_physinfo(CTX, &c_physinfo);
> +	caml_leave_blocking_section();
>
>   	if (ret != 0)
>   		failwith_xl(ret, "get_physinfo");
> @@ -773,7 +860,9 @@ value stub_xl_cputopology_get(value ctx)
>   	libxl_cputopology *c_topology;
>   	int i, nr;
>
> +	caml_enter_blocking_section();
>   	c_topology = libxl_get_cpu_topology(CTX, &nr);
> +	caml_leave_blocking_section();
>
>   	if (!c_topology)
>   		failwith_xl(ERROR_FAIL, "get_cpu_topologyinfo");
> @@ -801,7 +890,10 @@ value stub_xl_dominfo_list(value ctx)
>   	libxl_dominfo *c_domlist;
>   	int i, nb;
>
> +	caml_enter_blocking_section();
>   	c_domlist = libxl_list_domain(CTX, &nb);
> +	caml_leave_blocking_section();
> +
>   	if (!c_domlist)
>   		failwith_xl(ERROR_FAIL, "dominfo_list");
>
> @@ -826,8 +918,12 @@ value stub_xl_dominfo_get(value ctx, value domid)
>   	CAMLlocal1(dominfo);
>   	libxl_dominfo c_dominfo;
>   	int ret;
> +	uint32_t c_domid = Int_val(domid);
> +
> +	caml_enter_blocking_section();
> +	ret = libxl_domain_info(CTX, &c_dominfo, c_domid);
> +	caml_leave_blocking_section();
>
> -	ret = libxl_domain_info(CTX, &c_dominfo, Int_val(domid));
>   	if (ret != 0)
>   		failwith_xl(ERROR_FAIL, "domain_info");
>   	dominfo = Val_dominfo(&c_dominfo);
> @@ -841,8 +937,12 @@ value stub_xl_domain_sched_params_get(value ctx, value domid)
>   	CAMLlocal1(scinfo);
>   	libxl_domain_sched_params c_scinfo;
>   	int ret;
> +	uint32_t c_domid = Int_val(domid);
> +
> +	caml_enter_blocking_section();
> +	ret = libxl_domain_sched_params_get(CTX, c_domid, &c_scinfo);
> +	caml_leave_blocking_section();
>
> -	ret = libxl_domain_sched_params_get(CTX, Int_val(domid), &c_scinfo);
>   	if (ret != 0)
>   		failwith_xl(ret, "domain_sched_params_get");
>
> @@ -858,10 +958,13 @@ value stub_xl_domain_sched_params_set(value ctx, value domid, value scinfo)
>   	CAMLparam3(ctx, domid, scinfo);
>   	libxl_domain_sched_params c_scinfo;
>   	int ret;
> +	uint32_t c_domid = Int_val(domid);
>
>   	domain_sched_params_val(CTX, &c_scinfo, scinfo);
>
> -	ret = libxl_domain_sched_params_set(CTX, Int_val(domid), &c_scinfo);
> +	caml_enter_blocking_section();
> +	ret = libxl_domain_sched_params_set(CTX, c_domid, &c_scinfo);
> +	caml_leave_blocking_section();
>
>   	libxl_domain_sched_params_dispose(&c_scinfo);
>
> @@ -875,12 +978,15 @@ value stub_xl_send_trigger(value ctx, value domid, value trigger, value vcpuid)
>   {
>   	CAMLparam4(ctx, domid, trigger, vcpuid);
>   	int ret;
> +	uint32_t c_domid = Int_val(domid);
>   	libxl_trigger c_trigger = LIBXL_TRIGGER_UNKNOWN;
> +	int c_vcpuid = Int_val(vcpuid);
>
>   	trigger_val(CTX, &c_trigger, trigger);
>
> -	ret = libxl_send_trigger(CTX, Int_val(domid),
> -				 c_trigger, Int_val(vcpuid));
> +	caml_enter_blocking_section();
> +	ret = libxl_send_trigger(CTX, c_domid, c_trigger, c_vcpuid);
> +	caml_leave_blocking_section();
>
>   	if (ret != 0)
>   		failwith_xl(ret, "send_trigger");
> @@ -892,8 +998,12 @@ value stub_xl_send_sysrq(value ctx, value domid, value sysrq)
>   {
>   	CAMLparam3(ctx, domid, sysrq);
>   	int ret;
> +	uint32_t c_domid = Int_val(domid);
> +	int c_sysrq = Int_val(sysrq);
>
> -	ret = libxl_send_sysrq(CTX, Int_val(domid), Int_val(sysrq));
> +	caml_enter_blocking_section();
> +	ret = libxl_send_sysrq(CTX, c_domid, c_sysrq);
> +	caml_leave_blocking_section();
>
>   	if (ret != 0)
>   		failwith_xl(ret, "send_sysrq");
> @@ -909,7 +1019,10 @@ value stub_xl_send_debug_keys(value ctx, value keys)
>
>   	c_keys = dup_String_val(keys);
>
> +	caml_enter_blocking_section();
>   	ret = libxl_send_debug_keys(CTX, c_keys);
> +	caml_leave_blocking_section();
> +
>   	free(c_keys);
>
>   	if (ret != 0)
> @@ -933,9 +1046,12 @@ value stub_libxl_xen_console_read_start(value ctx, value clear)
>   {
>   	CAMLparam2(ctx, clear);
>   	CAMLlocal1(handle);
> +	int c_clear = Int_val(clear);
>   	libxl_xen_console_reader *cr;
>
> -	cr = libxl_xen_console_read_start(CTX, Int_val(clear));
> +	caml_enter_blocking_section();
> +	cr = libxl_xen_console_read_start(CTX, c_clear);
> +	caml_leave_blocking_section();
>
>   	handle = caml_alloc_custom(&libxl_console_reader_custom_operations, sizeof(cr), 0, 1);
>   	Console_reader_val(handle) = cr;
> @@ -965,7 +1081,9 @@ value stub_libxl_xen_console_read_line(value ctx, value reader)
>   	char *c_line;
>   	libxl_xen_console_reader *cr = (libxl_xen_console_reader *) Console_reader_val(reader);
>
> +	caml_enter_blocking_section();
>   	ret = libxl_xen_console_read_line(CTX, cr, &c_line);
> +	caml_leave_blocking_section();
>
>   	if (ret < 0)
>   		failwith_xl(ret, "xen_console_read_line");
> @@ -982,7 +1100,9 @@ value stub_libxl_xen_console_read_finish(value ctx, value reader)
>   	CAMLparam2(ctx, reader);
>   	libxl_xen_console_reader *cr = (libxl_xen_console_reader *) Console_reader_val(reader);
>
> +	caml_enter_blocking_section();
>   	libxl_xen_console_read_finish(CTX, cr);
> +	caml_leave_blocking_section();
>
>   	CAMLreturn(Val_unit);
>   }
> @@ -1074,6 +1194,7 @@ value Val_poll_events(short events)
>   int fd_register(void *user, int fd, void **for_app_registration_out,
>                        short events, void *for_libxl)
>   {
> +	caml_leave_blocking_section();
>   	CAMLparam0();
>   	CAMLlocalN(args, 4);
>   	static value *func = NULL;
> @@ -1089,12 +1210,15 @@ int fd_register(void *user, int fd, void **for_app_registration_out,
>   	args[3] = (value) for_libxl;
>
>   	caml_callbackN(*func, 4, args);
> -	CAMLreturn(0);
> +	CAMLdone;
> +	caml_enter_blocking_section();
> +	return 0;
>   }
>
>   int fd_modify(void *user, int fd, void **for_app_registration_update,
>                      short events)
>   {
> +	caml_leave_blocking_section();
>   	CAMLparam0();
>   	CAMLlocalN(args, 3);
>   	static value *func = NULL;
> @@ -1109,11 +1233,14 @@ int fd_modify(void *user, int fd, void **for_app_registration_update,
>   	args[2] = Val_poll_events(events);
>
>   	caml_callbackN(*func, 3, args);
> -	CAMLreturn(0);
> +	CAMLdone;
> +	caml_enter_blocking_section();
> +	return 0;
>   }
>
>   void fd_deregister(void *user, int fd, void *for_app_registration)
>   {
> +	caml_leave_blocking_section();
>   	CAMLparam0();
>   	CAMLlocalN(args, 2);
>   	static value *func = NULL;
> @@ -1127,12 +1254,14 @@ void fd_deregister(void *user, int fd, void *for_app_registration)
>   	args[1] = Val_int(fd);
>
>   	caml_callbackN(*func, 2, args);
> -	CAMLreturn0;
> +	CAMLdone;
> +	caml_enter_blocking_section();
>   }
>
>   int timeout_register(void *user, void **for_app_registration_out,
>                             struct timeval abs, void *for_libxl)
>   {
> +	caml_leave_blocking_section();
>   	CAMLparam0();
>   	CAMLlocalN(args, 4);
>   	static value *func = NULL;
> @@ -1148,12 +1277,15 @@ int timeout_register(void *user, void **for_app_registration_out,
>   	args[3] = (value) for_libxl;
>
>   	caml_callbackN(*func, 4, args);
> -	CAMLreturn(0);
> +	CAMLdone;
> +	caml_enter_blocking_section();
> +	return 0;
>   }
>
>   int timeout_modify(void *user, void **for_app_registration_update,
>                            struct timeval abs)
>   {
> +	caml_leave_blocking_section();
>   	CAMLparam0();
>   	static value *func = NULL;
>
> @@ -1163,13 +1295,16 @@ int timeout_modify(void *user, void **for_app_registration_update,
>   	}
>
>   	caml_callback(*func, (value) user);
> -	CAMLreturn(0);
> +	CAMLdone;
> +	caml_enter_blocking_section();
> +	return 0;
>   }
>
>   void timeout_deregister(void *user, void *for_app_registration)
>   {
> +	caml_leave_blocking_section();
>   	failwith_xl(ERROR_FAIL, "timeout_deregister not yet implemented");
> -	return;
> +	caml_enter_blocking_section();
>   }
>
>   value stub_libxl_osevent_register_hooks(value ctx, value user)
> @@ -1186,7 +1321,10 @@ value stub_libxl_osevent_register_hooks(value ctx, value user)
>   	hooks->timeout_modify = timeout_modify;
>   	hooks->timeout_deregister = timeout_deregister;
>
> +	caml_enter_blocking_section();
>   	libxl_osevent_register_hooks(CTX, hooks, (void *) user);
> +	caml_leave_blocking_section();
> +
>   	result = caml_alloc(1, Abstract_tag);
>   	*((libxl_osevent_hooks **) result) = hooks;
>
> @@ -1197,15 +1335,23 @@ value stub_libxl_osevent_occurred_fd(value ctx, value for_libxl, value fd,
>   	value events, value revents)
>   {
>   	CAMLparam5(ctx, for_libxl, fd, events, revents);
> +
> +	caml_enter_blocking_section();
>   	libxl_osevent_occurred_fd(CTX, (void *) for_libxl, Int_val(fd),
>   		Poll_events_val(events), Poll_events_val(revents));

Is the "events" OCaml value being accessed here without the heap lock?

> +	caml_leave_blocking_section();
> +
>   	CAMLreturn(Val_unit);
>   }
>
>   value stub_libxl_osevent_occurred_timeout(value ctx, value for_libxl)
>   {
>   	CAMLparam2(ctx, for_libxl);
> +
> +	caml_enter_blocking_section();
>   	libxl_osevent_occurred_timeout(CTX, (void *) for_libxl);
> +	caml_leave_blocking_section();
> +
>   	CAMLreturn(Val_unit);
>   }
>
> @@ -1216,6 +1362,7 @@ struct user_with_ctx {
>
>   void event_occurs(void *user, libxl_event *event)
>   {
> +	caml_leave_blocking_section();
>   	CAMLparam0();
>   	CAMLlocalN(args, 2);
>   	struct user_with_ctx *c_user = (struct user_with_ctx *) user;
> @@ -1231,12 +1378,14 @@ void event_occurs(void *user, libxl_event *event)
>   	libxl_event_free(c_user->ctx, event);
>
>   	caml_callbackN(*func, 2, args);
> -	CAMLreturn0;
> +	CAMLdone;
> +	caml_enter_blocking_section();
>   }
>
>   void disaster(void *user, libxl_event_type type,
>                        const char *msg, int errnoval)
>   {
> +	caml_leave_blocking_section();
>   	CAMLparam0();
>   	CAMLlocalN(args, 4);
>   	struct user_with_ctx *c_user = (struct user_with_ctx *) user;
> @@ -1253,7 +1402,8 @@ void disaster(void *user, libxl_event_type type,
>   	args[3] = Val_int(errnoval);
>
>   	caml_callbackN(*func, 4, args);
> -	CAMLreturn0;
> +	CAMLdone;
> +	caml_enter_blocking_section();
>   }
>
>   value stub_libxl_event_register_callbacks(value ctx, value user)
> @@ -1272,7 +1422,10 @@ value stub_libxl_event_register_callbacks(value ctx, value user)
>   	hooks->event_occurs = event_occurs;
>   	hooks->disaster = disaster;
>
> +	caml_enter_blocking_section();
>   	libxl_event_register_callbacks(CTX, hooks, (void *) c_user);
> +	caml_leave_blocking_section();
> +
>   	result = caml_alloc(1, Abstract_tag);
>   	*((libxl_event_hooks **) result) = hooks;
>
> @@ -1284,7 +1437,9 @@ value stub_libxl_evenable_domain_death(value ctx, value domid, value user)
>   	CAMLparam3(ctx, domid, user);
>   	libxl_evgen_domain_death *evgen_out;
>
> +	caml_enter_blocking_section();
>   	libxl_evenable_domain_death(CTX, Int_val(domid), Int_val(user), &evgen_out);
> +	caml_leave_blocking_section();
>
>   	CAMLreturn(Val_unit);
>   }
>

  reply	other threads:[~2013-11-26 18:27 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-26 17:52 [PATCH v5 00/12] libxl: ocaml: improve the bindings Rob Hoes
2013-11-26 17:52 ` [PATCH v5 01/12] libxl: ocaml: add simple test case for xentoollog Rob Hoes
2013-11-26 17:52 ` [PATCH v5 02/12] libxl: ocaml: implement some simple tests Rob Hoes
2013-11-26 17:52 ` [PATCH v5 03/12] libxl: ocaml: event management Rob Hoes
2013-11-28 16:50   ` Ian Jackson
2013-11-28 16:53     ` Ian Jackson
2013-11-28 16:50   ` Ian Jackson
2013-11-28 16:50   ` Ian Jackson
2013-11-28 16:50   ` Ian Jackson
2013-11-28 16:50   ` Ian Jackson
2013-11-29  8:40   ` Ian Campbell
2013-11-29  9:29     ` Rob Hoes
2013-11-26 17:52 ` [PATCH v5 04/12] libxl: ocaml: allow device operations to be called asynchronously Rob Hoes
2013-11-26 17:52 ` [PATCH v5 05/12] libxl: ocaml: add disk and cdrom helper functions Rob Hoes
2013-11-26 17:52 ` [PATCH v5 06/12] libxl: ocaml: add VM lifecycle operations Rob Hoes
2013-11-26 17:52 ` [PATCH v5 07/12] libxl: ocaml: add console reader functions Rob Hoes
2013-11-26 17:52 ` [PATCH v5 08/12] libxl: ocaml: drop the ocaml heap lock before calling into libxl Rob Hoes
2013-11-26 18:27   ` David Scott [this message]
2013-11-26 23:14     ` Rob Hoes
2013-11-26 17:52 ` [PATCH v5 09/12] libxl: ocaml: add some missing CAML macros Rob Hoes
2013-11-26 18:29   ` David Scott
2013-11-27 11:47   ` Ian Campbell
2013-11-27 11:53     ` Ian Campbell
2013-11-26 17:52 ` [PATCH v5 10/12] libxl: ocaml: fix memory corruption when converting string and key/values lists Rob Hoes
2013-11-26 18:01   ` Andrew Cooper
2013-11-27 12:05   ` Ian Campbell
2013-11-26 17:52 ` [PATCH v5 11/12] libxl: ocaml: remove dead code in xentoollog bindings Rob Hoes
2013-11-26 18:02   ` Andrew Cooper
2013-11-27 12:09   ` Ian Campbell
2013-11-26 17:52 ` [PATCH v5 12/12] libxl: ocaml: git/hgignore generated files Rob Hoes
2013-11-27 12:10   ` Ian Campbell
2013-11-27 11:28 ` [PATCH v5 00/12] libxl: ocaml: improve the bindings Ian Campbell
2013-11-27 11:39   ` Rob Hoes
2013-11-27 14:29     ` George Dunlap

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5294E80C.4020902@eu.citrix.com \
    --to=dave.scott@eu.citrix.com \
    --cc=ian.campbell@citrix.com \
    --cc=ian.jackson@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=rob.hoes@citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).