iflib: expose the Rx mbuf buffer size to drivers
From Jake: iflib_fl_setup calculates a suitable buffer size for the Rx mbufs based on the isc_max_frame_size value that drivers setup. This calculation is repeated by drivers when programming their hardware with the size of each Rx buffer. This can lead to a mismatch where the iflib mbuf size is different from the expected size of the buffer as programmed by the hardware. This can lead to unexpected results. If iflib ever wants to support mbuf sizes larger than one page, every driver must be updated to account for the new possible buffer sizes. Fix this by calculating the mbuf size prior to calling IFDI_INIT, and adding the iflib_get_rx_mbuf_sz function which will expose this value to drivers, so that they do not repeat the same calculation. Submitted by: Jacob Keller <jacob.e.keller@intel.com> Reviewed by: shurd@, erj@ MFC after: 1 week Sponsored by: Intel Corporation Differential Revision: https://reviews.freebsd.org/D19489
This commit is contained in:
parent
ef226b1dc6
commit
66cfcbc300
@ -1270,14 +1270,7 @@ em_if_init(if_ctx_t ctx)
|
||||
/* Setup Multicast table */
|
||||
em_if_multi_set(ctx);
|
||||
|
||||
/*
|
||||
* Figure out the desired mbuf
|
||||
* pool for doing jumbos
|
||||
*/
|
||||
if (adapter->hw.mac.max_frame_size <= 2048)
|
||||
adapter->rx_mbuf_sz = MCLBYTES;
|
||||
else
|
||||
adapter->rx_mbuf_sz = MJUMPAGESIZE;
|
||||
adapter->rx_mbuf_sz = iflib_get_rx_mbuf_sz(ctx);
|
||||
em_initialize_receive_unit(ctx);
|
||||
|
||||
/* Use real VLAN Filter support? */
|
||||
|
@ -2880,10 +2880,7 @@ ixgbe_if_init(if_ctx_t ctx)
|
||||
ixgbe_if_multi_set(ctx);
|
||||
|
||||
/* Determine the correct mbuf pool, based on frame size */
|
||||
if (adapter->max_frame_size <= MCLBYTES)
|
||||
adapter->rx_mbuf_sz = MCLBYTES;
|
||||
else
|
||||
adapter->rx_mbuf_sz = MJUMPAGESIZE;
|
||||
adapter->rx_mbuf_sz = iflib_get_rx_mbuf_sz(ctx);
|
||||
|
||||
/* Configure RX settings */
|
||||
ixgbe_initialize_receive_units(ctx);
|
||||
|
@ -629,14 +629,7 @@ ixv_if_init(if_ctx_t ctx)
|
||||
/* Setup Multicast table */
|
||||
ixv_if_multi_set(ctx);
|
||||
|
||||
/*
|
||||
* Determine the correct mbuf pool
|
||||
* for doing jumbo/headersplit
|
||||
*/
|
||||
if (ifp->if_mtu > ETHERMTU)
|
||||
adapter->rx_mbuf_sz = MJUMPAGESIZE;
|
||||
else
|
||||
adapter->rx_mbuf_sz = MCLBYTES;
|
||||
adapter->rx_mbuf_sz = iflib_get_rx_mbuf_sz(ctx);
|
||||
|
||||
/* Configure RX settings */
|
||||
ixv_initialize_receive_units(ctx);
|
||||
|
@ -614,7 +614,6 @@ iavf_send_vc_msg(struct iavf_sc *sc, u32 op)
|
||||
static void
|
||||
iavf_init_queues(struct ixl_vsi *vsi)
|
||||
{
|
||||
if_softc_ctx_t scctx = vsi->shared;
|
||||
struct ixl_tx_queue *tx_que = vsi->tx_queues;
|
||||
struct ixl_rx_queue *rx_que = vsi->rx_queues;
|
||||
struct rx_ring *rxr;
|
||||
@ -625,10 +624,7 @@ iavf_init_queues(struct ixl_vsi *vsi)
|
||||
for (int i = 0; i < vsi->num_rx_queues; i++, rx_que++) {
|
||||
rxr = &rx_que->rxr;
|
||||
|
||||
if (scctx->isc_max_frame_size <= MCLBYTES)
|
||||
rxr->mbuf_sz = MCLBYTES;
|
||||
else
|
||||
rxr->mbuf_sz = MJUMPAGESIZE;
|
||||
rxr->mbuf_sz = iflib_get_rx_mbuf_sz(vsi->ctx);
|
||||
|
||||
wr32(vsi->hw, rxr->tail, 0);
|
||||
}
|
||||
|
@ -1300,10 +1300,7 @@ ixl_initialize_vsi(struct ixl_vsi *vsi)
|
||||
struct i40e_hmc_obj_rxq rctx;
|
||||
|
||||
/* Next setup the HMC RX Context */
|
||||
if (scctx->isc_max_frame_size <= MCLBYTES)
|
||||
rxr->mbuf_sz = MCLBYTES;
|
||||
else
|
||||
rxr->mbuf_sz = MJUMPAGESIZE;
|
||||
rxr->mbuf_sz = iflib_get_rx_mbuf_sz(vsi->ctx);
|
||||
|
||||
u16 max_rxmax = rxr->mbuf_sz * hw->func_caps.rx_buf_chain_len;
|
||||
|
||||
|
@ -171,6 +171,7 @@ struct iflib_ctx {
|
||||
uint32_t ifc_if_flags;
|
||||
uint32_t ifc_flags;
|
||||
uint32_t ifc_max_fl_buf_size;
|
||||
uint32_t ifc_rx_mbuf_sz;
|
||||
|
||||
int ifc_link_state;
|
||||
int ifc_link_irq;
|
||||
@ -2172,7 +2173,6 @@ iflib_fl_setup(iflib_fl_t fl)
|
||||
{
|
||||
iflib_rxq_t rxq = fl->ifl_rxq;
|
||||
if_ctx_t ctx = rxq->ifr_ctx;
|
||||
if_softc_ctx_t sctx = &ctx->ifc_softc_ctx;
|
||||
|
||||
bit_nclear(fl->ifl_rx_bitmap, 0, fl->ifl_size - 1);
|
||||
/*
|
||||
@ -2181,14 +2181,7 @@ iflib_fl_setup(iflib_fl_t fl)
|
||||
iflib_fl_bufs_free(fl);
|
||||
/* Now replenish the mbufs */
|
||||
MPASS(fl->ifl_credits == 0);
|
||||
/*
|
||||
* XXX don't set the max_frame_size to larger
|
||||
* than the hardware can handle
|
||||
*/
|
||||
if (sctx->isc_max_frame_size <= 2048)
|
||||
fl->ifl_buf_size = MCLBYTES;
|
||||
else
|
||||
fl->ifl_buf_size = MJUMPAGESIZE;
|
||||
fl->ifl_buf_size = ctx->ifc_rx_mbuf_sz;
|
||||
if (fl->ifl_buf_size > ctx->ifc_max_fl_buf_size)
|
||||
ctx->ifc_max_fl_buf_size = fl->ifl_buf_size;
|
||||
fl->ifl_cltype = m_gettype(fl->ifl_buf_size);
|
||||
@ -2313,6 +2306,27 @@ iflib_timer(void *arg)
|
||||
STATE_UNLOCK(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
iflib_calc_rx_mbuf_sz(if_ctx_t ctx)
|
||||
{
|
||||
if_softc_ctx_t sctx = &ctx->ifc_softc_ctx;
|
||||
|
||||
/*
|
||||
* XXX don't set the max_frame_size to larger
|
||||
* than the hardware can handle
|
||||
*/
|
||||
if (sctx->isc_max_frame_size <= MCLBYTES)
|
||||
ctx->ifc_rx_mbuf_sz = MCLBYTES;
|
||||
else
|
||||
ctx->ifc_rx_mbuf_sz = MJUMPAGESIZE;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
iflib_get_rx_mbuf_sz(if_ctx_t ctx)
|
||||
{
|
||||
return (ctx->ifc_rx_mbuf_sz);
|
||||
}
|
||||
|
||||
static void
|
||||
iflib_init_locked(if_ctx_t ctx)
|
||||
{
|
||||
@ -2347,6 +2361,14 @@ iflib_init_locked(if_ctx_t ctx)
|
||||
CALLOUT_UNLOCK(txq);
|
||||
iflib_netmap_txq_init(ctx, txq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate a suitable Rx mbuf size prior to calling IFDI_INIT, so
|
||||
* that drivers can use the value when setting up the hardware receive
|
||||
* buffers.
|
||||
*/
|
||||
iflib_calc_rx_mbuf_sz(ctx);
|
||||
|
||||
#ifdef INVARIANTS
|
||||
i = if_getdrvflags(ifp);
|
||||
#endif
|
||||
|
@ -381,6 +381,8 @@ void iflib_set_mac(if_ctx_t ctx, uint8_t mac[ETHER_ADDR_LEN]);
|
||||
void iflib_request_reset(if_ctx_t ctx);
|
||||
uint8_t iflib_in_detach(if_ctx_t ctx);
|
||||
|
||||
uint32_t iflib_get_rx_mbuf_sz(if_ctx_t ctx);
|
||||
|
||||
/*
|
||||
* If the driver can plug cleanly in to newbus use these
|
||||
*/
|
||||
|
@ -60,7 +60,7 @@
|
||||
* in the range 5 to 9.
|
||||
*/
|
||||
#undef __FreeBSD_version
|
||||
#define __FreeBSD_version 1300016 /* Master, propagated to newvers */
|
||||
#define __FreeBSD_version 1300017 /* Master, propagated to newvers */
|
||||
|
||||
/*
|
||||
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
|
||||
|
Loading…
x
Reference in New Issue
Block a user