On 12/10/2018 04:34 PM, Magnus Karlsson wrote:
[...]
> +int xsk_create_umem(void *umem_area, __u64 size, struct xsk_prod_ring *fq,
> + struct xsk_cons_ring *cq,
> + struct xsk_umem_config *usr_config)
> +{
> + struct xdp_mmap_offsets off;
> + struct xsk_umem_info *umem;
> + struct xdp_umem_reg mr;
> + socklen_t optlen;
> + int err, fd;
> + void *map;
> +
> + if (!umem_area)
> + return -EFAULT;
> + if (!size && !xsk_page_aligned(umem_area))
> + return -EINVAL;
> +
> + fd = socket(AF_XDP, SOCK_RAW, 0);
> + if (fd < 0)
> + return -errno;
> +
> + umem = calloc(1, sizeof(*umem));
> + if (!umem)
> + return -ENOMEM;
On error, we should also close fd and not 'leak' it into the app, similar
for other errors below. Same in xsk_create_xdp_socket(), etc.
> + xsk_hash_insert_umem(fd, umem);
> + xsk_set_umem_config(&umem->config, usr_config);
> +
> + mr.addr = (uintptr_t)umem_area;
> + mr.len = size;
> + mr.chunk_size = umem->config.frame_size;
> + mr.headroom = umem->config.frame_headroom;
> +
> + err = setsockopt(fd, SOL_XDP, XDP_UMEM_REG, &mr, sizeof(mr));
> + if (err)
> + return -errno;
> + err = setsockopt(fd, SOL_XDP, XDP_UMEM_FILL_RING,
> + &umem->config.fq_size, sizeof(umem->config.fq_size));
> + if (err)
> + return -errno;
> + err = setsockopt(fd, SOL_XDP, XDP_UMEM_COMPLETION_RING,
> + &umem->config.cq_size, sizeof(umem->config.cq_size));
> + if (err)
> + return -errno;
> +
> + optlen = sizeof(off);
> + err = getsockopt(fd, SOL_XDP, XDP_MMAP_OFFSETS, &off, &optlen);
> + if (err)
> + return -errno;
> +
> + map = xsk_mmap(NULL, off.fr.desc + umem->config.fq_size * sizeof(__u64),
> + PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE,
> + fd, XDP_UMEM_PGOFF_FILL_RING);
> + if (map == MAP_FAILED)
> + return -errno;
> +
> + umem->fq = fq;
> + fq->mask = umem->config.fq_size - 1;
> + fq->size = umem->config.fq_size;
> + fq->producer = map + off.fr.producer;
> + fq->consumer = map + off.fr.consumer;
> + fq->ring = map + off.fr.desc;
> + fq->cached_cons = umem->config.fq_size;
> +
> + map = xsk_mmap(NULL, off.cr.desc + umem->config.cq_size * sizeof(__u64),
> + PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE,
> + fd, XDP_UMEM_PGOFF_COMPLETION_RING);
> + if (map == MAP_FAILED)
> + return -errno;
Plus undoing prior mmaps.
> + umem->cq = cq;
> + cq->mask = umem->config.cq_size - 1;
> + cq->size = umem->config.cq_size;
> + cq->producer = map + off.cr.producer;
> + cq->consumer = map + off.cr.consumer;
> + cq->ring = map + off.cr.desc;
> +
> + umem->umem_area = umem_area;
> + umem->fd = fd;
> +
> + return fd;
> +}
Thanks,
Daniel