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

Reply via email to