diff options
author | Jianhua Xie <jianhua.xie@freescale.com> | 2014-06-30 11:06:22 (GMT) |
---|---|---|
committer | Richard Schmitt <richard.schmitt@freescale.com> | 2014-08-06 20:17:53 (GMT) |
commit | 404731473a7c3ae4a25fb0fd53580f4d41b891b8 (patch) | |
tree | 5478eeee81fbeefa23e91130d03f8607659e9a54 /drivers | |
parent | 94a0df86ff6cc8586d84ddef29cbd9580f463f99 (diff) | |
download | linux-fsl-qoriq-404731473a7c3ae4a25fb0fd53580f4d41b891b8.tar.xz |
bonding: avoid re-allocate PCD memory for HW LAG
Add a flag to avoid re-allocation PCD memory for HW LAG.
Without this patch, old codes can introduce memory leak
when call alloc_pcd_mem() in HW LAG.
Change-Id: I92065867c8a2e8ea8315f4cd0de1b3ec99c512e7
Signed-off-by: Jianhua Xie <jianhua.xie@freescale.com>
Reviewed-on: http://git.am.freescale.net:8181/14201
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Jiafei Pan <Jiafei.Pan@freescale.com>
Reviewed-by: Richard Schmitt <richard.schmitt@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/bonding/hw_distribution.c | 1 | ||||
-rw-r--r-- | drivers/net/bonding/hw_distribution.h | 1 | ||||
-rw-r--r-- | drivers/net/bonding/hw_oh_pcd.c | 44 |
3 files changed, 31 insertions, 15 deletions
diff --git a/drivers/net/bonding/hw_distribution.c b/drivers/net/bonding/hw_distribution.c index b1a9cfc..74839c1 100644 --- a/drivers/net/bonding/hw_distribution.c +++ b/drivers/net/bonding/hw_distribution.c @@ -1533,6 +1533,7 @@ int get_oh_info(void) return errno; } + poh[i].allocated_pcd_mem = false; available_num_of_oh_ports = ++i; } } diff --git a/drivers/net/bonding/hw_distribution.h b/drivers/net/bonding/hw_distribution.h index 32f6e2f..da53c38 100644 --- a/drivers/net/bonding/hw_distribution.h +++ b/drivers/net/bonding/hw_distribution.h @@ -104,6 +104,7 @@ struct oh_port_priv { int oh_en; /* enable or disable offline port's help at run-time */ unsigned char friendname[OHFRIENDNAMSIZ]; unsigned long cell_index; + bool allocated_pcd_mem; t_Handle h_FmPcd; t_Handle h_FmPort; t_Handle h_NetEnv; diff --git a/drivers/net/bonding/hw_oh_pcd.c b/drivers/net/bonding/hw_oh_pcd.c index ce75048..9ba9abb 100644 --- a/drivers/net/bonding/hw_oh_pcd.c +++ b/drivers/net/bonding/hw_oh_pcd.c @@ -120,7 +120,7 @@ static int alloc_pcd_mem(struct fm_port *fm_port, uint8_t numOfSchemes, h_NetEnv = FM_PCD_NetEnvCharacteristicsSet(h_FmPcd, netEnvParams); if (!h_NetEnv) { pr_err("error on FM_PCD_NetEnvCharacteristicsSet.\n"); - return E_INVALID_VALUE; + goto netEnvParams_err; } hw_lag_dbg("FM_PCD_NetEnvCharacteristicsSet() ok.\n"); /* bind port to PCD properties */ @@ -128,14 +128,14 @@ static int alloc_pcd_mem(struct fm_port *fm_port, uint8_t numOfSchemes, pcdParam = kzalloc(sizeof(t_FmPortPcdParams), GFP_KERNEL); if (!pcdParam) { pr_err("Failed to allocate pcdParam.\n"); - return -ENOMEM; + goto netEnvParams_err; } hw_lag_dbg("pcdParam:%p\n", pcdParam); /* initialize parser port parameters */ prsParam = kzalloc(sizeof(t_FmPortPcdPrsParams), GFP_KERNEL); if (!prsParam) { pr_err("Failed to allocate prsParam.\n"); - return -ENOMEM; + goto pcdParam_err; } hw_lag_dbg("prsParam:%p\n", prsParam); @@ -149,7 +149,7 @@ static int alloc_pcd_mem(struct fm_port *fm_port, uint8_t numOfSchemes, kgParam = kzalloc(sizeof(t_FmPortPcdKgParams), GFP_KERNEL); if (!kgParam) { pr_err("Failed to allocate kgParam.\n"); - return -ENOMEM; + goto prsParam_err; } hw_lag_dbg("kgParam:%p\n", kgParam); @@ -163,7 +163,7 @@ static int alloc_pcd_mem(struct fm_port *fm_port, uint8_t numOfSchemes, GFP_KERNEL); if (!scheme) { pr_err("Failed to allocate scheme.\n"); - return -ENOMEM; + goto kgParam_err; } hw_lag_dbg("scheme:%p\n", scheme); @@ -534,8 +534,20 @@ static int alloc_pcd_mem(struct fm_port *fm_port, uint8_t numOfSchemes, bond->params.ohp->scheme = scheme; bond->params.ohp->netEnvParams = netEnvParams; hw_lag_dbg("alloc_pcd_mem() ok.\n"); + bond->params.ohp->allocated_pcd_mem = true; return BOND_OH_SUCCESS; + +kgParam_err: + kfree(kgParam); +prsParam_err: + kfree(prsParam); +pcdParam_err: + kfree(pcdParam); +netEnvParams_err: + kfree(netEnvParams); + + return BOND_OH_ERROR; } int release_pcd_mem(struct bonding *bond) @@ -725,18 +737,20 @@ bool apply_pcd(struct bonding *bond, int new_xmit_policy) hw_lag_dbg("fm_port:%p, numOfSchemes:%d, pcd_fqids_base:%d", fm_port, numOfSchemes, pcd_fqids_base); hw_lag_dbg("distNumOfQueues:%d, bond:%p\n", distNumOfQueues, bond); - err = alloc_pcd_mem(fm_port, numOfSchemes, pcd_fqids_base, - distNumOfQueues, bond); - if (err == BOND_OH_SUCCESS) { - err = replace_pcd(fm_port, numOfSchemes, pcd_fqids_base, - distNumOfQueues, bond); - if (err == BOND_OH_SUCCESS) { - hw_lag_dbg("applied PCD.\n"); - return true; - } else { - pr_err("error on replace_pcd()\n"); + if (!bond->params.ohp->allocated_pcd_mem) { + err = alloc_pcd_mem(fm_port, MAX_SCHEMES, pcd_fqids_base, + distNumOfQueues, bond); + if (err != BOND_OH_SUCCESS) { + pr_err("error on alloc_pcd_mem().\n"); return false; } + } + + err = replace_pcd(fm_port, numOfSchemes, pcd_fqids_base, + distNumOfQueues, bond); + if (err == BOND_OH_SUCCESS) { + hw_lag_dbg("applied PCD.\n"); + return true; } else { pr_err("error on replace_pcd()\n"); return false; |