From: Parav Pandit <parav@xxxxxxxxxxxx> When releasing GID table in release_gid_table(), there must not be any stale reference to a GID table entry. All GID entries must be freed when ib_cache_cleanup_one() completes. If a GID table entry has reference leak (unbalanced get/put), do not attempt to free such GID table entry. Fixes: 5198d83df9f6 ("IB/core: Introduce GID entry reference counts") Signed-off-by: Parav Pandit <parav@xxxxxxxxxxxx> Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx> --- drivers/infiniband/core/cache.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index 1c398555f3ee..fc10d99a5e60 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c @@ -798,6 +798,7 @@ static struct ib_gid_table *alloc_gid_table(int sz) static void release_gid_table(struct ib_device *device, u8 port, struct ib_gid_table *table) { + bool leak = false; int i; if (!table) @@ -806,12 +807,15 @@ static void release_gid_table(struct ib_device *device, u8 port, for (i = 0; i < table->sz; i++) { if (is_gid_entry_free(table->data_vec[i])) continue; - if (kref_read(&table->data_vec[i]->kref) > 1) - pr_warn("GID entry ref leak for %s (index %d) ref=%d\n", - device->name, i, - kref_read(&table->data_vec[i]->kref)); - put_gid_entry(table->data_vec[i]); + if (kref_read(&table->data_vec[i]->kref) > 1) { + pr_err("GID entry ref leak for %s (index %d) ref=%d\n", + device->name, i, + kref_read(&table->data_vec[i]->kref)); + leak = true; + } } + if (leak) + return; kfree(table->data_vec); kfree(table); -- 2.14.4 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html