if (new_bpf_prog && netdev->mtu > VMXNET3_XDP_MAX_MTU) {
NL_SET_ERR_MSG_FMT_MOD(extack, "MTU %u too large for XDP",
netdev->mtu); return -EOPNOTSUPP;
}
if (adapter->netdev->features & NETIF_F_LRO) {
NL_SET_ERR_MSG_MOD(extack, "LRO is not supported with XDP");
adapter->netdev->features &= ~NETIF_F_LRO;
}
old_bpf_prog = rcu_dereference(adapter->xdp_bpf_prog); if (!new_bpf_prog && !old_bpf_prog) return 0;
if (running && need_update)
vmxnet3_quiesce_dev(adapter);
vmxnet3_xdp_exchange_program(adapter, new_bpf_prog); if (old_bpf_prog)
bpf_prog_put(old_bpf_prog);
if (!running || !need_update) return 0;
if (new_bpf_prog)
xdp_features_set_redirect_target(netdev, false); else
xdp_features_clear_redirect_target(netdev);
vmxnet3_reset_dev(adapter);
vmxnet3_rq_destroy_all(adapter);
vmxnet3_adjust_rx_ring_size(adapter);
err = vmxnet3_rq_create_all(adapter); if (err) {
NL_SET_ERR_MSG_MOD(extack, "failed to re-create rx queues for XDP."); return -EOPNOTSUPP;
}
err = vmxnet3_activate_dev(adapter); if (err) {
NL_SET_ERR_MSG_MOD(extack, "failed to activate device for XDP."); return -EOPNOTSUPP;
}
clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
return 0;
}
/* This is the main xdp call used by kernel to set/unset eBPF program. */ int
vmxnet3_xdp(struct net_device *netdev, struct netdev_bpf *bpf)
{ switch (bpf->command) { case XDP_SETUP_PROG: return vmxnet3_xdp_set(netdev, bpf, bpf->extack); default: return -EINVAL;
}
/* No need to handle the case when tx_num_deferred doesn't reach * threshold. Backend driver at hypervisor side will poll and reset * tq->shared->txNumDeferred to 0.
*/ if (tx_num_deferred >= le32_to_cpu(tq->shared->txThreshold)) {
tq->shared->txNumDeferred = 0;
VMXNET3_WRITE_BAR0_REG(adapter,
VMXNET3_REG_TXPROD + tq->qid * 8,
tq->tx_ring.next2fill);
}
/* ndo_xdp_xmit */ int
vmxnet3_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames, u32 flags)
{ struct vmxnet3_adapter *adapter = netdev_priv(dev); struct vmxnet3_tx_queue *tq; struct netdev_queue *nq; int i;
if (unlikely(test_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state))) return -ENETDOWN; if (unlikely(test_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state))) return -EINVAL;
tq = vmxnet3_xdp_get_tq(adapter); if (tq->stopped) return -ENETDOWN;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.