|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v3 1/3] tools/libs/evtchn: decouple more from mini-os
Juergen Gross, le dim. 16 janv. 2022 09:23:44 +0100, a ecrit:
> Mini-OS and libevtchn are using implementation details of each other.
> Change that by letting libevtchn use the new alloc_file_type() and
> get_file_from_fd() function and the generic dev pointer of struct file
> from Mini-OS.
>
> By using private struct declarations Mini-OS will be able to drop the
> libevtchn specific definitions of struct evtchn_port_info and
> evtchn_port_list in future. While at it use bool for "pending" and
> "bound".
>
> Switch to use xce as function parameter instead of fd where possible.
>
> Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
Reviewed-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx>
> ---
> V2:
> - use xce instead of fd as parameter internally (Andrew Cooper)
> - add alloc_file_type() support
> V3:
> - switch callback to use struct file * as a parameter (Andrew Cooper)
> - use __attribute__((constructor)) (Andrew Cooper)
> ---
> tools/libs/evtchn/minios.c | 143 +++++++++++++++++++++++++------------
> 1 file changed, 96 insertions(+), 47 deletions(-)
>
> diff --git a/tools/libs/evtchn/minios.c b/tools/libs/evtchn/minios.c
> index 8f84048b11..ee3da9f8fe 100644
> --- a/tools/libs/evtchn/minios.c
> +++ b/tools/libs/evtchn/minios.c
> @@ -38,29 +38,40 @@
>
> #include "private.h"
>
> -extern void minios_evtchn_close_fd(int fd);
> +LIST_HEAD(port_list, port_info);
> +
> +struct port_info {
> + LIST_ENTRY(port_info) list;
> + evtchn_port_t port;
> + bool pending;
> + bool bound;
> +};
>
> extern struct wait_queue_head event_queue;
>
> +void minios_evtchn_close_fd(int fd);
> +
> /* XXX Note: This is not threadsafe */
> -static struct evtchn_port_info *port_alloc(int fd)
> +static struct port_info *port_alloc(xenevtchn_handle *xce)
> {
> - struct evtchn_port_info *port_info;
> + struct port_info *port_info;
> + struct file *file = get_file_from_fd(xce->fd);
> + struct port_list *port_list = file->dev;
>
> - port_info = malloc(sizeof(struct evtchn_port_info));
> + port_info = malloc(sizeof(struct port_info));
> if ( port_info == NULL )
> return NULL;
>
> - port_info->pending = 0;
> + port_info->pending = false;
> port_info->port = -1;
> - port_info->bound = 0;
> + port_info->bound = false;
>
> - LIST_INSERT_HEAD(&files[fd].evtchn.ports, port_info, list);
> + LIST_INSERT_HEAD(port_list, port_info, list);
>
> return port_info;
> }
>
> -static void port_dealloc(struct evtchn_port_info *port_info)
> +static void port_dealloc(struct port_info *port_info)
> {
> if ( port_info->bound )
> unbind_evtchn(port_info->port);
> @@ -69,18 +80,57 @@ static void port_dealloc(struct evtchn_port_info
> *port_info)
> free(port_info);
> }
>
> +static int evtchn_close_fd(struct file *file)
> +{
> + struct port_info *port_info, *tmp;
> + struct port_list *port_list = file->dev;
> +
> + LIST_FOREACH_SAFE(port_info, port_list, list, tmp)
> + port_dealloc(port_info);
> + free(port_list);
> +
> + return 0;
> +}
> +
> +static const struct file_ops evtchn_ops = {
> + .name = "evtchn",
> + .close = evtchn_close_fd,
> + .select_rd = select_read_flag,
> +};
> +
> +static unsigned int ftype_evtchn;
> +
> +__attribute__((constructor))
> +static void evtchn_initialize(void)
> +{
> + ftype_evtchn = alloc_file_type(&evtchn_ops);
> +}
> +
> /*
> * XENEVTCHN_NO_CLOEXEC is being ignored, as there is no exec() call
> supported
> * in Mini-OS.
> */
> int osdep_evtchn_open(xenevtchn_handle *xce, unsigned int flags)
> {
> - int fd = alloc_fd(FTYPE_EVTCHN);
> + int fd;
> + struct file *file;
> + struct port_list *list;
>
> - if ( fd == -1 )
> + list = malloc(sizeof(*list));
> + if ( !list )
> return -1;
>
> - LIST_INIT(&files[fd].evtchn.ports);
> + fd = alloc_fd(ftype_evtchn);
> + file = get_file_from_fd(fd);
> +
> + if ( !file )
> + {
> + free(list);
> + return -1;
> + }
> +
> + file->dev = list;
> + LIST_INIT(list);
> xce->fd = fd;
> printf("evtchn_open() -> %d\n", fd);
>
> @@ -104,12 +154,9 @@ int osdep_evtchn_restrict(xenevtchn_handle *xce, domid_t
> domid)
>
> void minios_evtchn_close_fd(int fd)
> {
> - struct evtchn_port_info *port_info, *tmp;
> + struct file *file = get_file_from_fd(fd);
>
> - LIST_FOREACH_SAFE(port_info, &files[fd].evtchn.ports, list, tmp)
> - port_dealloc(port_info);
> -
> - files[fd].type = FTYPE_NONE;
> + evtchn_close_fd(file);
> }
>
> int xenevtchn_notify(xenevtchn_handle *xce, evtchn_port_t port)
> @@ -129,42 +176,43 @@ int xenevtchn_notify(xenevtchn_handle *xce,
> evtchn_port_t port)
>
> static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void
> *data)
> {
> - int fd = (int)(intptr_t)data;
> - struct evtchn_port_info *port_info;
> + xenevtchn_handle *xce = data;
> + struct file *file = get_file_from_fd(xce->fd);
> + struct port_info *port_info;
> + struct port_list *port_list;
>
> - assert(files[fd].type == FTYPE_EVTCHN);
> + assert(file);
> + port_list = file->dev;
> mask_evtchn(port);
> - LIST_FOREACH(port_info, &files[fd].evtchn.ports, list)
> + LIST_FOREACH(port_info, port_list, list)
> {
> if ( port_info->port == port )
> goto found;
> }
>
> - printk("Unknown port for handle %d\n", fd);
> + printk("Unknown port %d for handle %d\n", port, xce->fd);
> return;
>
> found:
> - port_info->pending = 1;
> - files[fd].read = 1;
> + port_info->pending = true;
> + file->read = true;
> wake_up(&event_queue);
> }
>
> xenevtchn_port_or_error_t xenevtchn_bind_unbound_port(xenevtchn_handle *xce,
> uint32_t domid)
> {
> - int fd = xce->fd;
> - struct evtchn_port_info *port_info;
> + struct port_info *port_info;
> int ret;
> evtchn_port_t port;
>
> assert(get_current() == main_thread);
> - port_info = port_alloc(fd);
> + port_info = port_alloc(xce);
> if ( port_info == NULL )
> return -1;
>
> printf("xenevtchn_bind_unbound_port(%d)", domid);
> - ret = evtchn_alloc_unbound(domid, evtchn_handler,
> - (void *)(intptr_t)fd, &port);
> + ret = evtchn_alloc_unbound(domid, evtchn_handler, xce, &port);
> printf(" = %d\n", ret);
>
> if ( ret < 0 )
> @@ -174,7 +222,7 @@ xenevtchn_port_or_error_t
> xenevtchn_bind_unbound_port(xenevtchn_handle *xce,
> return -1;
> }
>
> - port_info->bound = 1;
> + port_info->bound = true;
> port_info->port = port;
> unmask_evtchn(port);
>
> @@ -185,19 +233,18 @@ xenevtchn_port_or_error_t
> xenevtchn_bind_interdomain(xenevtchn_handle *xce,
> uint32_t domid,
> evtchn_port_t
> remote_port)
> {
> - int fd = xce->fd;
> - struct evtchn_port_info *port_info;
> + struct port_info *port_info;
> evtchn_port_t local_port;
> int ret;
>
> assert(get_current() == main_thread);
> - port_info = port_alloc(fd);
> + port_info = port_alloc(xce);
> if ( port_info == NULL )
> return -1;
>
> printf("xenevtchn_bind_interdomain(%d, %"PRId32")", domid, remote_port);
> ret = evtchn_bind_interdomain(domid, remote_port, evtchn_handler,
> - (void *)(intptr_t)fd, &local_port);
> + xce, &local_port);
> printf(" = %d\n", ret);
>
> if ( ret < 0 )
> @@ -207,7 +254,7 @@ xenevtchn_port_or_error_t
> xenevtchn_bind_interdomain(xenevtchn_handle *xce,
> return -1;
> }
>
> - port_info->bound = 1;
> + port_info->bound = true;
> port_info->port = local_port;
> unmask_evtchn(local_port);
>
> @@ -217,9 +264,11 @@ xenevtchn_port_or_error_t
> xenevtchn_bind_interdomain(xenevtchn_handle *xce,
> int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port)
> {
> int fd = xce->fd;
> - struct evtchn_port_info *port_info;
> + struct file *file = get_file_from_fd(fd);
> + struct port_info *port_info;
> + struct port_list *port_list = file->dev;
>
> - LIST_FOREACH(port_info, &files[fd].evtchn.ports, list)
> + LIST_FOREACH(port_info, port_list, list)
> {
> if ( port_info->port == port )
> {
> @@ -238,17 +287,16 @@ int xenevtchn_unbind(xenevtchn_handle *xce,
> evtchn_port_t port)
> xenevtchn_port_or_error_t xenevtchn_bind_virq(xenevtchn_handle *xce,
> unsigned int virq)
> {
> - int fd = xce->fd;
> - struct evtchn_port_info *port_info;
> + struct port_info *port_info;
> evtchn_port_t port;
>
> assert(get_current() == main_thread);
> - port_info = port_alloc(fd);
> + port_info = port_alloc(xce);
> if ( port_info == NULL )
> return -1;
>
> printf("xenevtchn_bind_virq(%d)", virq);
> - port = bind_virq(virq, evtchn_handler, (void *)(intptr_t)fd);
> + port = bind_virq(virq, evtchn_handler, xce);
> printf(" = %d\n", port);
>
> if ( port < 0 )
> @@ -258,7 +306,7 @@ xenevtchn_port_or_error_t
> xenevtchn_bind_virq(xenevtchn_handle *xce,
> return -1;
> }
>
> - port_info->bound = 1;
> + port_info->bound = true;
> port_info->port = port;
> unmask_evtchn(port);
>
> @@ -267,27 +315,28 @@ xenevtchn_port_or_error_t
> xenevtchn_bind_virq(xenevtchn_handle *xce,
>
> xenevtchn_port_or_error_t xenevtchn_pending(xenevtchn_handle *xce)
> {
> - int fd = xce->fd;
> - struct evtchn_port_info *port_info;
> + struct file *file = get_file_from_fd(xce->fd);
> + struct port_info *port_info;
> + struct port_list *port_list = file->dev;
> unsigned long flags;
> evtchn_port_t ret = -1;
>
> local_irq_save(flags);
>
> - files[fd].read = 0;
> + file->read = false;
>
> - LIST_FOREACH(port_info, &files[fd].evtchn.ports, list)
> + LIST_FOREACH(port_info, port_list, list)
> {
> if ( port_info->port != -1 && port_info->pending )
> {
> if ( ret == -1 )
> {
> ret = port_info->port;
> - port_info->pending = 0;
> + port_info->pending = false;
> }
> else
> {
> - files[fd].read = 1;
> + file->read = true;
> break;
> }
> }
> --
> 2.26.2
>
--
Samuel
> Allez, soyez sympa ... traduisez-lui "linux"
Linux, c'est comme le miel : c'est vachement bon mais ça attire les
mouches. En plus, ça colle aux doigts et on a du mal à s'en défaire.
-+- TP in: Guide du linuxien pervers - "Barrez vous les mouches !"
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |