[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v1 2/5] tools/ocaml/libs/xc: add binding to xc_evtchn_status


  • To: Edwin Torok <edvin.torok@xxxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Andrew Cooper <Andrew.Cooper3@xxxxxxxxxx>
  • Date: Thu, 1 Dec 2022 11:34:04 +0000
  • Accept-language: en-GB, en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=IsJUD48X9AXv83wMcV0YFo5ac0Ej2uXNkeHQNFJxams=; b=NpywdOZfCz1EvamQQ+9dWW5slyBJPNYdnqiL5Ew++d6kZ7hVYuc+f5HSlkJQjlIewmKsXSOPO6+CdfkEnSF8tlK93p1BSY5taoGgOeMUSXG+pbU0IVY8QP7bXaQMUVvUNYDE0Qk2UBQlOyjTzrlgESlpN6mxFFfgh2ISagcafONMMkiLtfvukWf4oB3Xv+5TMvBjEf0Xl7vs3Dieriq/S6ajRmJzM945lgenC2TwKAn7of5m1RDa1K+JmixAwv4D7y108sIbDJRC7+3WwTO+q35MXu5SZiqwmRqm272op5v9KQNXHSMBLBGxXIWBF3F+Bs9shU+IFrTw8xVagwmRYQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TUkm1ft61yWq0AhmhlVJIS58CISMS95Oz4S2OrKTTJAmGYmG0AtxgB/10dLTY0Ly5AXkFcqGWe6x+gi1YT9exRlQy5WfOkMwkbiVLdI1iwmbAW0iZeCMBktZU7hgTtQdiauk9ZZ1O5Vj+YuOYDc0Deh7bGomMiXn14pe2HlpDuXiegcmNt64roezpDGQJQAnmwt+i92sYxnWD273fzJm0kdIQCVnyUrkyvj0+gmVXTHVDVUsX3ynJa0EKS/a7efPSLdH+jzhCS3B+dnAdqkn9wXyqDVPVSuOrIivktmEgd1au+J0RfMNB3QIkb8gDyTrP52uhaSXGppqfGqA+FjQww==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: Christian Lindig <christian.lindig@xxxxxxxxxx>, David Scott <dave@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Anthony Perard <anthony.perard@xxxxxxxxxx>
  • Delivery-date: Thu, 01 Dec 2022 11:34:17 +0000
  • Ironport-data: A9a23:I+m/HKowf8TO+GF8vsLZ9yijqPJeBmI4ZBIvgKrLsJaIsI4StFCzt garIBmDOKmKYDamedggaNu2oUoC7cfXmtcxHFZkrygxQXsbpZuZCYyVIHmrMnLJJKUvbq7FA +Y2MYCccZ9uHhcwgj/3b9ANeFEljfngqoLUUbKCYWYpAFc+E0/NsDo788YhmIlknNOlNA2Ev NL2sqX3NUSsnjV5KQr40YrawP9UlKm06W1wUmAWP6gR5gaEzyBNVvrzGInqR5fGatgMdgKFb 76rIIGRpgvx4xorA9W5pbf3GmVirmn6ZFXmZtJ+AsBOszAazsAA+v9T2Mk0MC+7vw6hjdFpo OihgLTrIesf0g8gr8xGO/VQO3kW0aSrY9YrK1Dn2SCY5xWun3cBX5yCpaz5VGEV0r8fPI1Ay RAXAA81YgiZurOH+pSYUsterNwJEpe2f4xK7xmMzRmBZRonabbqZvySoPN9gnI3jM0IGuvCb c0EbzYpdA7HfxBEJlYQDtQ5gfusgX78NTZfrTp5p4JuuzSVkFM3jeiraYKIEjCJbZw9ckKwj 2TK5WnmRDodM8SS02Gt+XOwnO7f2yj8Xer+EZXoqKYx3A3PnwT/DjU9TmSKv9qAm3WkSoNbA l03oRQEtZILoRnDot7VGkfQTGS/lg4RXZ9cHvM37CmJy7HI+ECJC24cVDlDZdc68sgsSlQC2 laXkvvzCDdosbnTTmiSnp+LqRuiNC5TKnUNDRLoViMA6tjn5Y020BTGS487FLbv14WoXzbt3 zqNsS4ywa0JitIG3Lm6+laBhC+wop/OTUg+4QC/sn+Z0z6VrbWNP+SAgWU3J94ZRGpFZjFtZ EQ5pvU=
  • Ironport-hdrordr: A9a23:AApn96GcNewHTJ29pLqE1seALOsnbusQ8zAXPiFKKCC9F/by/f xG885rtiMc5Ax9ZJhYo6HnBEDiex3hHPxOjbX5VI3KNDUP0gOTXfhfBODZrAEIdRefygZQvZ 0QEZSXBbXLfD9HZcyT2njcLz4uqOP3lJyVuQ==
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHZBOHxNXiRQvtogESX/t4C8rGLVK5Y590A
  • Thread-topic: [PATCH v1 2/5] tools/ocaml/libs/xc: add binding to xc_evtchn_status

