mirror of
https://github.com/torvalds/linux.git
synced 2024-12-03 17:41:22 +00:00
RDMA/rxe: Prevent double freeing rxe_map_set()
The same rxe_map_set could be freed twice: rxe_reg_user_mr() -> rxe_mr_init_user() -> rxe_mr_free_map_set() # 1st -> rxe_drop_ref() ... -> rxe_mr_cleanup() -> rxe_mr_free_map_set() # 2nd Follow normal convection and put resource cleanup either in the error unwind of the allocator, or the overall free function. Leave the object unchanged with a NULL cur_map_set on failure and remove the unncessary free in rxe_mr_init_user(). Link: https://lore.kernel.org/r/20211228014406.1033444-1-lizhijian@cn.fujitsu.com Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com> Acked-by: Zhu Yanjun <zyjzyj2000@gmail.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
c9e6606c7f
commit
8ff5f5d9d8
@ -135,19 +135,19 @@ static int rxe_mr_alloc(struct rxe_mr *mr, int num_buf, int both)
|
|||||||
|
|
||||||
ret = rxe_mr_alloc_map_set(num_map, &mr->cur_map_set);
|
ret = rxe_mr_alloc_map_set(num_map, &mr->cur_map_set);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_out;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (both) {
|
if (both) {
|
||||||
ret = rxe_mr_alloc_map_set(num_map, &mr->next_map_set);
|
ret = rxe_mr_alloc_map_set(num_map, &mr->next_map_set);
|
||||||
if (ret) {
|
if (ret)
|
||||||
rxe_mr_free_map_set(mr->num_map, mr->cur_map_set);
|
goto err_free;
|
||||||
goto err_out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_out:
|
err_free:
|
||||||
|
rxe_mr_free_map_set(mr->num_map, mr->cur_map_set);
|
||||||
|
mr->cur_map_set = NULL;
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
|
|||||||
pr_warn("%s: Unable to get virtual address\n",
|
pr_warn("%s: Unable to get virtual address\n",
|
||||||
__func__);
|
__func__);
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto err_cleanup_map;
|
goto err_release_umem;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf->addr = (uintptr_t)vaddr;
|
buf->addr = (uintptr_t)vaddr;
|
||||||
@ -237,8 +237,6 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_cleanup_map:
|
|
||||||
rxe_mr_free_map_set(mr->num_map, mr->cur_map_set);
|
|
||||||
err_release_umem:
|
err_release_umem:
|
||||||
ib_umem_release(umem);
|
ib_umem_release(umem);
|
||||||
err_out:
|
err_out:
|
||||||
|
Loading…
Reference in New Issue
Block a user