From 8d53e9f3c6001dcb2865f6e894da5b54e1418f88 Mon Sep 17 00:00:00 2001 From: Christian Ehrhardt Date: Thu, 4 Jul 2019 10:40:06 +0200 Subject: New upstream version 18.11.2 Change-Id: I23eb4f9179abf1f9c659891f8fddb27ee68ad26b Signed-off-by: Christian Ehrhardt --- drivers/bus/vmbus/linux/vmbus_uio.c | 56 +++++++++++++++++++++++++++++++++--- drivers/bus/vmbus/private.h | 3 ++ drivers/bus/vmbus/vmbus_channel.c | 20 +++++++++++-- drivers/bus/vmbus/vmbus_common_uio.c | 22 ++++++++++++-- 4 files changed, 91 insertions(+), 10 deletions(-) (limited to 'drivers/bus/vmbus') diff --git a/drivers/bus/vmbus/linux/vmbus_uio.c b/drivers/bus/vmbus/linux/vmbus_uio.c index 38df4d72..7cab5c19 100644 --- a/drivers/bus/vmbus/linux/vmbus_uio.c +++ b/drivers/bus/vmbus/linux/vmbus_uio.c @@ -202,6 +202,7 @@ static int vmbus_uio_map_subchan(const struct rte_vmbus_device *dev, char ring_path[PATH_MAX]; size_t file_size; struct stat sb; + void *mapaddr; int fd; snprintf(ring_path, sizeof(ring_path), @@ -232,18 +233,65 @@ static int vmbus_uio_map_subchan(const struct rte_vmbus_device *dev, return -EINVAL; } - *ring_size = file_size / 2; - *ring_buf = vmbus_map_resource(vmbus_map_addr, fd, - 0, sb.st_size, 0); + mapaddr = vmbus_map_resource(vmbus_map_addr, fd, + 0, file_size, 0); close(fd); - if (ring_buf == MAP_FAILED) + if (mapaddr == MAP_FAILED) return -EIO; + *ring_size = file_size / 2; + *ring_buf = mapaddr; + vmbus_map_addr = RTE_PTR_ADD(ring_buf, file_size); return 0; } +int +vmbus_uio_map_secondary_subchan(const struct rte_vmbus_device *dev, + const struct vmbus_channel *chan) +{ + const struct vmbus_br *br = &chan->txbr; + char ring_path[PATH_MAX]; + void *mapaddr, *ring_buf; + uint32_t ring_size; + int fd; + + snprintf(ring_path, sizeof(ring_path), + "%s/%s/channels/%u/ring", + SYSFS_VMBUS_DEVICES, dev->device.name, + chan->relid); + + ring_buf = br->vbr; + ring_size = br->dsize + sizeof(struct vmbus_bufring); + VMBUS_LOG(INFO, "secondary ring_buf %p size %u", + ring_buf, ring_size); + + fd = open(ring_path, O_RDWR); + if (fd < 0) { + VMBUS_LOG(ERR, "Cannot open %s: %s", + ring_path, strerror(errno)); + return -errno; + } + + mapaddr = vmbus_map_resource(ring_buf, fd, 0, 2 * ring_size, 0); + close(fd); + + if (mapaddr == ring_buf) + return 0; + + if (mapaddr == MAP_FAILED) + VMBUS_LOG(ERR, + "mmap subchan %u in secondary failed", chan->relid); + else { + VMBUS_LOG(ERR, + "mmap subchan %u in secondary address mismatch", + chan->relid); + vmbus_unmap_resource(mapaddr, 2 * ring_size); + } + return -1; +} + int vmbus_uio_map_rings(struct vmbus_channel *chan) { const struct rte_vmbus_device *dev = chan->device; diff --git a/drivers/bus/vmbus/private.h b/drivers/bus/vmbus/private.h index 211127dd..f19b14e4 100644 --- a/drivers/bus/vmbus/private.h +++ b/drivers/bus/vmbus/private.h @@ -45,6 +45,7 @@ struct mapped_vmbus_resource { rte_uuid_t id; int nb_maps; + struct vmbus_channel *primary; struct vmbus_map maps[VMBUS_MAX_RESOURCE]; char path[PATH_MAX]; }; @@ -107,6 +108,8 @@ bool vmbus_uio_subchannels_supported(const struct rte_vmbus_device *dev, int vmbus_uio_get_subchan(struct vmbus_channel *primary, struct vmbus_channel **subchan); int vmbus_uio_map_rings(struct vmbus_channel *chan); +int vmbus_uio_map_secondary_subchan(const struct rte_vmbus_device *dev, + const struct vmbus_channel *chan); void vmbus_br_setup(struct vmbus_br *br, void *buf, unsigned int blen); diff --git a/drivers/bus/vmbus/vmbus_channel.c b/drivers/bus/vmbus/vmbus_channel.c index bd14c066..46b3ba3f 100644 --- a/drivers/bus/vmbus/vmbus_channel.c +++ b/drivers/bus/vmbus/vmbus_channel.c @@ -352,12 +352,21 @@ int vmbus_chan_create(const struct rte_vmbus_device *device, int rte_vmbus_chan_open(struct rte_vmbus_device *device, struct vmbus_channel **new_chan) { + struct mapped_vmbus_resource *uio_res; int err; + uio_res = vmbus_uio_find_resource(device); + if (!uio_res) { + VMBUS_LOG(ERR, "can't find uio resource"); + return -EINVAL; + } + err = vmbus_chan_create(device, device->relid, 0, device->monitor_id, new_chan); - if (!err) + if (!err) { device->primary = *new_chan; + uio_res->primary = *new_chan; + } return err; } @@ -396,11 +405,16 @@ void rte_vmbus_chan_close(struct vmbus_channel *chan) const struct rte_vmbus_device *device = chan->device; struct vmbus_channel *primary = device->primary; - if (chan != primary) + /* + * intentionally leak primary channel because + * secondary may still reference it + */ + if (chan != primary) { STAILQ_REMOVE(&primary->subchannel_list, chan, vmbus_channel, next); + rte_free(chan); + } - rte_free(chan); } static void vmbus_dump_ring(FILE *f, const char *id, const struct vmbus_br *br) diff --git a/drivers/bus/vmbus/vmbus_common_uio.c b/drivers/bus/vmbus/vmbus_common_uio.c index 5ddd36ab..9947f82a 100644 --- a/drivers/bus/vmbus/vmbus_common_uio.c +++ b/drivers/bus/vmbus/vmbus_common_uio.c @@ -27,6 +27,7 @@ static int vmbus_uio_map_secondary(struct rte_vmbus_device *dev) { int fd, i; + struct vmbus_channel *chan; struct mapped_vmbus_resource *uio_res; struct mapped_vmbus_res_list *uio_res_list = RTE_TAILQ_CAST(vmbus_tailq.head, mapped_vmbus_res_list); @@ -47,9 +48,10 @@ vmbus_uio_map_secondary(struct rte_vmbus_device *dev) for (i = 0; i != uio_res->nb_maps; i++) { void *mapaddr; + off_t offset = i * PAGE_SIZE; mapaddr = vmbus_map_resource(uio_res->maps[i].addr, - fd, 0, + fd, offset, uio_res->maps[i].size, 0); if (mapaddr == uio_res->maps[i].addr) @@ -75,6 +77,20 @@ vmbus_uio_map_secondary(struct rte_vmbus_device *dev) /* fd is not needed in slave process, close it */ close(fd); + + dev->primary = uio_res->primary; + if (!dev->primary) { + VMBUS_LOG(ERR, "missing primary channel"); + return -1; + } + + STAILQ_FOREACH(chan, &dev->primary->subchannel_list, next) { + if (vmbus_uio_map_secondary_subchan(dev, chan) != 0) { + VMBUS_LOG(ERR, "cannot map secondary subchan"); + return -1; + } + } + return 0; } @@ -97,9 +113,9 @@ vmbus_uio_map_primary(struct rte_vmbus_device *dev) /* Map the resources */ for (i = 0; i < VMBUS_MAX_RESOURCE; i++) { - /* skip empty BAR */ + /* stop at empty BAR */ if (dev->resource[i].len == 0) - continue; + break; ret = vmbus_uio_map_resource_by_index(dev, i, uio_res, 0); if (ret) -- cgit 1.2.3-korg