bus/vmbus: map ring in secondary process
Need to remember primary channel in secondary process. Then use it to iterate over subchannels in secondary process mapping setup. Fixes: 831dba47bd36 ("bus/vmbus: add Hyper-V virtual bus support") Cc: stable@dpdk.org Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
This commit is contained in:
parent
41a7f8cbee
commit
2a28a502c6
@ -247,6 +247,49 @@ static int vmbus_uio_map_subchan(const struct rte_vmbus_device *dev,
|
|||||||
return 0;
|
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);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int vmbus_uio_map_rings(struct vmbus_channel *chan)
|
int vmbus_uio_map_rings(struct vmbus_channel *chan)
|
||||||
{
|
{
|
||||||
const struct rte_vmbus_device *dev = chan->device;
|
const struct rte_vmbus_device *dev = chan->device;
|
||||||
|
@ -45,6 +45,7 @@ struct mapped_vmbus_resource {
|
|||||||
|
|
||||||
rte_uuid_t id;
|
rte_uuid_t id;
|
||||||
int nb_maps;
|
int nb_maps;
|
||||||
|
struct vmbus_channel *primary;
|
||||||
struct vmbus_map maps[VMBUS_MAX_RESOURCE];
|
struct vmbus_map maps[VMBUS_MAX_RESOURCE];
|
||||||
char path[PATH_MAX];
|
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,
|
int vmbus_uio_get_subchan(struct vmbus_channel *primary,
|
||||||
struct vmbus_channel **subchan);
|
struct vmbus_channel **subchan);
|
||||||
int vmbus_uio_map_rings(struct vmbus_channel *chan);
|
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);
|
void vmbus_br_setup(struct vmbus_br *br, void *buf, unsigned int blen);
|
||||||
|
|
||||||
|
@ -352,12 +352,21 @@ int vmbus_chan_create(const struct rte_vmbus_device *device,
|
|||||||
int rte_vmbus_chan_open(struct rte_vmbus_device *device,
|
int rte_vmbus_chan_open(struct rte_vmbus_device *device,
|
||||||
struct vmbus_channel **new_chan)
|
struct vmbus_channel **new_chan)
|
||||||
{
|
{
|
||||||
|
struct mapped_vmbus_resource *uio_res;
|
||||||
int err;
|
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,
|
err = vmbus_chan_create(device, device->relid, 0,
|
||||||
device->monitor_id, new_chan);
|
device->monitor_id, new_chan);
|
||||||
if (!err)
|
if (!err) {
|
||||||
device->primary = *new_chan;
|
device->primary = *new_chan;
|
||||||
|
uio_res->primary = *new_chan;
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -396,11 +405,16 @@ void rte_vmbus_chan_close(struct vmbus_channel *chan)
|
|||||||
const struct rte_vmbus_device *device = chan->device;
|
const struct rte_vmbus_device *device = chan->device;
|
||||||
struct vmbus_channel *primary = device->primary;
|
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,
|
STAILQ_REMOVE(&primary->subchannel_list, chan,
|
||||||
vmbus_channel, next);
|
vmbus_channel, next);
|
||||||
|
rte_free(chan);
|
||||||
|
}
|
||||||
|
|
||||||
rte_free(chan);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vmbus_dump_ring(FILE *f, const char *id, const struct vmbus_br *br)
|
static void vmbus_dump_ring(FILE *f, const char *id, const struct vmbus_br *br)
|
||||||
|
@ -27,6 +27,7 @@ static int
|
|||||||
vmbus_uio_map_secondary(struct rte_vmbus_device *dev)
|
vmbus_uio_map_secondary(struct rte_vmbus_device *dev)
|
||||||
{
|
{
|
||||||
int fd, i;
|
int fd, i;
|
||||||
|
struct vmbus_channel *chan;
|
||||||
struct mapped_vmbus_resource *uio_res;
|
struct mapped_vmbus_resource *uio_res;
|
||||||
struct mapped_vmbus_res_list *uio_res_list
|
struct mapped_vmbus_res_list *uio_res_list
|
||||||
= RTE_TAILQ_CAST(vmbus_tailq.head, mapped_vmbus_res_list);
|
= RTE_TAILQ_CAST(vmbus_tailq.head, mapped_vmbus_res_list);
|
||||||
@ -76,6 +77,20 @@ vmbus_uio_map_secondary(struct rte_vmbus_device *dev)
|
|||||||
|
|
||||||
/* fd is not needed in slave process, close it */
|
/* fd is not needed in slave process, close it */
|
||||||
close(fd);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user