180a06cc5SStefan Hajnoczi /* 280a06cc5SStefan Hajnoczi * Sharing QEMU devices via vhost-user protocol 380a06cc5SStefan Hajnoczi * 480a06cc5SStefan Hajnoczi * Copyright (c) Coiby Xu <coiby.xu@gmail.com>. 580a06cc5SStefan Hajnoczi * Copyright (c) 2020 Red Hat, Inc. 680a06cc5SStefan Hajnoczi * 780a06cc5SStefan Hajnoczi * This work is licensed under the terms of the GNU GPL, version 2 or 880a06cc5SStefan Hajnoczi * later. See the COPYING file in the top-level directory. 980a06cc5SStefan Hajnoczi */ 1080a06cc5SStefan Hajnoczi 1180a06cc5SStefan Hajnoczi #ifndef VHOST_USER_SERVER_H 1280a06cc5SStefan Hajnoczi #define VHOST_USER_SERVER_H 1380a06cc5SStefan Hajnoczi 140df750e9SMarc-André Lureau #include "subprojects/libvhost-user/libvhost-user.h" /* only for the type definitions */ 1580a06cc5SStefan Hajnoczi #include "io/channel-socket.h" 1680a06cc5SStefan Hajnoczi #include "io/channel-file.h" 1780a06cc5SStefan Hajnoczi #include "io/net-listener.h" 1880a06cc5SStefan Hajnoczi #include "qapi/error.h" 1980a06cc5SStefan Hajnoczi #include "standard-headers/linux/virtio_blk.h" 2080a06cc5SStefan Hajnoczi 2180a06cc5SStefan Hajnoczi /* A kick fd that we monitor on behalf of libvhost-user */ 2280a06cc5SStefan Hajnoczi typedef struct VuFdWatch { 2380a06cc5SStefan Hajnoczi VuDev *vu_dev; 2480a06cc5SStefan Hajnoczi int fd; /*kick fd*/ 2580a06cc5SStefan Hajnoczi void *pvt; 2680a06cc5SStefan Hajnoczi vu_watch_cb cb; 2780a06cc5SStefan Hajnoczi QTAILQ_ENTRY(VuFdWatch) next; 2880a06cc5SStefan Hajnoczi } VuFdWatch; 2980a06cc5SStefan Hajnoczi 3080a06cc5SStefan Hajnoczi /** 3180a06cc5SStefan Hajnoczi * VuServer: 3280a06cc5SStefan Hajnoczi * A vhost-user server instance with user-defined VuDevIface callbacks. 3380a06cc5SStefan Hajnoczi * Vhost-user device backends can be implemented using VuServer. VuDevIface 3480a06cc5SStefan Hajnoczi * callbacks and virtqueue kicks run in the given AioContext. 3580a06cc5SStefan Hajnoczi */ 3680a06cc5SStefan Hajnoczi typedef struct { 3780a06cc5SStefan Hajnoczi QIONetListener *listener; 3880a06cc5SStefan Hajnoczi QEMUBH *restart_listener_bh; 3980a06cc5SStefan Hajnoczi AioContext *ctx; 4080a06cc5SStefan Hajnoczi int max_queues; 4180a06cc5SStefan Hajnoczi const VuDevIface *vu_iface; 4280a06cc5SStefan Hajnoczi 438f5e9a8eSStefan Hajnoczi unsigned int in_flight; /* atomic */ 448f5e9a8eSStefan Hajnoczi 4580a06cc5SStefan Hajnoczi /* Protected by ctx lock */ 4606e0f098SStefan Hajnoczi bool in_qio_channel_yield; 47520d8b40SKevin Wolf bool wait_idle; 48*411132c9SKevin Wolf bool quiescing; 4980a06cc5SStefan Hajnoczi VuDev vu_dev; 5080a06cc5SStefan Hajnoczi QIOChannel *ioc; /* The I/O channel with the client */ 5180a06cc5SStefan Hajnoczi QIOChannelSocket *sioc; /* The underlying data channel with the client */ 5280a06cc5SStefan Hajnoczi QTAILQ_HEAD(, VuFdWatch) vu_fd_watches; 5380a06cc5SStefan Hajnoczi 5480a06cc5SStefan Hajnoczi Coroutine *co_trip; /* coroutine for processing VhostUserMsg */ 5580a06cc5SStefan Hajnoczi } VuServer; 5680a06cc5SStefan Hajnoczi 5780a06cc5SStefan Hajnoczi bool vhost_user_server_start(VuServer *server, 5880a06cc5SStefan Hajnoczi SocketAddress *unix_socket, 5980a06cc5SStefan Hajnoczi AioContext *ctx, 6080a06cc5SStefan Hajnoczi uint16_t max_queues, 6180a06cc5SStefan Hajnoczi const VuDevIface *vu_iface, 6280a06cc5SStefan Hajnoczi Error **errp); 6380a06cc5SStefan Hajnoczi 6480a06cc5SStefan Hajnoczi void vhost_user_server_stop(VuServer *server); 6580a06cc5SStefan Hajnoczi 6675d33e85SStefan Hajnoczi void vhost_user_server_inc_in_flight(VuServer *server); 6775d33e85SStefan Hajnoczi void vhost_user_server_dec_in_flight(VuServer *server); 688f5e9a8eSStefan Hajnoczi bool vhost_user_server_has_in_flight(VuServer *server); 69520d8b40SKevin Wolf 7080a06cc5SStefan Hajnoczi void vhost_user_server_attach_aio_context(VuServer *server, AioContext *ctx); 7180a06cc5SStefan Hajnoczi void vhost_user_server_detach_aio_context(VuServer *server); 7280a06cc5SStefan Hajnoczi 7380a06cc5SStefan Hajnoczi #endif /* VHOST_USER_SERVER_H */ 74