On 30/11/2022 17:32, Edwin Török wrote:
> There is no API or ioctl to query event channel status, it is only
> present in xenctrl.h

Yeah, this is very unfortunate, because it really wanted to be part of
the xenevtchn stable API/ABI.

> The C union is mapped to an OCaml variant exposing just the value from the
> correct union tag.
>
> Querying event channel status is useful when analyzing Windows VMs that
> may have reset and changed the xenstore event channel port number from
> what it initially got booted with.

This paragraph is why we need it now, but it's not really relevant for
the upstream commit.  I'd drop this sentence, and simply how the lower
one noting the similarity to lsevtchn.

> The information provided here is similar to 'lstevtchn', but rather than

"lsevtchn".

> parsing its output it queries the underlying API directly.
>
> Signed-off-by: Edwin Török <edvin.torok@xxxxxxxxxx>
> ---
>  tools/ocaml/libs/xc/xenctrl.ml      | 14 +++++++
>  tools/ocaml/libs/xc/xenctrl.mli     | 15 +++++++
>  tools/ocaml/libs/xc/xenctrl_stubs.c | 65 +++++++++++++++++++++++++++++
>  3 files changed, 94 insertions(+)
>
> diff --git a/tools/ocaml/libs/xc/xenctrl.ml b/tools/ocaml/libs/xc/xenctrl.ml
> index 2ed7454b16..c21e391f98 100644
> --- a/tools/ocaml/libs/xc/xenctrl.ml
> +++ b/tools/ocaml/libs/xc/xenctrl.ml
> @@ -267,6 +267,20 @@ external evtchn_alloc_unbound: handle -> domid -> domid 
> -> int
>    = "stub_xc_evtchn_alloc_unbound"
>  external evtchn_reset: handle -> domid -> unit = "stub_xc_evtchn_reset"
>  
> +type evtchn_interdomain = { dom: domid; port: int}

Strictly speaking, port needs to be int32.

ABI-wise, it can be configured as large as 2^32-2 during domain creation.

However, FIFO currently tops out at 2^17 and has a theoretical maximum
at 2^28, so perhaps int ought to enough for now.

> +
> +type evtchn_stat =
> +  | EVTCHNSTAT_unbound of domid
> +  | EVTCHNSTAT_interdomain of evtchn_interdomain
> +  | EVTCHNSTAT_pirq of int
> +  | EVTCHNSTAT_virq of int

Similar comment.  A vcpu id should in principle be int32

> +  | EVTCHNSTAT_ipi

Normally when having an enumeration like this, we want to hook up the
build-time ABI check.

