美文网首页
非root用户使用dpdk初始化失败

非root用户使用dpdk初始化失败

作者: 被误认为吃货的程序猿 | 来源:发表于2021-12-10 12:10 被阅读0次

    非root用户使用dpdk初始化失败

    错误内容

    非root用户使用dpdk初始化失败时(root用户没有问题),报错:Cannot obtain physical addresses: No such file or directory

    尝试解决方案

    查看了dpdk官方文档,非root用户需要修改某些文件的权限,但是该修改的权限也修改了,还是一样的问题。比如:

    chmod o+rw /dev/hugepages
    chmod o+rw /dev/uio*
    chmod o+rw /sys/class/uio/uio*/device/config
    chmod o+rw /sys/class/uio/uio*/device/resource*
    

    然后看了源代码,主要是在检测是否能访问物理地址时报的错误。可以分析到,主要是没有权限访问物理地址。

    最终解决方案(二选其一):

    1. IOVA模式改VA。默认为PA模式,所以在初始化是增加参数:--iova-mode va 就可以了。
    2. 为你的应用增加特权:setcap CAP_SYS_ADMIN+ep 你的应用

    参考的源代码:

    ...
    int
    rte_eal_using_phys_addrs(void)
    {
        if (phys_addrs_available == -1) {
            uint64_t tmp = 0;
    
            if (rte_eal_has_hugepages() != 0 &&
                rte_mem_virt2phy(&tmp) != RTE_BAD_PHYS_ADDR)
                phys_addrs_available = 1;
            else
                phys_addrs_available = 0;
        }
        return phys_addrs_available;
    }
    
    ...
    
    phys_addr_t
    rte_mem_virt2phy(const void *virtaddr)
    {
        int fd, retval;
        uint64_t page, physaddr;
        unsigned long virt_pfn;
        int page_size;
        off_t offset;
    
        if (phys_addrs_available == 0)
            return RTE_BAD_IOVA;
    
        /* standard page size */
        page_size = getpagesize();
    
        fd = open("/proc/self/pagemap", O_RDONLY);
        if (fd < 0) {
            RTE_LOG(INFO, EAL, "%s(): cannot open /proc/self/pagemap: %s\n",
                __func__, strerror(errno));
            return RTE_BAD_IOVA;
        }
    
        virt_pfn = (unsigned long)virtaddr / page_size;
        offset = sizeof(uint64_t) * virt_pfn;
        if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
            RTE_LOG(INFO, EAL, "%s(): seek error in /proc/self/pagemap: %s\n",
                    __func__, strerror(errno));
            close(fd);
            return RTE_BAD_IOVA;
        }
    
        retval = read(fd, &page, PFN_MASK_SIZE);
        close(fd);
        if (retval < 0) {
            RTE_LOG(INFO, EAL, "%s(): cannot read /proc/self/pagemap: %s\n",
                    __func__, strerror(errno));
            return RTE_BAD_IOVA;
        } else if (retval != PFN_MASK_SIZE) {
            RTE_LOG(INFO, EAL, "%s(): read %d bytes from /proc/self/pagemap "
                    "but expected %d:\n",
                    __func__, retval, PFN_MASK_SIZE);
            return RTE_BAD_IOVA;
        }
    
        /*
         * the pfn (page frame number) are bits 0-54 (see
         * pagemap.txt in linux Documentation)
         */
        if ((page & 0x7fffffffffffffULL) == 0)
            return RTE_BAD_IOVA;
    
        physaddr = ((page & 0x7fffffffffffffULL) * page_size)
            + ((unsigned long)virtaddr % page_size);
    
        return physaddr;
    }
    ...
    

    相关文章

      网友评论

          本文标题:非root用户使用dpdk初始化失败

          本文链接:https://www.haomeiwen.com/subject/oescfrtx.html