From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9D606A00C4; Tue, 26 Apr 2022 10:33:11 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id BA53B4280B; Tue, 26 Apr 2022 10:32:41 +0200 (CEST) Received: from mail-pl1-f195.google.com (mail-pl1-f195.google.com [209.85.214.195]) by mails.dpdk.org (Postfix) with ESMTP id 3033440E09 for ; Sat, 23 Apr 2022 06:29:56 +0200 (CEST) Received: by mail-pl1-f195.google.com with SMTP id b12so245321plg.4 for ; Fri, 22 Apr 2022 21:29:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oneconvergence.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vg4ke78CvnDAmcrkcGJTrqji0pMUMbiqwLF5mHDt9hg=; b=gfUwtINXOfPUPugveb0JrWXhoO1ewXtGqCtn6xJo30X4iTVuvRQfSPQIOzxud2FkAc dAnsXRmBls2ZSDX6EU6uYHMaiRJqnh8oq1MihU+yGFTElNUk7oJ010vi/Iu56AYC65Df 9qdekBtktD5eN1X3w8EmJWQdneVjUNpvFUAHU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vg4ke78CvnDAmcrkcGJTrqji0pMUMbiqwLF5mHDt9hg=; b=cIdZVUmnEDB+aQAijGUTmmip2V+UiIaoNWznp7mH9d02HqIxuS9ZSp8IOnSbbmyJ9v w4T2MGqdH8gmC5QSEDmAsMLHRkiXYdtbcOxF3fJJmVcsheeiWXBO5Vu/TbYlHRet1Hnr Ky9CQYHEWKAo8SlZpWIvgRdbF5G0j8xzioOhzFeODV3gs7SE11N59gXk0KbfOVmOTrba sWQrAzCbY+Z7SXhI2f70zfrBf77bYlf3tWEZT25ERU/ZbsZYHMgXC3R1xCkMAc5KBJ/S QqHnsE0jS4OHoaqAY0Jio6FyVZHyyq9+81Hoca823Ig6diXBtEMSOqNewas0O6eoI6Lk VRYw== X-Gm-Message-State: AOAM533PyzcOXLD2DQnQFCd6DrTx8TNKCI4Ac9QAykyTr7nNS4gcoJ+P dbuFxF0jOLfSMX09Fy2kYYgm4Tt4qQFroXcS X-Google-Smtp-Source: ABdhPJxercxMB7p5NbBFKdsrfFr+bEz2jWeChfUy+VrGPedi2OMuwOL0XhhOo2fD8k6V+WCrJpMuwQ== X-Received: by 2002:a17:902:eb84:b0:158:8a72:bbdd with SMTP id q4-20020a170902eb8400b001588a72bbddmr7751192plg.117.1650688195288; Fri, 22 Apr 2022 21:29:55 -0700 (PDT) Received: from home-desktop.localdomain ([49.37.158.191]) by smtp.gmail.com with ESMTPSA id g6-20020a17090a714600b001d7f3bb11d7sm4056438pjs.53.2022.04.22.21.29.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 Apr 2022 21:29:54 -0700 (PDT) From: Srikanth Kaka To: Stephen Hemminger , Long Li Cc: dev@dpdk.org, Vag Singh , Anand Thulasiram , Srikanth Kaka Subject: [PATCH v5 03/14] bus/vmbus: move OS independent UIO functions Date: Sat, 23 Apr 2022 09:58:38 +0530 Message-Id: <20220423042849.7718-4-srikanth.k@oneconvergence.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220423042849.7718-1-srikanth.k@oneconvergence.com> References: <20220418042915.5765-1-srikanth.k@oneconvergence.com> <20220423042849.7718-1-srikanth.k@oneconvergence.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailman-Approved-At: Tue, 26 Apr 2022 10:32:34 +0200 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Moved all Linux independent UIO functions to unix dir. Split the vmbus_uio_map_subchan() by keeping OS dependent code in vmbus_uio_map_subchan_os() function Signed-off-by: Srikanth Kaka Signed-off-by: Vag Singh Signed-off-by: Anand Thulasiram --- drivers/bus/vmbus/linux/vmbus_uio.c | 292 ++---------------------------- drivers/bus/vmbus/meson.build | 3 +- drivers/bus/vmbus/unix/vmbus_unix.h | 12 ++ drivers/bus/vmbus/unix/vmbus_unix_uio.c | 306 ++++++++++++++++++++++++++++++++ 4 files changed, 330 insertions(+), 283 deletions(-) create mode 100644 drivers/bus/vmbus/unix/vmbus_unix_uio.c diff --git a/drivers/bus/vmbus/linux/vmbus_uio.c b/drivers/bus/vmbus/linux/vmbus_uio.c index 5db70f8..b5d15c9 100644 --- a/drivers/bus/vmbus/linux/vmbus_uio.c +++ b/drivers/bus/vmbus/linux/vmbus_uio.c @@ -21,233 +21,18 @@ #include #include "private.h" +#include "vmbus_unix.h" /** Pathname of VMBUS devices directory. */ #define SYSFS_VMBUS_DEVICES "/sys/bus/vmbus/devices" -static void *vmbus_map_addr; - -/* Control interrupts */ -void vmbus_uio_irq_control(struct rte_vmbus_device *dev, int32_t onoff) -{ - if ((rte_intr_fd_get(dev->intr_handle) < 0) || - write(rte_intr_fd_get(dev->intr_handle), &onoff, - sizeof(onoff)) < 0) { - VMBUS_LOG(ERR, "cannot write to %d:%s", - rte_intr_fd_get(dev->intr_handle), - strerror(errno)); - } -} - -int vmbus_uio_irq_read(struct rte_vmbus_device *dev) -{ - int32_t count; - int cc; - - if (rte_intr_fd_get(dev->intr_handle) < 0) - return -1; - - cc = read(rte_intr_fd_get(dev->intr_handle), &count, - sizeof(count)); - if (cc < (int)sizeof(count)) { - if (cc < 0) { - VMBUS_LOG(ERR, "IRQ read failed %s", - strerror(errno)); - return -errno; - } - VMBUS_LOG(ERR, "can't read IRQ count"); - return -EINVAL; - } - - return count; -} - -void -vmbus_uio_free_resource(struct rte_vmbus_device *dev, - struct mapped_vmbus_resource *uio_res) -{ - rte_free(uio_res); - - if (rte_intr_dev_fd_get(dev->intr_handle) >= 0) { - close(rte_intr_dev_fd_get(dev->intr_handle)); - rte_intr_dev_fd_set(dev->intr_handle, -1); - } - - if (rte_intr_fd_get(dev->intr_handle) >= 0) { - close(rte_intr_fd_get(dev->intr_handle)); - rte_intr_fd_set(dev->intr_handle, -1); - rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN); - } -} - -int -vmbus_uio_alloc_resource(struct rte_vmbus_device *dev, - struct mapped_vmbus_resource **uio_res) -{ - char devname[PATH_MAX]; /* contains the /dev/uioX */ - int fd; - - /* save fd if in primary process */ - snprintf(devname, sizeof(devname), "/dev/uio%u", dev->uio_num); - fd = open(devname, O_RDWR); - if (fd < 0) { - VMBUS_LOG(ERR, "Cannot open %s: %s", - devname, strerror(errno)); - goto error; - } - - if (rte_intr_fd_set(dev->intr_handle, fd)) - goto error; - - if (rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UIO_INTX)) - goto error; - - /* allocate the mapping details for secondary processes*/ - *uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0); - if (*uio_res == NULL) { - VMBUS_LOG(ERR, "cannot store uio mmap details"); - goto error; - } - - strlcpy((*uio_res)->path, devname, PATH_MAX); - rte_uuid_copy((*uio_res)->id, dev->device_id); - - return 0; - -error: - vmbus_uio_free_resource(dev, *uio_res); - return -1; -} - -static int -find_max_end_va(const struct rte_memseg_list *msl, void *arg) -{ - size_t sz = msl->memseg_arr.len * msl->page_sz; - void *end_va = RTE_PTR_ADD(msl->base_va, sz); - void **max_va = arg; - - if (*max_va < end_va) - *max_va = end_va; - return 0; -} - -/* - * TODO: this should be part of memseg api. - * code is duplicated from PCI. - */ -static void * -vmbus_find_max_end_va(void) -{ - void *va = NULL; - - rte_memseg_list_walk(find_max_end_va, &va); - return va; -} - -int -vmbus_uio_map_resource_by_index(struct rte_vmbus_device *dev, int idx, - struct mapped_vmbus_resource *uio_res, - int flags) -{ - size_t size = dev->resource[idx].len; - struct vmbus_map *maps = uio_res->maps; - void *mapaddr; - off_t offset; - int fd; - - /* devname for mmap */ - fd = open(uio_res->path, O_RDWR); - if (fd < 0) { - VMBUS_LOG(ERR, "Cannot open %s: %s", - uio_res->path, strerror(errno)); - return -1; - } - - /* try mapping somewhere close to the end of hugepages */ - if (vmbus_map_addr == NULL) - vmbus_map_addr = vmbus_find_max_end_va(); - - /* offset is special in uio it indicates which resource */ - offset = idx * rte_mem_page_size(); - - mapaddr = vmbus_map_resource(vmbus_map_addr, fd, offset, size, flags); - close(fd); - - if (mapaddr == MAP_FAILED) - return -1; - - dev->resource[idx].addr = mapaddr; - vmbus_map_addr = RTE_PTR_ADD(mapaddr, size); - - /* Record result of successful mapping for use by secondary */ - maps[idx].addr = mapaddr; - maps[idx].size = size; - - return 0; -} - -static int vmbus_uio_map_primary(struct vmbus_channel *chan, - void **ring_buf, uint32_t *ring_size) -{ - struct mapped_vmbus_resource *uio_res; - - uio_res = vmbus_uio_find_resource(chan->device); - if (!uio_res) { - VMBUS_LOG(ERR, "can not find resources!"); - return -ENOMEM; - } - - if (uio_res->nb_maps < VMBUS_MAX_RESOURCE) { - VMBUS_LOG(ERR, "VMBUS: only %u resources found!", - uio_res->nb_maps); - return -EINVAL; - } - - *ring_size = uio_res->maps[HV_TXRX_RING_MAP].size / 2; - *ring_buf = uio_res->maps[HV_TXRX_RING_MAP].addr; - return 0; -} - -static int vmbus_uio_map_subchan(const struct rte_vmbus_device *dev, - const struct vmbus_channel *chan, - void **ring_buf, uint32_t *ring_size) +int vmbus_uio_map_subchan_os(const struct rte_vmbus_device *dev, + const struct vmbus_channel *chan, + void **mapaddr, size_t *file_size) { char ring_path[PATH_MAX]; - size_t file_size; struct stat sb; - void *mapaddr; int fd; - struct mapped_vmbus_resource *uio_res; - int channel_idx; - - uio_res = vmbus_uio_find_resource(dev); - if (!uio_res) { - VMBUS_LOG(ERR, "can not find resources for mapping subchan"); - return -ENOMEM; - } - - if (rte_eal_process_type() == RTE_PROC_PRIMARY) { - if (uio_res->nb_subchannels >= UIO_MAX_SUBCHANNEL) { - VMBUS_LOG(ERR, - "exceeding max subchannels UIO_MAX_SUBCHANNEL(%d)", - UIO_MAX_SUBCHANNEL); - VMBUS_LOG(ERR, "Change UIO_MAX_SUBCHANNEL and recompile"); - return -ENOMEM; - } - } else { - for (channel_idx = 0; channel_idx < uio_res->nb_subchannels; - channel_idx++) - if (uio_res->subchannel_maps[channel_idx].relid == - chan->relid) - break; - if (channel_idx == uio_res->nb_subchannels) { - VMBUS_LOG(ERR, - "couldn't find sub channel %d from shared mapping in primary", - chan->relid); - return -ENOMEM; - } - vmbus_map_addr = uio_res->subchannel_maps[channel_idx].addr; - } snprintf(ring_path, sizeof(ring_path), "%s/%s/channels/%u/ring", @@ -267,68 +52,23 @@ static int vmbus_uio_map_subchan(const struct rte_vmbus_device *dev, close(fd); return -errno; } - file_size = sb.st_size; + *file_size = sb.st_size; - if (file_size == 0 || (file_size & (rte_mem_page_size() - 1))) { + if (*file_size == 0 || (*file_size & (rte_mem_page_size() - 1))) { VMBUS_LOG(ERR, "incorrect size %s: %zu", - ring_path, file_size); + ring_path, *file_size); close(fd); return -EINVAL; } - mapaddr = vmbus_map_resource(vmbus_map_addr, fd, - 0, file_size, 0); + *mapaddr = vmbus_map_resource(vmbus_map_addr, fd, + 0, *file_size, 0); close(fd); - if (mapaddr == MAP_FAILED) + if (*mapaddr == MAP_FAILED) return -EIO; - if (rte_eal_process_type() == RTE_PROC_PRIMARY) { - - /* Add this mapping to uio_res for use by secondary */ - uio_res->subchannel_maps[uio_res->nb_subchannels].relid = - chan->relid; - uio_res->subchannel_maps[uio_res->nb_subchannels].addr = - mapaddr; - uio_res->subchannel_maps[uio_res->nb_subchannels].size = - file_size; - uio_res->nb_subchannels++; - - vmbus_map_addr = RTE_PTR_ADD(mapaddr, file_size); - } else { - if (mapaddr != vmbus_map_addr) { - VMBUS_LOG(ERR, "failed to map channel %d to addr %p", - chan->relid, mapaddr); - vmbus_unmap_resource(mapaddr, file_size); - return -EIO; - } - } - - *ring_size = file_size / 2; - *ring_buf = mapaddr; - - return 0; -} - -int vmbus_uio_map_rings(struct vmbus_channel *chan) -{ - const struct rte_vmbus_device *dev = chan->device; - uint32_t ring_size; - void *ring_buf; - int ret; - - /* Primary channel */ - if (chan->subchannel_id == 0) - ret = vmbus_uio_map_primary(chan, &ring_buf, &ring_size); - else - ret = vmbus_uio_map_subchan(dev, chan, &ring_buf, &ring_size); - - if (ret) - return ret; - - vmbus_br_setup(&chan->txbr, ring_buf, ring_size); - vmbus_br_setup(&chan->rxbr, (char *)ring_buf + ring_size, ring_size); return 0; } @@ -377,18 +117,6 @@ bool vmbus_uio_subchannels_supported(const struct rte_vmbus_device *dev, return vmbus_uio_ring_present(dev, chan->relid); } -static bool vmbus_isnew_subchannel(struct vmbus_channel *primary, - unsigned long id) -{ - const struct vmbus_channel *c; - - STAILQ_FOREACH(c, &primary->subchannel_list, next) { - if (c->relid == id) - return false; - } - return true; -} - int vmbus_uio_get_subchan(struct vmbus_channel *primary, struct vmbus_channel **subchan) { diff --git a/drivers/bus/vmbus/meson.build b/drivers/bus/vmbus/meson.build index 01ef01f..60913d0 100644 --- a/drivers/bus/vmbus/meson.build +++ b/drivers/bus/vmbus/meson.build @@ -18,7 +18,8 @@ sources = files( includes += include_directories('unix') sources += files( - 'unix/vmbus_unix_bus.c' + 'unix/vmbus_unix_bus.c', + 'unix/vmbus_unix_uio.c' ) if is_linux diff --git a/drivers/bus/vmbus/unix/vmbus_unix.h b/drivers/bus/vmbus/unix/vmbus_unix.h index 2db9399..579c4bb 100644 --- a/drivers/bus/vmbus/unix/vmbus_unix.h +++ b/drivers/bus/vmbus/unix/vmbus_unix.h @@ -6,6 +6,18 @@ #ifndef _VMBUS_BUS_UNIX_H_ #define _VMBUS_BUS_UNIX_H_ +#include + +#include "private.h" + extern const rte_uuid_t vmbus_nic_uuid; +extern void *vmbus_map_addr; + +int vmbus_uio_map_subchan_os(const struct rte_vmbus_device *dev, + const struct vmbus_channel *chan, + void **mapaddr, size_t *file_size); + +bool vmbus_isnew_subchannel(struct vmbus_channel *primary, + unsigned long id); #endif /* _VMBUS_BUS_UNIX_H_ */ diff --git a/drivers/bus/vmbus/unix/vmbus_unix_uio.c b/drivers/bus/vmbus/unix/vmbus_unix_uio.c new file mode 100644 index 0000000..c5ce8ca --- /dev/null +++ b/drivers/bus/vmbus/unix/vmbus_unix_uio.c @@ -0,0 +1,306 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2018, Microsoft Corporation. + * All Rights Reserved. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "private.h" +#include "vmbus_unix.h" + +void *vmbus_map_addr; + +/* Control interrupts */ +void vmbus_uio_irq_control(struct rte_vmbus_device *dev, int32_t onoff) +{ + if ((rte_intr_fd_get(dev->intr_handle) < 0) || + write(rte_intr_fd_get(dev->intr_handle), &onoff, + sizeof(onoff)) < 0) { + VMBUS_LOG(ERR, "cannot write to %d:%s", + rte_intr_fd_get(dev->intr_handle), + strerror(errno)); + } +} + +int vmbus_uio_irq_read(struct rte_vmbus_device *dev) +{ + int32_t count; + int cc; + + if (rte_intr_fd_get(dev->intr_handle) < 0) + return -1; + + cc = read(rte_intr_fd_get(dev->intr_handle), &count, + sizeof(count)); + if (cc < (int)sizeof(count)) { + if (cc < 0) { + VMBUS_LOG(ERR, "IRQ read failed %s", + strerror(errno)); + return -errno; + } + VMBUS_LOG(ERR, "can't read IRQ count"); + return -EINVAL; + } + + return count; +} + +void +vmbus_uio_free_resource(struct rte_vmbus_device *dev, + struct mapped_vmbus_resource *uio_res) +{ + rte_free(uio_res); + + if (rte_intr_dev_fd_get(dev->intr_handle) >= 0) { + close(rte_intr_dev_fd_get(dev->intr_handle)); + rte_intr_dev_fd_set(dev->intr_handle, -1); + } + + if (rte_intr_fd_get(dev->intr_handle) >= 0) { + close(rte_intr_fd_get(dev->intr_handle)); + rte_intr_fd_set(dev->intr_handle, -1); + rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN); + } +} + +int +vmbus_uio_alloc_resource(struct rte_vmbus_device *dev, + struct mapped_vmbus_resource **uio_res) +{ + char devname[PATH_MAX]; /* contains the /dev/uioX */ + int fd; + + /* save fd if in primary process */ + snprintf(devname, sizeof(devname), "/dev/uio%u", dev->uio_num); + fd = open(devname, O_RDWR); + if (fd < 0) { + VMBUS_LOG(ERR, "Cannot open %s: %s", + devname, strerror(errno)); + goto error; + } + + if (rte_intr_fd_set(dev->intr_handle, fd)) + goto error; + + if (rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UIO_INTX)) + goto error; + + /* allocate the mapping details for secondary processes*/ + *uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0); + if (*uio_res == NULL) { + VMBUS_LOG(ERR, "cannot store uio mmap details"); + goto error; + } + + strlcpy((*uio_res)->path, devname, PATH_MAX); + rte_uuid_copy((*uio_res)->id, dev->device_id); + + return 0; + +error: + vmbus_uio_free_resource(dev, *uio_res); + return -1; +} + +static int +find_max_end_va(const struct rte_memseg_list *msl, void *arg) +{ + size_t sz = msl->memseg_arr.len * msl->page_sz; + void *end_va = RTE_PTR_ADD(msl->base_va, sz); + void **max_va = arg; + + if (*max_va < end_va) + *max_va = end_va; + return 0; +} + +/* + * TODO: this should be part of memseg api. + * code is duplicated from PCI. + */ +static void * +vmbus_find_max_end_va(void) +{ + void *va = NULL; + + rte_memseg_list_walk(find_max_end_va, &va); + return va; +} + +int +vmbus_uio_map_resource_by_index(struct rte_vmbus_device *dev, int idx, + struct mapped_vmbus_resource *uio_res, + int flags) +{ + size_t size = dev->resource[idx].len; + struct vmbus_map *maps = uio_res->maps; + void *mapaddr; + off_t offset; + int fd; + + /* devname for mmap */ + fd = open(uio_res->path, O_RDWR); + if (fd < 0) { + VMBUS_LOG(ERR, "Cannot open %s: %s", + uio_res->path, strerror(errno)); + return -1; + } + + /* try mapping somewhere close to the end of hugepages */ + if (vmbus_map_addr == NULL) + vmbus_map_addr = vmbus_find_max_end_va(); + + /* offset is special in uio it indicates which resource */ + offset = idx * rte_mem_page_size(); + + mapaddr = vmbus_map_resource(vmbus_map_addr, fd, offset, size, flags); + close(fd); + + if (mapaddr == MAP_FAILED) + return -1; + + dev->resource[idx].addr = mapaddr; + vmbus_map_addr = RTE_PTR_ADD(mapaddr, size); + + /* Record result of successful mapping for use by secondary */ + maps[idx].addr = mapaddr; + maps[idx].size = size; + + return 0; +} + +static int vmbus_uio_map_primary(struct vmbus_channel *chan, + void **ring_buf, uint32_t *ring_size) +{ + struct mapped_vmbus_resource *uio_res; + + uio_res = vmbus_uio_find_resource(chan->device); + if (!uio_res) { + VMBUS_LOG(ERR, "can not find resources!"); + return -ENOMEM; + } + + if (uio_res->nb_maps < VMBUS_MAX_RESOURCE) { + VMBUS_LOG(ERR, "VMBUS: only %u resources found!", + uio_res->nb_maps); + return -EINVAL; + } + + *ring_size = uio_res->maps[HV_TXRX_RING_MAP].size / 2; + *ring_buf = uio_res->maps[HV_TXRX_RING_MAP].addr; + return 0; +} + +static int vmbus_uio_map_subchan(const struct rte_vmbus_device *dev, + const struct vmbus_channel *chan, + void **ring_buf, uint32_t *ring_size) +{ + size_t file_size = 0; + void *mapaddr = NULL; + struct mapped_vmbus_resource *uio_res; + int channel_idx; + int ret; + + uio_res = vmbus_uio_find_resource(dev); + if (!uio_res) { + VMBUS_LOG(ERR, "can not find resources for mapping subchan"); + return -ENOMEM; + } + + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + if (uio_res->nb_subchannels >= UIO_MAX_SUBCHANNEL) { + VMBUS_LOG(ERR, + "exceeding max subchannels UIO_MAX_SUBCHANNEL(%d)", + UIO_MAX_SUBCHANNEL); + VMBUS_LOG(ERR, "Change UIO_MAX_SUBCHANNEL and recompile"); + return -ENOMEM; + } + } else { + for (channel_idx = 0; channel_idx < uio_res->nb_subchannels; + channel_idx++) + if (uio_res->subchannel_maps[channel_idx].relid == + chan->relid) + break; + if (channel_idx == uio_res->nb_subchannels) { + VMBUS_LOG(ERR, + "couldn't find sub channel %d from shared mapping in primary", + chan->relid); + return -ENOMEM; + } + vmbus_map_addr = uio_res->subchannel_maps[channel_idx].addr; + } + + ret = vmbus_uio_map_subchan_os(dev, chan, &mapaddr, &file_size); + if (ret) + return ret; + + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + + /* Add this mapping to uio_res for use by secondary */ + uio_res->subchannel_maps[uio_res->nb_subchannels].relid = + chan->relid; + uio_res->subchannel_maps[uio_res->nb_subchannels].addr = + mapaddr; + uio_res->subchannel_maps[uio_res->nb_subchannels].size = + file_size; + uio_res->nb_subchannels++; + + vmbus_map_addr = RTE_PTR_ADD(mapaddr, file_size); + } else { + if (mapaddr != vmbus_map_addr) { + VMBUS_LOG(ERR, "failed to map channel %d to addr %p", + chan->relid, mapaddr); + vmbus_unmap_resource(mapaddr, file_size); + return -EIO; + } + } + + *ring_size = file_size / 2; + *ring_buf = mapaddr; + + return 0; +} + +int vmbus_uio_map_rings(struct vmbus_channel *chan) +{ + const struct rte_vmbus_device *dev = chan->device; + uint32_t ring_size = 0; + void *ring_buf = NULL; + int ret; + + /* Primary channel */ + if (chan->subchannel_id == 0) + ret = vmbus_uio_map_primary(chan, &ring_buf, &ring_size); + else + ret = vmbus_uio_map_subchan(dev, chan, &ring_buf, &ring_size); + + if (ret) + return ret; + + vmbus_br_setup(&chan->txbr, ring_buf, ring_size); + vmbus_br_setup(&chan->rxbr, (char *)ring_buf + ring_size, ring_size); + return 0; +} + +bool vmbus_isnew_subchannel(struct vmbus_channel *primary, + unsigned long id) +{ + const struct vmbus_channel *c; + + STAILQ_FOREACH(c, &primary->subchannel_list, next) { + if (c->relid == id) + return false; + } + return true; +} -- 1.8.3.1