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