But in this case, it's produced by the bindings (not consumed by them),
and there's an exception raised in the default case, so I don't think we
need the build-time ABI check for any kind of safety (and therefore
shouldn't go to the reasonably-invasive effort of adding the check).

> diff --git a/tools/ocaml/libs/xc/xenctrl_stubs.c 
> b/tools/ocaml/libs/xc/xenctrl_stubs.c
> index d30585f21c..67f3648391 100644
> --- a/tools/ocaml/libs/xc/xenctrl_stubs.c
> +++ b/tools/ocaml/libs/xc/xenctrl_stubs.c
> @@ -641,6 +641,71 @@ CAMLprim value stub_xc_evtchn_reset(value xch, value 
> domid)
>      CAMLreturn(Val_unit);
>  }
>  
> +CAMLprim value stub_xc_evtchn_status(value xch, value domid, value port)
> +{
> +    CAMLparam3(xch, domid, port);
> +    CAMLlocal4(result, result_status, stat, interdomain);
> +    xc_evtchn_status_t status;
> +    int rc;
> +
> +    memset(&status, 0, sizeof(status));
> +    status.dom = _D(domid);
> +    status.port = Int_val(port);

xc_evtchn_status_t status = {
    .dom = _D(domid),
    .port = Int_val(port),
};

is the marginally preferred way of doing this.  It removes potential
issues with typo-ing the memset().

> +
> +    caml_enter_blocking_section();
> +    rc = xc_evtchn_status(_H(xch), &status);
> +    caml_leave_blocking_section();
> +
> +    if ( rc < 0 )
> +        failwith_xc(_H(xch));
> +
> +    if ( status.status == EVTCHNSTAT_closed )
> +        result = Val_none;
> +    else
> +    {

This is actually one example where using a second CAMLreturn would
simply things substantially.

switch ( status.status )
{
case EVTCHNSTAT_closed:
    CAMLreturn(Val_none);

case EVTCHNSTAT_unbound:
    ...

Would remove the need for the outer if/else.


> +        switch ( status.status )
> +        {
> +        case EVTCHNSTAT_unbound:
> +            stat = caml_alloc(1, 0); /* 1st non-constant constructor */
> +            Store_field(stat, 0, Val_int(status.u.unbound.dom));
> +            break;
> +
> +        case EVTCHNSTAT_interdomain:
> +            interdomain = caml_alloc_tuple(2);
> +            Store_field(interdomain, 0, Val_int(status.u.interdomain.dom));
> +            Store_field(interdomain, 1, Val_int(status.u.interdomain.port));
> +            stat = caml_alloc(1, 1); /*  2nd non-constant constructor */
> +            Store_field(stat, 0, interdomain);
> +            break;
> +        case EVTCHNSTAT_pirq:
> +            stat = caml_alloc(1, 2); /* 3rd non-constant constructor */
> +            Store_field(stat, 0, Val_int(status.u.pirq));
> +            break;
> +
> +        case EVTCHNSTAT_virq:
> +            stat = caml_alloc(1, 3); /* 4th non-constant constructor */
> +            Store_field(stat, 0, Val_int(status.u.virq));
> +            break;
> +
> +        case EVTCHNSTAT_ipi:
> +            stat = Val_int(0); /* 1st constant constructor */
> +            break;
> +
> +        default:
> +            caml_failwith("Unkown evtchn status");
> +        }

We'd normally have a blank line here.

> +        result_status = caml_alloc_tuple(2);
> +        Store_field(result_status, 0, Val_int(status.vcpu));
> +        Store_field(result_status, 1, stat);
> +
> +        /* Tag_some and caml_alloc_some are missing in older versions of 
> OCaml
> +         */

Can we do the usual

#ifndef Tag_some
# define Tag_some ...
#endif

at the top, and use it unconditionally here?

caml_alloc_some() is perhaps less interesting as it only appeared in
Ocaml 4.12 AFAICT, but we could also have some ifdefary for that at the
top of the file.

I don't know whether we have opencoded options elsewhere in the
bindings, but it certainly would be reduce the amount opencoding that
exists for standard patterns.

~Andrew

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.