Commit 4864a16a authored by Yuval Mintz's avatar Yuval Mintz Committed by David S. Miller

bnx2x: Fix fastpath structures when memory allocation fails

When allocating Tx queues, if for some reason
(e.g., lack of memory) allocation fails, driver will incorrectly
calculate the pointers of the various queues.

This patch repositions all pointers in such a case to point at
sequential structures in memory, allowing the bnx2x macros to
be used correctly when accessing them.
Signed-off-by: default avatarYuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: default avatarAriel Elior <ariele@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ec82f94c
...@@ -80,12 +80,37 @@ static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to) ...@@ -80,12 +80,37 @@ static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to)
new_txdata_index = new_max_eth_txqs + FCOE_TXQ_IDX_OFFSET; new_txdata_index = new_max_eth_txqs + FCOE_TXQ_IDX_OFFSET;
} }
memcpy(&bp->bnx2x_txq[old_txdata_index], memcpy(&bp->bnx2x_txq[new_txdata_index],
&bp->bnx2x_txq[new_txdata_index], &bp->bnx2x_txq[old_txdata_index],
sizeof(struct bnx2x_fp_txdata)); sizeof(struct bnx2x_fp_txdata));
to_fp->txdata_ptr[0] = &bp->bnx2x_txq[new_txdata_index]; to_fp->txdata_ptr[0] = &bp->bnx2x_txq[new_txdata_index];
} }
/**
* bnx2x_shrink_eth_fp - guarantees fastpath structures stay intact
*
* @bp: driver handle
* @delta: number of eth queues which were not allocated
*/
static void bnx2x_shrink_eth_fp(struct bnx2x *bp, int delta)
{
int i, cos, old_eth_num = BNX2X_NUM_ETH_QUEUES(bp);
/* Queue pointer cannot be re-set on an fp-basis, as moving pointer
* backward along the array could cause memory to be overriden
*/
for (cos = 1; cos < bp->max_cos; cos++) {
for (i = 0; i < old_eth_num - delta; i++) {
struct bnx2x_fastpath *fp = &bp->fp[i];
int new_idx = cos * (old_eth_num - delta) + i;
memcpy(&bp->bnx2x_txq[new_idx], fp->txdata_ptr[cos],
sizeof(struct bnx2x_fp_txdata));
fp->txdata_ptr[cos] = &bp->bnx2x_txq[new_idx];
}
}
}
int load_count[2][3] = { {0} }; /* per-path: 0-common, 1-port0, 2-port1 */ int load_count[2][3] = { {0} }; /* per-path: 0-common, 1-port0, 2-port1 */
/* free skb in the packet ring at pos idx /* free skb in the packet ring at pos idx
...@@ -3863,6 +3888,7 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp) ...@@ -3863,6 +3888,7 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp)
int delta = BNX2X_NUM_ETH_QUEUES(bp) - i; int delta = BNX2X_NUM_ETH_QUEUES(bp) - i;
WARN_ON(delta < 0); WARN_ON(delta < 0);
bnx2x_shrink_eth_fp(bp, delta);
if (CNIC_SUPPORT(bp)) if (CNIC_SUPPORT(bp))
/* move non eth FPs next to last eth FP /* move non eth FPs next to last eth FP
* must be done in that order * must be done in that order
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment