Re: [Qemu-devel] [PATCH v3 5/9] xen/9pfs: connect to the frontend
On Fri, 17 Mar 2017, Greg Kurz wrote: > On Thu, 16 Mar 2017 13:01:54 -0700 > Stefano Stabelliniwrote: > > > Write the limits of the backend to xenstore. Connect to the frontend. > > Upon connection, allocate the rings according to the protocol > > specification. > > > > Initialize a QEMUBH to schedule work upon receiving an event channel > > notification from the frontend. > > > > Signed-off-by: Stefano Stabellini > > CC: anthony.per...@citrix.com > > CC: jgr...@suse.com > > CC: Aneesh Kumar K.V > > CC: Greg Kurz > > --- > > hw/9pfs/xen-9p-backend.c | 182 > > ++- > > 1 file changed, 181 insertions(+), 1 deletion(-) > > > > diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c > > index 92bb805..3fd20ff 100644 > > --- a/hw/9pfs/xen-9p-backend.c > > +++ b/hw/9pfs/xen-9p-backend.c > > @@ -23,8 +23,39 @@ > > #define XEN_9PFS_RING_SIZE XEN_FLEX_RING_SIZE(XEN_9PFS_RING_ORDER) > > DEFINE_XEN_FLEX_RING_AND_INTF(xen_9pfs); > > > > +#define VERSIONS "1" > > +#define MAX_RINGS 8 > > +#define MAX_RING_ORDER 8 > > + > > +typedef struct Xen9pfsRing { > > +struct Xen9pfsDev *priv; > > + > > +int ref; > > +xenevtchn_handle *evtchndev; > > +int evtchn; > > +int local_port; > > +struct xen_9pfs_data_intf *intf; > > +unsigned char *data; > > +struct xen_9pfs_data ring; > > + > > +QEMUBH *bh; > > + > > +/* local copies, so that we can read/write PDU data directly from > > + * the ring */ > > +RING_IDX out_cons, out_size, in_cons; > > +bool inprogress; > > +} Xen9pfsRing; > > + > > typedef struct Xen9pfsDev { > > struct XenDevice xendev; /* must be first */ > > +V9fsState state; > > +char *path; > > +char *security_model; > > +char *tag; > > +char *id; > > + > > +int num_rings; > > +Xen9pfsRing *rings; > > } Xen9pfsDev; > > > > static ssize_t xen_9pfs_pdu_vmarshal(V9fsPDU *pdu, > > @@ -73,22 +104,171 @@ static int xen_9pfs_init(struct XenDevice *xendev) > > return 0; > > } > > > > +static void xen_9pfs_bh(void *opaque) > > +{ > > +} > > + > > +static void xen_9pfs_evtchn_event(void *opaque) > > +{ > > +} > > + > > static int xen_9pfs_free(struct XenDevice *xendev) > > { > > -return -1; > > +int i; > > +Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev); > > + > > +if (xen_9pdev->id != NULL) { > > +g_free(xen_9pdev->id); > > +} > > +if (xen_9pdev->tag != NULL) { > > +g_free(xen_9pdev->tag); > > +} > > +if (xen_9pdev->path != NULL) { > > +g_free(xen_9pdev->path); > > +} > > +if (xen_9pdev->security_model != NULL) { > > +g_free(xen_9pdev->security_model); > > +} > > You don't need the if's since g_free(NULL) is legal. I'll make the changes, thanks > > + > > +for (i = 0; i < xen_9pdev->num_rings; i++) { > > +if (xen_9pdev->rings[i].data != NULL) { > > +xengnttab_unmap(xen_9pdev->xendev.gnttabdev, > > +xen_9pdev->rings[i].data, > > +(1 << XEN_9PFS_RING_ORDER)); > > +} > > +if (xen_9pdev->rings[i].intf != NULL) { > > +xengnttab_unmap(xen_9pdev->xendev.gnttabdev, > > +xen_9pdev->rings[i].intf, > > +1); > > +} > > +if (xen_9pdev->rings[i].evtchndev > 0) { > > + > > qemu_set_fd_handler(xenevtchn_fd(xen_9pdev->rings[i].evtchndev), > > +NULL, NULL, NULL); > > +xenevtchn_unbind(xen_9pdev->rings[i].evtchndev, > > + xen_9pdev->rings[i].local_port); > > +} > > +if (xen_9pdev->rings[i].bh != NULL) { > > +qemu_bh_delete(xen_9pdev->rings[i].bh); > > +} > > +} > > +g_free(xen_9pdev->rings); > > +return 0; > > } > > > > static int xen_9pfs_connect(struct XenDevice *xendev) > > { > > +int i; > > +Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev); > > +V9fsState *s = _9pdev->state; > > +QemuOpts *fsdev; > > + > > +if (xenstore_read_fe_int(_9pdev->xendev, "num-rings", > > + _9pdev->num_rings) == -1 || > > +xen_9pdev->num_rings > MAX_RINGS || xen_9pdev->num_rings < 1) { > > +return -1; > > +} > > + > > +xen_9pdev->rings = g_malloc0(xen_9pdev->num_rings * > > sizeof(Xen9pfsRing)); > > +for (i = 0; i < xen_9pdev->num_rings; i++) { > > +char *str; > > + > > +xen_9pdev->rings[i].priv = xen_9pdev; > > +xen_9pdev->rings[i].evtchn = -1; > > +xen_9pdev->rings[i].local_port = -1; > > + > > +str = g_strdup_printf("ring-ref%u", i); > > +if (xenstore_read_fe_int(_9pdev->xendev, str, > > + _9pdev->rings[i].ref) == -1) { > > +goto out; > > +} > > +
Re: [Qemu-devel] [PATCH v3 5/9] xen/9pfs: connect to the frontend
On Thu, 16 Mar 2017 13:01:54 -0700 Stefano Stabelliniwrote: > Write the limits of the backend to xenstore. Connect to the frontend. > Upon connection, allocate the rings according to the protocol > specification. > > Initialize a QEMUBH to schedule work upon receiving an event channel > notification from the frontend. > > Signed-off-by: Stefano Stabellini > CC: anthony.per...@citrix.com > CC: jgr...@suse.com > CC: Aneesh Kumar K.V > CC: Greg Kurz > --- > hw/9pfs/xen-9p-backend.c | 182 > ++- > 1 file changed, 181 insertions(+), 1 deletion(-) > > diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c > index 92bb805..3fd20ff 100644 > --- a/hw/9pfs/xen-9p-backend.c > +++ b/hw/9pfs/xen-9p-backend.c > @@ -23,8 +23,39 @@ > #define XEN_9PFS_RING_SIZE XEN_FLEX_RING_SIZE(XEN_9PFS_RING_ORDER) > DEFINE_XEN_FLEX_RING_AND_INTF(xen_9pfs); > > +#define VERSIONS "1" > +#define MAX_RINGS 8 > +#define MAX_RING_ORDER 8 > + > +typedef struct Xen9pfsRing { > +struct Xen9pfsDev *priv; > + > +int ref; > +xenevtchn_handle *evtchndev; > +int evtchn; > +int local_port; > +struct xen_9pfs_data_intf *intf; > +unsigned char *data; > +struct xen_9pfs_data ring; > + > +QEMUBH *bh; > + > +/* local copies, so that we can read/write PDU data directly from > + * the ring */ > +RING_IDX out_cons, out_size, in_cons; > +bool inprogress; > +} Xen9pfsRing; > + > typedef struct Xen9pfsDev { > struct XenDevice xendev; /* must be first */ > +V9fsState state; > +char *path; > +char *security_model; > +char *tag; > +char *id; > + > +int num_rings; > +Xen9pfsRing *rings; > } Xen9pfsDev; > > static ssize_t xen_9pfs_pdu_vmarshal(V9fsPDU *pdu, > @@ -73,22 +104,171 @@ static int xen_9pfs_init(struct XenDevice *xendev) > return 0; > } > > +static void xen_9pfs_bh(void *opaque) > +{ > +} > + > +static void xen_9pfs_evtchn_event(void *opaque) > +{ > +} > + > static int xen_9pfs_free(struct XenDevice *xendev) > { > -return -1; > +int i; > +Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev); > + > +if (xen_9pdev->id != NULL) { > +g_free(xen_9pdev->id); > +} > +if (xen_9pdev->tag != NULL) { > +g_free(xen_9pdev->tag); > +} > +if (xen_9pdev->path != NULL) { > +g_free(xen_9pdev->path); > +} > +if (xen_9pdev->security_model != NULL) { > +g_free(xen_9pdev->security_model); > +} You don't need the if's since g_free(NULL) is legal. > + > +for (i = 0; i < xen_9pdev->num_rings; i++) { > +if (xen_9pdev->rings[i].data != NULL) { > +xengnttab_unmap(xen_9pdev->xendev.gnttabdev, > +xen_9pdev->rings[i].data, > +(1 << XEN_9PFS_RING_ORDER)); > +} > +if (xen_9pdev->rings[i].intf != NULL) { > +xengnttab_unmap(xen_9pdev->xendev.gnttabdev, > +xen_9pdev->rings[i].intf, > +1); > +} > +if (xen_9pdev->rings[i].evtchndev > 0) { > +qemu_set_fd_handler(xenevtchn_fd(xen_9pdev->rings[i].evtchndev), > +NULL, NULL, NULL); > +xenevtchn_unbind(xen_9pdev->rings[i].evtchndev, > + xen_9pdev->rings[i].local_port); > +} > +if (xen_9pdev->rings[i].bh != NULL) { > +qemu_bh_delete(xen_9pdev->rings[i].bh); > +} > +} > +g_free(xen_9pdev->rings); > +return 0; > } > > static int xen_9pfs_connect(struct XenDevice *xendev) > { > +int i; > +Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev); > +V9fsState *s = _9pdev->state; > +QemuOpts *fsdev; > + > +if (xenstore_read_fe_int(_9pdev->xendev, "num-rings", > + _9pdev->num_rings) == -1 || > +xen_9pdev->num_rings > MAX_RINGS || xen_9pdev->num_rings < 1) { > +return -1; > +} > + > +xen_9pdev->rings = g_malloc0(xen_9pdev->num_rings * sizeof(Xen9pfsRing)); > +for (i = 0; i < xen_9pdev->num_rings; i++) { > +char *str; > + > +xen_9pdev->rings[i].priv = xen_9pdev; > +xen_9pdev->rings[i].evtchn = -1; > +xen_9pdev->rings[i].local_port = -1; > + > +str = g_strdup_printf("ring-ref%u", i); > +if (xenstore_read_fe_int(_9pdev->xendev, str, > + _9pdev->rings[i].ref) == -1) { > +goto out; > +} > +g_free(str); > +str = g_strdup_printf("event-channel-%u", i); > +if (xenstore_read_fe_int(_9pdev->xendev, str, > + _9pdev->rings[i].evtchn) == -1) { > +goto out; > +} > +g_free(str); > + > +xen_9pdev->rings[i].intf = xengnttab_map_grant_ref( > +
[Qemu-devel] [PATCH v3 5/9] xen/9pfs: connect to the frontend
Write the limits of the backend to xenstore. Connect to the frontend. Upon connection, allocate the rings according to the protocol specification. Initialize a QEMUBH to schedule work upon receiving an event channel notification from the frontend. Signed-off-by: Stefano StabelliniCC: anthony.per...@citrix.com CC: jgr...@suse.com CC: Aneesh Kumar K.V CC: Greg Kurz --- hw/9pfs/xen-9p-backend.c | 182 ++- 1 file changed, 181 insertions(+), 1 deletion(-) diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c index 92bb805..3fd20ff 100644 --- a/hw/9pfs/xen-9p-backend.c +++ b/hw/9pfs/xen-9p-backend.c @@ -23,8 +23,39 @@ #define XEN_9PFS_RING_SIZE XEN_FLEX_RING_SIZE(XEN_9PFS_RING_ORDER) DEFINE_XEN_FLEX_RING_AND_INTF(xen_9pfs); +#define VERSIONS "1" +#define MAX_RINGS 8 +#define MAX_RING_ORDER 8 + +typedef struct Xen9pfsRing { +struct Xen9pfsDev *priv; + +int ref; +xenevtchn_handle *evtchndev; +int evtchn; +int local_port; +struct xen_9pfs_data_intf *intf; +unsigned char *data; +struct xen_9pfs_data ring; + +QEMUBH *bh; + +/* local copies, so that we can read/write PDU data directly from + * the ring */ +RING_IDX out_cons, out_size, in_cons; +bool inprogress; +} Xen9pfsRing; + typedef struct Xen9pfsDev { struct XenDevice xendev; /* must be first */ +V9fsState state; +char *path; +char *security_model; +char *tag; +char *id; + +int num_rings; +Xen9pfsRing *rings; } Xen9pfsDev; static ssize_t xen_9pfs_pdu_vmarshal(V9fsPDU *pdu, @@ -73,22 +104,171 @@ static int xen_9pfs_init(struct XenDevice *xendev) return 0; } +static void xen_9pfs_bh(void *opaque) +{ +} + +static void xen_9pfs_evtchn_event(void *opaque) +{ +} + static int xen_9pfs_free(struct XenDevice *xendev) { -return -1; +int i; +Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev); + +if (xen_9pdev->id != NULL) { +g_free(xen_9pdev->id); +} +if (xen_9pdev->tag != NULL) { +g_free(xen_9pdev->tag); +} +if (xen_9pdev->path != NULL) { +g_free(xen_9pdev->path); +} +if (xen_9pdev->security_model != NULL) { +g_free(xen_9pdev->security_model); +} + +for (i = 0; i < xen_9pdev->num_rings; i++) { +if (xen_9pdev->rings[i].data != NULL) { +xengnttab_unmap(xen_9pdev->xendev.gnttabdev, +xen_9pdev->rings[i].data, +(1 << XEN_9PFS_RING_ORDER)); +} +if (xen_9pdev->rings[i].intf != NULL) { +xengnttab_unmap(xen_9pdev->xendev.gnttabdev, +xen_9pdev->rings[i].intf, +1); +} +if (xen_9pdev->rings[i].evtchndev > 0) { +qemu_set_fd_handler(xenevtchn_fd(xen_9pdev->rings[i].evtchndev), +NULL, NULL, NULL); +xenevtchn_unbind(xen_9pdev->rings[i].evtchndev, + xen_9pdev->rings[i].local_port); +} +if (xen_9pdev->rings[i].bh != NULL) { +qemu_bh_delete(xen_9pdev->rings[i].bh); +} +} +g_free(xen_9pdev->rings); +return 0; } static int xen_9pfs_connect(struct XenDevice *xendev) { +int i; +Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev); +V9fsState *s = _9pdev->state; +QemuOpts *fsdev; + +if (xenstore_read_fe_int(_9pdev->xendev, "num-rings", + _9pdev->num_rings) == -1 || +xen_9pdev->num_rings > MAX_RINGS || xen_9pdev->num_rings < 1) { +return -1; +} + +xen_9pdev->rings = g_malloc0(xen_9pdev->num_rings * sizeof(Xen9pfsRing)); +for (i = 0; i < xen_9pdev->num_rings; i++) { +char *str; + +xen_9pdev->rings[i].priv = xen_9pdev; +xen_9pdev->rings[i].evtchn = -1; +xen_9pdev->rings[i].local_port = -1; + +str = g_strdup_printf("ring-ref%u", i); +if (xenstore_read_fe_int(_9pdev->xendev, str, + _9pdev->rings[i].ref) == -1) { +goto out; +} +g_free(str); +str = g_strdup_printf("event-channel-%u", i); +if (xenstore_read_fe_int(_9pdev->xendev, str, + _9pdev->rings[i].evtchn) == -1) { +goto out; +} +g_free(str); + +xen_9pdev->rings[i].intf = xengnttab_map_grant_ref( +xen_9pdev->xendev.gnttabdev, +xen_9pdev->xendev.dom, +xen_9pdev->rings[i].ref, +PROT_READ | PROT_WRITE); +if (!xen_9pdev->rings[i].intf) { +goto out; +} +xen_9pdev->rings[i].data = xengnttab_map_domain_grant_refs( +xen_9pdev->xendev.gnttabdev, +(1 << XEN_9PFS_RING_ORDER), +xen_9pdev->xendev.dom, +xen_9pdev->rings[i].intf->ref,