Commit 85192dbf authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Daniel Borkmann
Browse files

bpf: Convert bpf_prog refcnt to atomic64_t



Similarly to bpf_map's refcnt/usercnt, convert bpf_prog's refcnt to atomic64
and remove artificial 32k limit. This allows to make bpf_prog's refcounting
non-failing, simplifying logic of users of bpf_prog_add/bpf_prog_inc.

Validated compilation by running allyesconfig kernel build.

Suggested-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Signed-off-by: default avatarAndrii Nakryiko <andriin@fb.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20191117172806.2195367-3-andriin@fb.com
parent 1e0bd5a0
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -3171,13 +3171,8 @@ static int bnxt_init_one_rx_ring(struct bnxt *bp, int ring_nr)
	bnxt_init_rxbd_pages(ring, type);

	if (BNXT_RX_PAGE_MODE(bp) && bp->xdp_prog) {
		rxr->xdp_prog = bpf_prog_add(bp->xdp_prog, 1);
		if (IS_ERR(rxr->xdp_prog)) {
			int rc = PTR_ERR(rxr->xdp_prog);

			rxr->xdp_prog = NULL;
			return rc;
		}
		bpf_prog_add(bp->xdp_prog, 1);
		rxr->xdp_prog = bp->xdp_prog;
	}
	prod = rxr->rx_prod;
	for (i = 0; i < bp->rx_ring_size; i++) {
+2 −7
Original line number Diff line number Diff line
@@ -1876,13 +1876,8 @@ static int nicvf_xdp_setup(struct nicvf *nic, struct bpf_prog *prog)

	if (nic->xdp_prog) {
		/* Attach BPF program */
		nic->xdp_prog = bpf_prog_add(nic->xdp_prog, nic->rx_queues - 1);
		if (!IS_ERR(nic->xdp_prog)) {
		bpf_prog_add(nic->xdp_prog, nic->rx_queues - 1);
		bpf_attached = true;
		} else {
			ret = PTR_ERR(nic->xdp_prog);
			nic->xdp_prog = NULL;
		}
	}

	/* Calculate Tx queues needed for XDP and network stack */
+2 −5
Original line number Diff line number Diff line
@@ -1807,11 +1807,8 @@ static int setup_xdp(struct net_device *dev, struct bpf_prog *prog)
	if (prog && !xdp_mtu_valid(priv, dev->mtu))
		return -EINVAL;

	if (prog) {
		prog = bpf_prog_add(prog, priv->num_channels);
		if (IS_ERR(prog))
			return PTR_ERR(prog);
	}
	if (prog)
		bpf_prog_add(prog, priv->num_channels);

	up = netif_running(dev);
	need_update = (!!priv->xdp_prog != !!prog);
+6 −18
Original line number Diff line number Diff line
@@ -2286,11 +2286,7 @@ int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv,
		lockdep_is_held(&priv->mdev->state_lock));

	if (xdp_prog && carry_xdp_prog) {
		xdp_prog = bpf_prog_add(xdp_prog, tmp->rx_ring_num);
		if (IS_ERR(xdp_prog)) {
			mlx4_en_free_resources(tmp);
			return PTR_ERR(xdp_prog);
		}
		bpf_prog_add(xdp_prog, tmp->rx_ring_num);
		for (i = 0; i < tmp->rx_ring_num; i++)
			rcu_assign_pointer(tmp->rx_ring[i]->xdp_prog,
					   xdp_prog);
@@ -2782,11 +2778,9 @@ static int mlx4_xdp_set(struct net_device *dev, struct bpf_prog *prog)
	 * program for a new one.
	 */
	if (priv->tx_ring_num[TX_XDP] == xdp_ring_num) {
		if (prog) {
			prog = bpf_prog_add(prog, priv->rx_ring_num - 1);
			if (IS_ERR(prog))
				return PTR_ERR(prog);
		}
		if (prog)
			bpf_prog_add(prog, priv->rx_ring_num - 1);

		mutex_lock(&mdev->state_lock);
		for (i = 0; i < priv->rx_ring_num; i++) {
			old_prog = rcu_dereference_protected(
@@ -2807,13 +2801,8 @@ static int mlx4_xdp_set(struct net_device *dev, struct bpf_prog *prog)
	if (!tmp)
		return -ENOMEM;

	if (prog) {
		prog = bpf_prog_add(prog, priv->rx_ring_num - 1);
		if (IS_ERR(prog)) {
			err = PTR_ERR(prog);
			goto out;
		}
	}
	if (prog)
		bpf_prog_add(prog, priv->rx_ring_num - 1);

	mutex_lock(&mdev->state_lock);
	memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));
@@ -2862,7 +2851,6 @@ static int mlx4_xdp_set(struct net_device *dev, struct bpf_prog *prog)

unlock_out:
	mutex_unlock(&mdev->state_lock);
out:
	kfree(tmp);
	return err;
}
+5 −13
Original line number Diff line number Diff line
@@ -408,12 +408,9 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
		rq->stats = &c->priv->channel_stats[c->ix].rq;
	INIT_WORK(&rq->recover_work, mlx5e_rq_err_cqe_work);

	rq->xdp_prog = params->xdp_prog ? bpf_prog_inc(params->xdp_prog) : NULL;
	if (IS_ERR(rq->xdp_prog)) {
		err = PTR_ERR(rq->xdp_prog);
		rq->xdp_prog = NULL;
		goto err_rq_wq_destroy;
	}
	if (params->xdp_prog)
		bpf_prog_inc(params->xdp_prog);
	rq->xdp_prog = params->xdp_prog;

	rq_xdp_ix = rq->ix;
	if (xsk)
@@ -4406,16 +4403,11 @@ static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog)
	/* no need for full reset when exchanging programs */
	reset = (!priv->channels.params.xdp_prog || !prog);

	if (was_opened && !reset) {
	if (was_opened && !reset)
		/* num_channels is invariant here, so we can take the
		 * batched reference right upfront.
		 */
		prog = bpf_prog_add(prog, priv->channels.num);
		if (IS_ERR(prog)) {
			err = PTR_ERR(prog);
			goto unlock;
		}
	}
		bpf_prog_add(prog, priv->channels.num);

	if (was_opened && reset) {
		struct mlx5e_channels new_channels = {};
Loading