On Fri, Nov 07, 2014 at 04:01:24PM +0800, lxu wrote: > A multiple process DPDK application must mmap hugepages and pci resource into > same virtual addresses. By default the virtual addresses chosen by the > primary process automatically when calling the mmap. But sometime the virtual > addresses chosen by the primary process isn't usable at secondary process. > Such as the secondary process linked with more libraries than primary > process. The library has been mapped into this virtual address. The command > line parameter 'base-virtaddr' has been added for this situation. If it's > configured, the hugepages will be mapped into this base address. But the > virtual address of uio resource mapped still does not refer to the parameter. > In that case it would still fail. > > This patch try to map uio resources after hugepages when the base_virtaddr is > configured. So the error of "EAL: pci_map_resource(): cannot mmap" can be > resolved by set base-virtaddr into free virtual address space. > > Signed-off-by: lxu <liang.xu at cinfotech.cn> > --- > lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 29 ++++++++++++++++++++++++++++- > 1 file changed, 28 insertions(+), 1 deletion(-) > > diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c > b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c > index 7e62266..a2c9ab6 100644 > --- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c > +++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c > @@ -273,6 +273,24 @@ pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf, > return uio_num; > } > > +static inline const struct rte_memseg * > +get_physmem_last(void) > +{ > + const struct rte_memseg * seg = rte_eal_get_physmem_layout(); > + const struct rte_memseg * last = seg; > + unsigned i = 0; > + > + for (i=0; i<RTE_MAX_MEMSEG; i++, seg++) { > + if (seg->addr == NULL) > + break; > + > + if(seg->addr > last->addr) > + last = seg; > + > + } > + return last; > +} > + > /* map the PCI resource of a PCI device in virtual memory */ > int > pci_uio_map_resource(struct rte_pci_device *dev) > @@ -290,6 +308,13 @@ pci_uio_map_resource(struct rte_pci_device *dev) > struct mapped_pci_resource *uio_res; > struct pci_map *maps; > > + /* map uio resource into user required virtual address */ > + static void * requested_addr; > + if (internal_config.base_virtaddr && NULL == requested_addr) { > + const struct rte_memseg * last = get_physmem_last(); > + requested_addr = RTE_PTR_ADD(last->addr, last->len); > + } > +
Could you perhaps take anatoly's suggestion and modify this patch so the checking for a space right after the memsegs does not just depend on base-virtaddr being set. Unless it causes other problems, there is no reason this code should not always be used. /Bruce