summaryrefslogtreecommitdiff
path: root/drivers/net/bonding
diff options
context:
space:
mode:
authorJianhua Xie <jianhua.xie@freescale.com>2014-06-30 11:06:22 (GMT)
committerRichard Schmitt <richard.schmitt@freescale.com>2014-08-06 20:17:53 (GMT)
commit404731473a7c3ae4a25fb0fd53580f4d41b891b8 (patch)
tree5478eeee81fbeefa23e91130d03f8607659e9a54 /drivers/net/bonding
parent94a0df86ff6cc8586d84ddef29cbd9580f463f99 (diff)
downloadlinux-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/net/bonding')
-rw-r--r--drivers/net/bonding/hw_distribution.c1
-rw-r--r--drivers/net/bonding/hw_distribution.h1
-rw-r--r--drivers/net/bonding/hw_oh_pcd.c44
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;