Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue
Tony Nguyen says: ==================== This series contains updates to ice driver only. Przemyslaw fixes memory leak of DMA memory due to incorrect freeing of rx_buf. Michal S corrects incorrect call to free memory. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
cf5c15d1e9
@ -7,18 +7,6 @@
|
||||
#include "ice_dcb_lib.h"
|
||||
#include "ice_sriov.h"
|
||||
|
||||
static bool ice_alloc_rx_buf_zc(struct ice_rx_ring *rx_ring)
|
||||
{
|
||||
rx_ring->xdp_buf = kcalloc(rx_ring->count, sizeof(*rx_ring->xdp_buf), GFP_KERNEL);
|
||||
return !!rx_ring->xdp_buf;
|
||||
}
|
||||
|
||||
static bool ice_alloc_rx_buf(struct ice_rx_ring *rx_ring)
|
||||
{
|
||||
rx_ring->rx_buf = kcalloc(rx_ring->count, sizeof(*rx_ring->rx_buf), GFP_KERNEL);
|
||||
return !!rx_ring->rx_buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* __ice_vsi_get_qs_contig - Assign a contiguous chunk of queues to VSI
|
||||
* @qs_cfg: gathered variables needed for PF->VSI queues assignment
|
||||
@ -519,11 +507,8 @@ int ice_vsi_cfg_rxq(struct ice_rx_ring *ring)
|
||||
xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev,
|
||||
ring->q_index, ring->q_vector->napi.napi_id);
|
||||
|
||||
kfree(ring->rx_buf);
|
||||
ring->xsk_pool = ice_xsk_pool(ring);
|
||||
if (ring->xsk_pool) {
|
||||
if (!ice_alloc_rx_buf_zc(ring))
|
||||
return -ENOMEM;
|
||||
xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq);
|
||||
|
||||
ring->rx_buf_len =
|
||||
@ -538,8 +523,6 @@ int ice_vsi_cfg_rxq(struct ice_rx_ring *ring)
|
||||
dev_info(dev, "Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring %d\n",
|
||||
ring->q_index);
|
||||
} else {
|
||||
if (!ice_alloc_rx_buf(ring))
|
||||
return -ENOMEM;
|
||||
if (!xdp_rxq_info_is_reg(&ring->xdp_rxq))
|
||||
/* coverity[check_return] */
|
||||
xdp_rxq_info_reg(&ring->xdp_rxq,
|
||||
|
@ -2898,10 +2898,18 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
|
||||
if (xdp_ring_err)
|
||||
NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Tx resources failed");
|
||||
}
|
||||
/* reallocate Rx queues that are used for zero-copy */
|
||||
xdp_ring_err = ice_realloc_zc_buf(vsi, true);
|
||||
if (xdp_ring_err)
|
||||
NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Rx resources failed");
|
||||
} else if (ice_is_xdp_ena_vsi(vsi) && !prog) {
|
||||
xdp_ring_err = ice_destroy_xdp_rings(vsi);
|
||||
if (xdp_ring_err)
|
||||
NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Tx resources failed");
|
||||
/* reallocate Rx queues that were used for zero-copy */
|
||||
xdp_ring_err = ice_realloc_zc_buf(vsi, false);
|
||||
if (xdp_ring_err)
|
||||
NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Rx resources failed");
|
||||
} else {
|
||||
/* safe to call even when prog == vsi->xdp_prog as
|
||||
* dev_xdp_install in net/core/dev.c incremented prog's
|
||||
@ -3905,7 +3913,7 @@ static int ice_init_pf(struct ice_pf *pf)
|
||||
|
||||
pf->avail_rxqs = bitmap_zalloc(pf->max_pf_rxqs, GFP_KERNEL);
|
||||
if (!pf->avail_rxqs) {
|
||||
devm_kfree(ice_pf_to_dev(pf), pf->avail_txqs);
|
||||
bitmap_free(pf->avail_txqs);
|
||||
pf->avail_txqs = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -192,6 +192,7 @@ static int ice_qp_dis(struct ice_vsi *vsi, u16 q_idx)
|
||||
err = ice_vsi_ctrl_one_rx_ring(vsi, false, q_idx, true);
|
||||
if (err)
|
||||
return err;
|
||||
ice_clean_rx_ring(rx_ring);
|
||||
|
||||
ice_qvec_toggle_napi(vsi, q_vector, false);
|
||||
ice_qp_clean_rings(vsi, q_idx);
|
||||
@ -316,6 +317,62 @@ ice_xsk_pool_enable(struct ice_vsi *vsi, struct xsk_buff_pool *pool, u16 qid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_realloc_rx_xdp_bufs - reallocate for either XSK or normal buffer
|
||||
* @rx_ring: Rx ring
|
||||
* @pool_present: is pool for XSK present
|
||||
*
|
||||
* Try allocating memory and return ENOMEM, if failed to allocate.
|
||||
* If allocation was successful, substitute buffer with allocated one.
|
||||
* Returns 0 on success, negative on failure
|
||||
*/
|
||||
static int
|
||||
ice_realloc_rx_xdp_bufs(struct ice_rx_ring *rx_ring, bool pool_present)
|
||||
{
|
||||
size_t elem_size = pool_present ? sizeof(*rx_ring->xdp_buf) :
|
||||
sizeof(*rx_ring->rx_buf);
|
||||
void *sw_ring = kcalloc(rx_ring->count, elem_size, GFP_KERNEL);
|
||||
|
||||
if (!sw_ring)
|
||||
return -ENOMEM;
|
||||
|
||||
if (pool_present) {
|
||||
kfree(rx_ring->rx_buf);
|
||||
rx_ring->rx_buf = NULL;
|
||||
rx_ring->xdp_buf = sw_ring;
|
||||
} else {
|
||||
kfree(rx_ring->xdp_buf);
|
||||
rx_ring->xdp_buf = NULL;
|
||||
rx_ring->rx_buf = sw_ring;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_realloc_zc_buf - reallocate XDP ZC queue pairs
|
||||
* @vsi: Current VSI
|
||||
* @zc: is zero copy set
|
||||
*
|
||||
* Reallocate buffer for rx_rings that might be used by XSK.
|
||||
* XDP requires more memory, than rx_buf provides.
|
||||
* Returns 0 on success, negative on failure
|
||||
*/
|
||||
int ice_realloc_zc_buf(struct ice_vsi *vsi, bool zc)
|
||||
{
|
||||
struct ice_rx_ring *rx_ring;
|
||||
unsigned long q;
|
||||
|
||||
for_each_set_bit(q, vsi->af_xdp_zc_qps,
|
||||
max_t(int, vsi->alloc_txq, vsi->alloc_rxq)) {
|
||||
rx_ring = vsi->rx_rings[q];
|
||||
if (ice_realloc_rx_xdp_bufs(rx_ring, zc))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_xsk_pool_setup - enable/disable a buffer pool region depending on its state
|
||||
* @vsi: Current VSI
|
||||
@ -345,11 +402,17 @@ int ice_xsk_pool_setup(struct ice_vsi *vsi, struct xsk_buff_pool *pool, u16 qid)
|
||||
if_running = netif_running(vsi->netdev) && ice_is_xdp_ena_vsi(vsi);
|
||||
|
||||
if (if_running) {
|
||||
struct ice_rx_ring *rx_ring = vsi->rx_rings[qid];
|
||||
|
||||
ret = ice_qp_dis(vsi, qid);
|
||||
if (ret) {
|
||||
netdev_err(vsi->netdev, "ice_qp_dis error = %d\n", ret);
|
||||
goto xsk_pool_if_up;
|
||||
}
|
||||
|
||||
ret = ice_realloc_rx_xdp_bufs(rx_ring, pool_present);
|
||||
if (ret)
|
||||
goto xsk_pool_if_up;
|
||||
}
|
||||
|
||||
pool_failure = pool_present ? ice_xsk_pool_enable(vsi, pool, qid) :
|
||||
|
@ -27,6 +27,7 @@ bool ice_xsk_any_rx_ring_ena(struct ice_vsi *vsi);
|
||||
void ice_xsk_clean_rx_ring(struct ice_rx_ring *rx_ring);
|
||||
void ice_xsk_clean_xdp_ring(struct ice_tx_ring *xdp_ring);
|
||||
bool ice_xmit_zc(struct ice_tx_ring *xdp_ring, u32 budget, int napi_budget);
|
||||
int ice_realloc_zc_buf(struct ice_vsi *vsi, bool zc);
|
||||
#else
|
||||
static inline bool
|
||||
ice_xmit_zc(struct ice_tx_ring __always_unused *xdp_ring,
|
||||
@ -72,5 +73,12 @@ ice_xsk_wakeup(struct net_device __always_unused *netdev,
|
||||
|
||||
static inline void ice_xsk_clean_rx_ring(struct ice_rx_ring *rx_ring) { }
|
||||
static inline void ice_xsk_clean_xdp_ring(struct ice_tx_ring *xdp_ring) { }
|
||||
|
||||
static inline int
|
||||
ice_realloc_zc_buf(struct ice_vsi __always_unused *vsi,
|
||||
bool __always_unused zc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_XDP_SOCKETS */
|
||||
#endif /* !_ICE_XSK_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user