Skip to content

Commit

Permalink
RDMA/hns: Fix the double unlock problem of poll_sem
Browse files Browse the repository at this point in the history
[ Upstream commit 8b436a9 ]

If hns_roce_cmd_use_events() fails then it means that the poll_sem is not
obtained, but the poll_sem is released in hns_roce_cmd_use_polling(), this
will cause an unlock problem.

This is the static checker warning:
	drivers/infiniband/hw/hns/hns_roce_main.c:926 hns_roce_init()
	error: double unlocked '&hr_dev->cmd.poll_sem' (orig line 879)

Event mode and polling mode are mutually exclusive and resources are
separated, so there is no need to process polling mode resources in event
mode.

The initial mode of cmd is polling mode, so even if cmd fails to switch to
event mode, it is not necessary to switch to polling mode.

Fixes: a389d01 ("RDMA/hns: Enable all CMDQ context")
Fixes: 3d50503 ("RDMA/hns: Optimize cmd init and mode selection for hip08")
Link: https://lore.kernel.org/r/1627887374-20019-1-git-send-email-liangwenpeng@huawei.com
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Yangyang Li <liyangyang20@huawei.com>
Signed-off-by: Wenpeng Liang <liangwenpeng@huawei.com>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
l00436852 authored and gregkh committed Aug 12, 2021
1 parent c3aba13 commit 60dd525
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 7 deletions.
7 changes: 3 additions & 4 deletions drivers/infiniband/hw/hns/hns_roce_cmd.c
Expand Up @@ -213,8 +213,10 @@ int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev)

hr_cmd->context =
kcalloc(hr_cmd->max_cmds, sizeof(*hr_cmd->context), GFP_KERNEL);
if (!hr_cmd->context)
if (!hr_cmd->context) {
hr_dev->cmd_mod = 0;
return -ENOMEM;
}

for (i = 0; i < hr_cmd->max_cmds; ++i) {
hr_cmd->context[i].token = i;
Expand All @@ -228,7 +230,6 @@ int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev)
spin_lock_init(&hr_cmd->context_lock);

hr_cmd->use_events = 1;
down(&hr_cmd->poll_sem);

return 0;
}
Expand All @@ -239,8 +240,6 @@ void hns_roce_cmd_use_polling(struct hns_roce_dev *hr_dev)

kfree(hr_cmd->context);
hr_cmd->use_events = 0;

up(&hr_cmd->poll_sem);
}

struct hns_roce_cmd_mailbox *
Expand Down
4 changes: 1 addition & 3 deletions drivers/infiniband/hw/hns/hns_roce_main.c
Expand Up @@ -897,11 +897,9 @@ int hns_roce_init(struct hns_roce_dev *hr_dev)

if (hr_dev->cmd_mod) {
ret = hns_roce_cmd_use_events(hr_dev);
if (ret) {
if (ret)
dev_warn(dev,
"Cmd event mode failed, set back to poll!\n");
hns_roce_cmd_use_polling(hr_dev);
}
}

ret = hns_roce_init_hem(hr_dev);
Expand Down

0 comments on commit 60dd525

Please sign in to comment.