From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Ian Campbell <Ian.Campbell@citrix.com>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>,
"Keir (Xen.org)" <keir@xen.org>, Jan Beulich <JBeulich@suse.com>,
"xen-devel@lists.xen.org" <xen-devel@lists.xen.org>
Subject: Re: [PATCH 4 of 5] tools/ocaml: libxc bindings: Fix stub_xc_readconsolering()
Date: Thu, 21 Feb 2013 11:12:03 +0000 [thread overview]
Message-ID: <51260103.9060509@citrix.com> (raw)
In-Reply-To: <1361441667.26546.50.camel@zakaz.uk.xensource.com>
On 21/02/13 10:14, Ian Campbell wrote:
> On Wed, 2013-02-20 at 18:05 +0000, Andrew Cooper wrote:
>> There are two problems with this function:
>> * The caml_{enter,leave}_blocking_section() calls mean that two threads can
>> compete for use of the static ring[] buffer.
>> * It fails to retrieve the entire buffer if the hypervisor has used 32K or
>> more of its console ring.
>>
>> Rewrite the function using the new xc_consoleringsize() and
>> xc_readconsolering_buffer() functions to efficiently grab the entire console
>> ring.
>>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
>>
>> diff -r 6b8c513cff4f -r a73d0c5a5b24 tools/ocaml/libs/xc/xenctrl_stubs.c
>> --- a/tools/ocaml/libs/xc/xenctrl_stubs.c
>> +++ b/tools/ocaml/libs/xc/xenctrl_stubs.c
>> @@ -523,27 +523,61 @@ CAMLprim value stub_xc_evtchn_reset(valu
>> CAMLreturn(Val_unit);
>> }
>>
>> -
>> -#define RING_SIZE 32768
>> -static char ring[RING_SIZE];
>> -
>> +/* Maximum size of console ring we are prepared to read, 16MB */
>> +#define MAX_CONSOLE_RING_SIZE (1U << 24)
> A bit arbitrary, why not just let it handle whatever the hypervisor
> throws at it. If there is to be a limit it probably belongs on the
> hypervisor side, but in the meantime someone who passes consring=1G can
> keep all the pieces ;-)
>
>> CAMLprim value stub_xc_readconsolering(value xch)
>> {
>> - unsigned int size = RING_SIZE - 1;
>> - char *ring_ptr = ring;
>> - int retval;
>> + uint64_t conring_size;
>> + DECLARE_HYPERCALL_BUFFER(char, ring);
>> + unsigned int nr_chars;
>> + int r;
>>
>> CAMLparam1(xch);
>> + CAMLlocal1(conring);
>> +
>> + r = xc_consoleringsize(_H(xch), &conring_size);
> static int consoleringsize and only call this once the first time?
One of the point of this patch was to remove the static buffer for
thread safety reasons. Having said that, even if you do race on this
static variable, it should be filled in with the same value, so is
probably safe?
>
>> +
>> + if ( r )
>> + {
>> + failwith_xc(_H(xch));
>> + CAMLreturn(Val_unit);
>> + }
>> +
>> + /* Round conring_size up to the next page, for NULL terminator and
>> + slop from a race with printk() in the hypervisor. */
>> + conring_size = (conring_size + XC_PAGE_SIZE) & XC_PAGE_MASK;
>> + nr_chars = conring_size-1;
>> +
>> + if ( conring_size > MAX_CONSOLE_RING_SIZE )
>> + {
>> + caml_failwith("Console ring too large");
>> + CAMLreturn(Val_unit);
>> + }
>> +
>> + ring = xc_hypercall_buffer_alloc(_H(xch), ring, conring_size);
>> +
>> + if ( ! ring )
>> + {
>> + failwith_xc(_H(xch));
>> + CAMLreturn(Val_unit);
>> + }
>>
>> caml_enter_blocking_section();
>> - retval = xc_readconsolering(_H(xch), ring_ptr, &size, 0, 0, NULL);
>> + r = xc_readconsolering_buffer(_H(xch), HYPERCALL_BUFFER(ring),
>> + &nr_chars, 0, 0, NULL);
>> caml_leave_blocking_section();
>>
>> - if (retval)
>> + if ( r )
>> + {
>> failwith_xc(_H(xch));
> Doesn't this (due to caml_raise...) end up exiting synchronously via a
> longjmp back to the runtime? i.e. it leaks the buffer which is only
> free'd after.
>
> It's a good idea to cc xen-api@ with ocaml changes, for this sort of
> reason...
I will double check that. If so, then I have some memory leaks to fix
up in other bits of Ocaml/C bindings, which I was using as an example
here...
I will cc xen-api@ for the next submission of this series.
>
>> + xc_hypercall_buffer_free(_H(xch), ring);
>> + CAMLreturn(Val_unit);
> I think CAMLnoreturn here.
Ok.
~Andrew
>
>> + }
>>
>> - ring[size] = '\0';
>> - CAMLreturn(caml_copy_string(ring));
>> + ring[nr_chars] = '\0';
>> + conring = caml_copy_string(ring);
>> + xc_hypercall_buffer_free(_H(xch), ring);
>> + CAMLreturn(conring);
>> }
>>
>> CAMLprim value stub_xc_send_debug_keys(value xch, value keys)
>
next prev parent reply other threads:[~2013-02-21 11:12 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-20 18:05 [PATCH 0 of 5] tools: console ring fixes Andrew Cooper
2013-02-20 18:05 ` [PATCH 1 of 5] common/sysctl: Introduce hypercall to query the console ring size Andrew Cooper
2013-02-20 18:05 ` [PATCH 2 of 5] tools/libxc: Helper function for XEN_SYSCTL_consoleringsize Andrew Cooper
2013-02-20 18:05 ` [PATCH 3 of 5] tools/libxc: Implement of xc_readconsolering_buffer Andrew Cooper
2013-02-21 10:01 ` Ian Campbell
2013-02-21 11:07 ` Andrew Cooper
2013-02-20 18:05 ` [PATCH 4 of 5] tools/ocaml: libxc bindings: Fix stub_xc_readconsolering() Andrew Cooper
2013-02-21 10:14 ` Ian Campbell
2013-02-21 11:12 ` Andrew Cooper [this message]
2013-02-20 18:05 ` [PATCH 5 of 5] tools/ocaml: libxc bindings: Fix failwith_xc() Andrew Cooper
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=51260103.9060509@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=Ian.Campbell@citrix.com \
--cc=Ian.Jackson@eu.citrix.com \
--cc=JBeulich@suse.com \
--cc=keir@xen.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.