fjes: fix memleaks in fjes_hw_setup
[ Upstream commit f6cc4b6a3ae53df425771000e9c9540cce9b7bb1 ]
In fjes_hw_setup, it allocates several memory and delay the deallocation
to the fjes_hw_exit in fjes_probe through the following call chain:
fjes_probe
|-> fjes_hw_init
|-> fjes_hw_setup
|-> fjes_hw_exit
However, when fjes_hw_setup fails, fjes_hw_exit won't be called and thus
all the resources allocated in fjes_hw_setup will be leaked. In this
patch, we free those resources in fjes_hw_setup and prevents such leaks.
Fixes: 2fcbca6877
("fjes: platform_driver's .probe and .remove routine")
Signed-off-by: Zhipeng Lu <alexious@zju.edu.cn>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20240122172445.3841883-1-alexious@zju.edu.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
4b4dcb3f42
commit
5b1086d226
|
@ -221,21 +221,25 @@ static int fjes_hw_setup(struct fjes_hw *hw)
|
|||
|
||||
mem_size = FJES_DEV_REQ_BUF_SIZE(hw->max_epid);
|
||||
hw->hw_info.req_buf = kzalloc(mem_size, GFP_KERNEL);
|
||||
if (!(hw->hw_info.req_buf))
|
||||
return -ENOMEM;
|
||||
if (!(hw->hw_info.req_buf)) {
|
||||
result = -ENOMEM;
|
||||
goto free_ep_info;
|
||||
}
|
||||
|
||||
hw->hw_info.req_buf_size = mem_size;
|
||||
|
||||
mem_size = FJES_DEV_RES_BUF_SIZE(hw->max_epid);
|
||||
hw->hw_info.res_buf = kzalloc(mem_size, GFP_KERNEL);
|
||||
if (!(hw->hw_info.res_buf))
|
||||
return -ENOMEM;
|
||||
if (!(hw->hw_info.res_buf)) {
|
||||
result = -ENOMEM;
|
||||
goto free_req_buf;
|
||||
}
|
||||
|
||||
hw->hw_info.res_buf_size = mem_size;
|
||||
|
||||
result = fjes_hw_alloc_shared_status_region(hw);
|
||||
if (result)
|
||||
return result;
|
||||
goto free_res_buf;
|
||||
|
||||
hw->hw_info.buffer_share_bit = 0;
|
||||
hw->hw_info.buffer_unshare_reserve_bit = 0;
|
||||
|
@ -246,11 +250,11 @@ static int fjes_hw_setup(struct fjes_hw *hw)
|
|||
|
||||
result = fjes_hw_alloc_epbuf(&buf_pair->tx);
|
||||
if (result)
|
||||
return result;
|
||||
goto free_epbuf;
|
||||
|
||||
result = fjes_hw_alloc_epbuf(&buf_pair->rx);
|
||||
if (result)
|
||||
return result;
|
||||
goto free_epbuf;
|
||||
|
||||
spin_lock_irqsave(&hw->rx_status_lock, flags);
|
||||
fjes_hw_setup_epbuf(&buf_pair->tx, mac,
|
||||
|
@ -273,6 +277,25 @@ static int fjes_hw_setup(struct fjes_hw *hw)
|
|||
fjes_hw_init_command_registers(hw, ¶m);
|
||||
|
||||
return 0;
|
||||
|
||||
free_epbuf:
|
||||
for (epidx = 0; epidx < hw->max_epid ; epidx++) {
|
||||
if (epidx == hw->my_epid)
|
||||
continue;
|
||||
fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].tx);
|
||||
fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].rx);
|
||||
}
|
||||
fjes_hw_free_shared_status_region(hw);
|
||||
free_res_buf:
|
||||
kfree(hw->hw_info.res_buf);
|
||||
hw->hw_info.res_buf = NULL;
|
||||
free_req_buf:
|
||||
kfree(hw->hw_info.req_buf);
|
||||
hw->hw_info.req_buf = NULL;
|
||||
free_ep_info:
|
||||
kfree(hw->ep_shm_info);
|
||||
hw->ep_shm_info = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void fjes_hw_cleanup(struct fjes_hw *hw)
|
||||
|
|
Loading…
Reference in New Issue