diff options
Diffstat (limited to 'tools/lib/bpf')
| -rw-r--r-- | tools/lib/bpf/ringbuf.c | 2 | ||||
| -rw-r--r-- | tools/lib/bpf/xsk.c | 57 | 
2 files changed, 38 insertions, 21 deletions
| diff --git a/tools/lib/bpf/ringbuf.c b/tools/lib/bpf/ringbuf.c index 8caaafe7e312..e7a8d847161f 100644 --- a/tools/lib/bpf/ringbuf.c +++ b/tools/lib/bpf/ringbuf.c @@ -227,7 +227,7 @@ static int ringbuf_process_ring(struct ring* r)  			if ((len & BPF_RINGBUF_DISCARD_BIT) == 0) {  				sample = (void *)len_ptr + BPF_RINGBUF_HDR_SZ;  				err = r->sample_cb(r->ctx, sample, len); -				if (err) { +				if (err < 0) {  					/* update consumer pos and bail out */  					smp_store_release(r->consumer_pos,  							  cons_pos); diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c index 526fc35c0b23..d24b5cc720ec 100644 --- a/tools/lib/bpf/xsk.c +++ b/tools/lib/bpf/xsk.c @@ -59,6 +59,8 @@ struct xsk_umem {  	int fd;  	int refcount;  	struct list_head ctx_list; +	bool rx_ring_setup_done; +	bool tx_ring_setup_done;  };  struct xsk_ctx { @@ -743,26 +745,30 @@ static struct xsk_ctx *xsk_get_ctx(struct xsk_umem *umem, int ifindex,  	return NULL;  } -static void xsk_put_ctx(struct xsk_ctx *ctx) +static void xsk_put_ctx(struct xsk_ctx *ctx, bool unmap)  {  	struct xsk_umem *umem = ctx->umem;  	struct xdp_mmap_offsets off;  	int err; -	if (--ctx->refcount == 0) { -		err = xsk_get_mmap_offsets(umem->fd, &off); -		if (!err) { -			munmap(ctx->fill->ring - off.fr.desc, -			       off.fr.desc + umem->config.fill_size * -			       sizeof(__u64)); -			munmap(ctx->comp->ring - off.cr.desc, -			       off.cr.desc + umem->config.comp_size * -			       sizeof(__u64)); -		} +	if (--ctx->refcount) +		return; -		list_del(&ctx->list); -		free(ctx); -	} +	if (!unmap) +		goto out_free; + +	err = xsk_get_mmap_offsets(umem->fd, &off); +	if (err) +		goto out_free; + +	munmap(ctx->fill->ring - off.fr.desc, off.fr.desc + umem->config.fill_size * +	       sizeof(__u64)); +	munmap(ctx->comp->ring - off.cr.desc, off.cr.desc + umem->config.comp_size * +	       sizeof(__u64)); + +out_free: +	list_del(&ctx->list); +	free(ctx);  }  static struct xsk_ctx *xsk_create_ctx(struct xsk_socket *xsk, @@ -797,8 +803,6 @@ static struct xsk_ctx *xsk_create_ctx(struct xsk_socket *xsk,  	memcpy(ctx->ifname, ifname, IFNAMSIZ - 1);  	ctx->ifname[IFNAMSIZ - 1] = '\0'; -	umem->fill_save = NULL; -	umem->comp_save = NULL;  	ctx->fill = fill;  	ctx->comp = comp;  	list_add(&ctx->list, &umem->ctx_list); @@ -854,6 +858,8 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,  	struct xsk_socket *xsk;  	struct xsk_ctx *ctx;  	int err, ifindex; +	bool unmap = umem->fill_save != fill; +	bool rx_setup_done = false, tx_setup_done = false;  	if (!umem || !xsk_ptr || !(rx || tx))  		return -EFAULT; @@ -881,6 +887,8 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,  		}  	} else {  		xsk->fd = umem->fd; +		rx_setup_done = umem->rx_ring_setup_done; +		tx_setup_done = umem->tx_ring_setup_done;  	}  	ctx = xsk_get_ctx(umem, ifindex, queue_id); @@ -899,7 +907,7 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,  	}  	xsk->ctx = ctx; -	if (rx) { +	if (rx && !rx_setup_done) {  		err = setsockopt(xsk->fd, SOL_XDP, XDP_RX_RING,  				 &xsk->config.rx_size,  				 sizeof(xsk->config.rx_size)); @@ -907,8 +915,10 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,  			err = -errno;  			goto out_put_ctx;  		} +		if (xsk->fd == umem->fd) +			umem->rx_ring_setup_done = true;  	} -	if (tx) { +	if (tx && !tx_setup_done) {  		err = setsockopt(xsk->fd, SOL_XDP, XDP_TX_RING,  				 &xsk->config.tx_size,  				 sizeof(xsk->config.tx_size)); @@ -916,6 +926,8 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,  			err = -errno;  			goto out_put_ctx;  		} +		if (xsk->fd == umem->fd) +			umem->rx_ring_setup_done = true;  	}  	err = xsk_get_mmap_offsets(xsk->fd, &off); @@ -994,6 +1006,8 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,  	}  	*xsk_ptr = xsk; +	umem->fill_save = NULL; +	umem->comp_save = NULL;  	return 0;  out_mmap_tx: @@ -1005,7 +1019,7 @@ out_mmap_rx:  		munmap(rx_map, off.rx.desc +  		       xsk->config.rx_size * sizeof(struct xdp_desc));  out_put_ctx: -	xsk_put_ctx(ctx); +	xsk_put_ctx(ctx, unmap);  out_socket:  	if (--umem->refcount)  		close(xsk->fd); @@ -1019,6 +1033,9 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname,  		       struct xsk_ring_cons *rx, struct xsk_ring_prod *tx,  		       const struct xsk_socket_config *usr_config)  { +	if (!umem) +		return -EFAULT; +  	return xsk_socket__create_shared(xsk_ptr, ifname, queue_id, umem,  					 rx, tx, umem->fill_save,  					 umem->comp_save, usr_config); @@ -1068,7 +1085,7 @@ void xsk_socket__delete(struct xsk_socket *xsk)  		}  	} -	xsk_put_ctx(ctx); +	xsk_put_ctx(ctx, true);  	umem->refcount--;  	/* Do not close an fd that also has an associated umem connected |