aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorShlomo Pongratz <shlomop@mellanox.com>2012-08-29 11:14:33 -0400
committerRoland Dreier <roland@purestorage.com>2012-09-12 12:05:03 -0400
commit66172c09938bfc4efdcf9b5e0246a85b9b76dd54 (patch)
tree05b77629b993215b0cbc478b5941fdf5cc1e1d05 /drivers
parentfea7a08acb13524b47711625eebea40a0ede69a0 (diff)
IPoIB: Fix memory leak in the neigh table deletion flow
If the neighbours hash table is empty when unloading the module, then ipoib_flush_neighs(), the cleanup routine, isn't called and the memory used for the hash table itself leaked. To fix this, ipoib_flush_neighs() is allways called, and another completion object is added to signal when the table is freed. Once invoked, ipoib_flush_neighs() flushes all the neighbours (if there are any), calls the the hash table RCU free routine, which now signals completion of the deletion process, and waits for the last neighbour to be freed. Signed-off-by: Shlomo Pongratz <shlomop@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c23
2 files changed, 21 insertions, 6 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index ca43901ed861..e6bbeae1c309 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -262,7 +262,10 @@ struct ipoib_ethtool_st {
262 u16 max_coalesced_frames; 262 u16 max_coalesced_frames;
263}; 263};
264 264
265struct ipoib_neigh_table;
266
265struct ipoib_neigh_hash { 267struct ipoib_neigh_hash {
268 struct ipoib_neigh_table *ntbl;
266 struct ipoib_neigh __rcu **buckets; 269 struct ipoib_neigh __rcu **buckets;
267 struct rcu_head rcu; 270 struct rcu_head rcu;
268 u32 mask; 271 u32 mask;
@@ -274,6 +277,7 @@ struct ipoib_neigh_table {
274 rwlock_t rwlock; 277 rwlock_t rwlock;
275 atomic_t entries; 278 atomic_t entries;
276 struct completion flushed; 279 struct completion flushed;
280 struct completion deleted;
277}; 281};
278 282
279/* 283/*
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 3e2085a3ee47..72c1fc28f079 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -1095,6 +1095,7 @@ static int ipoib_neigh_hash_init(struct ipoib_dev_priv *priv)
1095 htbl->mask = (size - 1); 1095 htbl->mask = (size - 1);
1096 htbl->buckets = buckets; 1096 htbl->buckets = buckets;
1097 ntbl->htbl = htbl; 1097 ntbl->htbl = htbl;
1098 htbl->ntbl = ntbl;
1098 atomic_set(&ntbl->entries, 0); 1099 atomic_set(&ntbl->entries, 0);
1099 1100
1100 /* start garbage collection */ 1101 /* start garbage collection */
@@ -1111,9 +1112,11 @@ static void neigh_hash_free_rcu(struct rcu_head *head)
1111 struct ipoib_neigh_hash, 1112 struct ipoib_neigh_hash,
1112 rcu); 1113 rcu);
1113 struct ipoib_neigh __rcu **buckets = htbl->buckets; 1114 struct ipoib_neigh __rcu **buckets = htbl->buckets;
1115 struct ipoib_neigh_table *ntbl = htbl->ntbl;
1114 1116
1115 kfree(buckets); 1117 kfree(buckets);
1116 kfree(htbl); 1118 kfree(htbl);
1119 complete(&ntbl->deleted);
1117} 1120}
1118 1121
1119void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid) 1122void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid)
@@ -1164,7 +1167,9 @@ static void ipoib_flush_neighs(struct ipoib_dev_priv *priv)
1164 struct ipoib_neigh_table *ntbl = &priv->ntbl; 1167 struct ipoib_neigh_table *ntbl = &priv->ntbl;
1165 struct ipoib_neigh_hash *htbl; 1168 struct ipoib_neigh_hash *htbl;
1166 unsigned long flags; 1169 unsigned long flags;
1167 int i; 1170 int i, wait_flushed = 0;
1171
1172 init_completion(&priv->ntbl.flushed);
1168 1173
1169 write_lock_bh(&ntbl->rwlock); 1174 write_lock_bh(&ntbl->rwlock);
1170 1175
@@ -1173,6 +1178,10 @@ static void ipoib_flush_neighs(struct ipoib_dev_priv *priv)
1173 if (!htbl) 1178 if (!htbl)
1174 goto out_unlock; 1179 goto out_unlock;
1175 1180
1181 wait_flushed = atomic_read(&priv->ntbl.entries);
1182 if (!wait_flushed)
1183 goto free_htbl;
1184
1176 for (i = 0; i < htbl->size; i++) { 1185 for (i = 0; i < htbl->size; i++) {
1177 struct ipoib_neigh *neigh; 1186 struct ipoib_neigh *neigh;
1178 struct ipoib_neigh __rcu **np = &htbl->buckets[i]; 1187 struct ipoib_neigh __rcu **np = &htbl->buckets[i];
@@ -1190,11 +1199,14 @@ static void ipoib_flush_neighs(struct ipoib_dev_priv *priv)
1190 } 1199 }
1191 } 1200 }
1192 1201
1202free_htbl:
1193 rcu_assign_pointer(ntbl->htbl, NULL); 1203 rcu_assign_pointer(ntbl->htbl, NULL);
1194 call_rcu(&htbl->rcu, neigh_hash_free_rcu); 1204 call_rcu(&htbl->rcu, neigh_hash_free_rcu);
1195 1205
1196out_unlock: 1206out_unlock:
1197 write_unlock_bh(&ntbl->rwlock); 1207 write_unlock_bh(&ntbl->rwlock);
1208 if (wait_flushed)
1209 wait_for_completion(&priv->ntbl.flushed);
1198} 1210}
1199 1211
1200static void ipoib_neigh_hash_uninit(struct net_device *dev) 1212static void ipoib_neigh_hash_uninit(struct net_device *dev)
@@ -1203,7 +1215,7 @@ static void ipoib_neigh_hash_uninit(struct net_device *dev)
1203 int stopped; 1215 int stopped;
1204 1216
1205 ipoib_dbg(priv, "ipoib_neigh_hash_uninit\n"); 1217 ipoib_dbg(priv, "ipoib_neigh_hash_uninit\n");
1206 init_completion(&priv->ntbl.flushed); 1218 init_completion(&priv->ntbl.deleted);
1207 set_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags); 1219 set_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags);
1208 1220
1209 /* Stop GC if called at init fail need to cancel work */ 1221 /* Stop GC if called at init fail need to cancel work */
@@ -1211,10 +1223,9 @@ static void ipoib_neigh_hash_uninit(struct net_device *dev)
1211 if (!stopped) 1223 if (!stopped)
1212 cancel_delayed_work(&priv->neigh_reap_task); 1224 cancel_delayed_work(&priv->neigh_reap_task);
1213 1225
1214 if (atomic_read(&priv->ntbl.entries)) { 1226 ipoib_flush_neighs(priv);
1215 ipoib_flush_neighs(priv); 1227
1216 wait_for_completion(&priv->ntbl.flushed); 1228 wait_for_completion(&priv->ntbl.deleted);
1217 }
1218} 1229}
1219 1230
1220 1231