]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
RDMA/hns: Fix the double unlock problem of poll_sem
authorYangyang Li <liyangyang20@huawei.com>
Mon, 2 Aug 2021 06:56:14 +0000 (14:56 +0800)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 3 Aug 2021 16:42:44 +0000 (13:42 -0300)
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: a389d016c030 ("RDMA/hns: Enable all CMDQ context")
Fixes: 3d50503b3b33 ("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>
drivers/infiniband/hw/hns/hns_roce_cmd.c
drivers/infiniband/hw/hns/hns_roce_main.c

index 8f68cc3ff193f004ae594aa457c30d2055ea7fa9..84f3f2b5f097606d98c62a175052c9459c6bc26f 100644 (file)
@@ -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;
@@ -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;
 }
@@ -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 *
index 078a97193f0eab05461be00de1dbcdb6397e03d9..cc6eab14a2220d0ea607fad8902a7db7764d2108 100644 (file)
@@ -873,11 +873,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);