drivers/net/ethernet/microsoft/mana/mana_bpf.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/microsoft/mana/mana_bpf.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/microsoft/mana/mana_bpf.c
Extension
.c
Size
5525 bytes
Lines
267
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!rxq->xdp_rc) {
			rxq->xdp_flush = true;

			u64_stats_update_begin(&rx_stats->syncp);
			rx_stats->packets++;
			rx_stats->bytes += pkt_len;
			rx_stats->xdp_redirect++;
			u64_stats_update_end(&rx_stats->syncp);

			break;
		}

		fallthrough;

	case XDP_ABORTED:
		trace_xdp_exception(ndev, prog, act);
		break;

	default:
		bpf_warn_invalid_xdp_action(ndev, prog, act);
	}

out:
	rcu_read_unlock();

	return act;
}

struct bpf_prog *mana_xdp_get(struct mana_port_context *apc)
{
	ASSERT_RTNL();

	return apc->bpf_prog;
}

static struct bpf_prog *mana_chn_xdp_get(struct mana_port_context *apc)
{
	return rtnl_dereference(apc->rxqs[0]->bpf_prog);
}

/* Set xdp program on channels */
void mana_chn_setxdp(struct mana_port_context *apc, struct bpf_prog *prog)
{
	struct bpf_prog *old_prog = mana_chn_xdp_get(apc);
	unsigned int num_queues = apc->num_queues;
	int i;

	ASSERT_RTNL();

	if (old_prog == prog)
		return;

	if (prog)
		bpf_prog_add(prog, num_queues);

	for (i = 0; i < num_queues; i++)
		rcu_assign_pointer(apc->rxqs[i]->bpf_prog, prog);

	if (old_prog)
		for (i = 0; i < num_queues; i++)
			bpf_prog_put(old_prog);
}

static int mana_xdp_set(struct net_device *ndev, struct bpf_prog *prog,
			struct netlink_ext_ack *extack)
{
	struct mana_port_context *apc = netdev_priv(ndev);
	struct bpf_prog *old_prog;
	struct gdma_context *gc;
	int err;

	gc = apc->ac->gdma_dev->gdma_context;

	old_prog = mana_xdp_get(apc);

	if (!old_prog && !prog)
		return 0;

	if (prog && ndev->mtu > MANA_XDP_MTU_MAX) {
		netdev_err(ndev, "XDP: mtu:%u too large, mtu_max:%lu\n",
			   ndev->mtu, MANA_XDP_MTU_MAX);
		NL_SET_ERR_MSG_MOD(extack, "XDP: mtu too large");

		return -EOPNOTSUPP;
	}

	/* One refcnt of the prog is hold by the caller already, so
	 * don't increase refcnt for this one.
	 */
	apc->bpf_prog = prog;

Annotation

Implementation Notes