Commit c3146eb6 authored by Dmitry Kravkov's avatar Dmitry Kravkov Committed by David S. Miller

bnx2x: Correct memory preparation and release

Since commit 15192a8c there have been a memory leak upon rmmod
of the bnx2x driver.

This corrects the memory leak and corrects the zeroing of internal
memories upon driver load.
Signed-off-by: default avatarDmitry Kravkov <dmitry@broadcom.com>
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 6ab20355
...@@ -1702,6 +1702,8 @@ struct bnx2x { ...@@ -1702,6 +1702,8 @@ struct bnx2x {
/* priority to cos mapping */ /* priority to cos mapping */
u8 prio_to_cos[8]; u8 prio_to_cos[8];
int fp_array_size;
u32 dump_preset_idx; u32 dump_preset_idx;
}; };
......
...@@ -2308,50 +2308,16 @@ static void bnx2x_nic_load_afex_dcc(struct bnx2x *bp, int load_code) ...@@ -2308,50 +2308,16 @@ static void bnx2x_nic_load_afex_dcc(struct bnx2x *bp, int load_code)
static void bnx2x_bz_fp(struct bnx2x *bp, int index) static void bnx2x_bz_fp(struct bnx2x *bp, int index)
{ {
struct bnx2x_fastpath *fp = &bp->fp[index]; struct bnx2x_fastpath *fp = &bp->fp[index];
struct bnx2x_fp_stats *fp_stats = &bp->fp_stats[index];
int cos; int cos;
struct napi_struct orig_napi = fp->napi; struct napi_struct orig_napi = fp->napi;
struct bnx2x_agg_info *orig_tpa_info = fp->tpa_info; struct bnx2x_agg_info *orig_tpa_info = fp->tpa_info;
/* bzero bnx2x_fastpath contents */ /* bzero bnx2x_fastpath contents */
if (bp->stats_init) { if (fp->tpa_info)
memset(fp->tpa_info, 0, sizeof(*fp->tpa_info)); memset(fp->tpa_info, 0, ETH_MAX_AGGREGATION_QUEUES_E1H_E2 *
memset(fp, 0, sizeof(*fp)); sizeof(struct bnx2x_agg_info));
} else {
/* Keep Queue statistics */
struct bnx2x_eth_q_stats *tmp_eth_q_stats;
struct bnx2x_eth_q_stats_old *tmp_eth_q_stats_old;
tmp_eth_q_stats = kzalloc(sizeof(struct bnx2x_eth_q_stats),
GFP_KERNEL);
if (tmp_eth_q_stats)
memcpy(tmp_eth_q_stats, &fp_stats->eth_q_stats,
sizeof(struct bnx2x_eth_q_stats));
tmp_eth_q_stats_old =
kzalloc(sizeof(struct bnx2x_eth_q_stats_old),
GFP_KERNEL);
if (tmp_eth_q_stats_old)
memcpy(tmp_eth_q_stats_old, &fp_stats->eth_q_stats_old,
sizeof(struct bnx2x_eth_q_stats_old));
memset(fp->tpa_info, 0, sizeof(*fp->tpa_info));
memset(fp, 0, sizeof(*fp)); memset(fp, 0, sizeof(*fp));
if (tmp_eth_q_stats) {
memcpy(&fp_stats->eth_q_stats, tmp_eth_q_stats,
sizeof(struct bnx2x_eth_q_stats));
kfree(tmp_eth_q_stats);
}
if (tmp_eth_q_stats_old) {
memcpy(&fp_stats->eth_q_stats_old, tmp_eth_q_stats_old,
sizeof(struct bnx2x_eth_q_stats_old));
kfree(tmp_eth_q_stats_old);
}
}
/* Restore the NAPI object as it has been already initialized */ /* Restore the NAPI object as it has been already initialized */
fp->napi = orig_napi; fp->napi = orig_napi;
fp->tpa_info = orig_tpa_info; fp->tpa_info = orig_tpa_info;
...@@ -4227,7 +4193,10 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp) ...@@ -4227,7 +4193,10 @@ int bnx2x_alloc_fp_mem(struct bnx2x *bp)
void bnx2x_free_mem_bp(struct bnx2x *bp) void bnx2x_free_mem_bp(struct bnx2x *bp)
{ {
kfree(bp->fp->tpa_info); int i;
for (i = 0; i < bp->fp_array_size; i++)
kfree(bp->fp[i].tpa_info);
kfree(bp->fp); kfree(bp->fp);
kfree(bp->sp_objs); kfree(bp->sp_objs);
kfree(bp->fp_stats); kfree(bp->fp_stats);
...@@ -4256,12 +4225,13 @@ int bnx2x_alloc_mem_bp(struct bnx2x *bp) ...@@ -4256,12 +4225,13 @@ int bnx2x_alloc_mem_bp(struct bnx2x *bp)
/* fp array: RSS plus CNIC related L2 queues */ /* fp array: RSS plus CNIC related L2 queues */
fp_array_size = BNX2X_MAX_RSS_COUNT(bp) + CNIC_SUPPORT(bp); fp_array_size = BNX2X_MAX_RSS_COUNT(bp) + CNIC_SUPPORT(bp);
BNX2X_DEV_INFO("fp_array_size %d", fp_array_size); bp->fp_array_size = fp_array_size;
BNX2X_DEV_INFO("fp_array_size %d\n", bp->fp_array_size);
fp = kcalloc(fp_array_size, sizeof(*fp), GFP_KERNEL); fp = kcalloc(bp->fp_array_size, sizeof(*fp), GFP_KERNEL);
if (!fp) if (!fp)
goto alloc_err; goto alloc_err;
for (i = 0; i < fp_array_size; i++) { for (i = 0; i < bp->fp_array_size; i++) {
fp[i].tpa_info = fp[i].tpa_info =
kcalloc(ETH_MAX_AGGREGATION_QUEUES_E1H_E2, kcalloc(ETH_MAX_AGGREGATION_QUEUES_E1H_E2,
sizeof(struct bnx2x_agg_info), GFP_KERNEL); sizeof(struct bnx2x_agg_info), GFP_KERNEL);
...@@ -4272,13 +4242,13 @@ int bnx2x_alloc_mem_bp(struct bnx2x *bp) ...@@ -4272,13 +4242,13 @@ int bnx2x_alloc_mem_bp(struct bnx2x *bp)
bp->fp = fp; bp->fp = fp;
/* allocate sp objs */ /* allocate sp objs */
bp->sp_objs = kcalloc(fp_array_size, sizeof(struct bnx2x_sp_objs), bp->sp_objs = kcalloc(bp->fp_array_size, sizeof(struct bnx2x_sp_objs),
GFP_KERNEL); GFP_KERNEL);
if (!bp->sp_objs) if (!bp->sp_objs)
goto alloc_err; goto alloc_err;
/* allocate fp_stats */ /* allocate fp_stats */
bp->fp_stats = kcalloc(fp_array_size, sizeof(struct bnx2x_fp_stats), bp->fp_stats = kcalloc(bp->fp_array_size, sizeof(struct bnx2x_fp_stats),
GFP_KERNEL); GFP_KERNEL);
if (!bp->fp_stats) if (!bp->fp_stats)
goto alloc_err; goto alloc_err;
......
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