| From foo@baz Thu Dec 21 09:02:40 CET 2017 |
| From: Sagi Grimberg <sagi@grimberg.me> |
| Date: Mon, 27 Feb 2017 20:16:33 +0200 |
| Subject: RDMA/iser: Fix possible mr leak on device removal event |
| |
| From: Sagi Grimberg <sagi@grimberg.me> |
| |
| |
| [ Upstream commit ea174c9573b0e0c8bc1a7a90fe9360ccb7aa9cbb ] |
| |
| When the rdma device is removed, we must cleanup all |
| the rdma resources within the DEVICE_REMOVAL event |
| handler to let the device teardown gracefully. When |
| this happens with live I/O, some memory regions are |
| occupied. Thus, track them too and dereg all the mr's. |
| |
| We are safe with mr access by iscsi_iser_cleanup_task. |
| |
| Reported-by: Raju Rangoju <rajur@chelsio.com> |
| Signed-off-by: Sagi Grimberg <sagi@grimberg.me> |
| Reviewed-by: Max Gurtovoy <maxg@mellanox.com> |
| Reviewed-by: Max Gurtovoy <maxg@mellanox.com> |
| Signed-off-by: Doug Ledford <dledford@redhat.com> |
| Signed-off-by: Sasha Levin <alexander.levin@verizon.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/infiniband/ulp/iser/iscsi_iser.h | 2 ++ |
| drivers/infiniband/ulp/iser/iser_verbs.c | 8 +++++--- |
| 2 files changed, 7 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/infiniband/ulp/iser/iscsi_iser.h |
| +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h |
| @@ -430,6 +430,7 @@ struct iser_fr_desc { |
| struct list_head list; |
| struct iser_reg_resources rsc; |
| struct iser_pi_context *pi_ctx; |
| + struct list_head all_list; |
| }; |
| |
| /** |
| @@ -443,6 +444,7 @@ struct iser_fr_pool { |
| struct list_head list; |
| spinlock_t lock; |
| int size; |
| + struct list_head all_list; |
| }; |
| |
| /** |
| --- a/drivers/infiniband/ulp/iser/iser_verbs.c |
| +++ b/drivers/infiniband/ulp/iser/iser_verbs.c |
| @@ -362,6 +362,7 @@ int iser_alloc_fastreg_pool(struct ib_co |
| int i, ret; |
| |
| INIT_LIST_HEAD(&fr_pool->list); |
| + INIT_LIST_HEAD(&fr_pool->all_list); |
| spin_lock_init(&fr_pool->lock); |
| fr_pool->size = 0; |
| for (i = 0; i < cmds_max; i++) { |
| @@ -373,6 +374,7 @@ int iser_alloc_fastreg_pool(struct ib_co |
| } |
| |
| list_add_tail(&desc->list, &fr_pool->list); |
| + list_add_tail(&desc->all_list, &fr_pool->all_list); |
| fr_pool->size++; |
| } |
| |
| @@ -392,13 +394,13 @@ void iser_free_fastreg_pool(struct ib_co |
| struct iser_fr_desc *desc, *tmp; |
| int i = 0; |
| |
| - if (list_empty(&fr_pool->list)) |
| + if (list_empty(&fr_pool->all_list)) |
| return; |
| |
| iser_info("freeing conn %p fr pool\n", ib_conn); |
| |
| - list_for_each_entry_safe(desc, tmp, &fr_pool->list, list) { |
| - list_del(&desc->list); |
| + list_for_each_entry_safe(desc, tmp, &fr_pool->all_list, all_list) { |
| + list_del(&desc->all_list); |
| iser_free_reg_res(&desc->rsc); |
| if (desc->pi_ctx) |
| iser_free_pi_ctx(desc->pi_ctx); |