int count = 0;
        struct nvme_ctrl *ctrl;
 
-       mutex_lock(&subsys->lock);
+       lockdep_assert_held(&nvme_subsystems_lock);
+
        list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) {
                if (ctrl->state != NVME_CTRL_DELETING &&
                    ctrl->state != NVME_CTRL_DEAD)
                        count++;
        }
-       mutex_unlock(&subsys->lock);
 
        return count;
 }
        mutex_lock(&nvme_subsystems_lock);
        found = __nvme_find_get_subsystem(subsys->subnqn);
        if (found) {
+               __nvme_release_subsystem(subsys);
+               subsys = found;
+
                /*
                 * Verify that the subsystem actually supports multiple
                 * controllers, else bail out.
                    nvme_active_ctrls(found) && !(id->cmic & (1 << 1))) {
                        dev_err(ctrl->device,
                                "ignoring ctrl due to duplicate subnqn (%s).\n",
-                               found->subnqn);
-                       nvme_put_subsystem(found);
+                               subsys->subnqn);
                        ret = -EINVAL;
-                       goto out_unlock;
+                       goto out_put_subsystem;
                }
-
-               __nvme_release_subsystem(subsys);
-               subsys = found;
        } else {
                ret = device_add(&subsys->dev);
                if (ret) {
                list_add_tail(&subsys->entry, &nvme_subsystems);
        }
 
-       ctrl->subsys = subsys;
-       mutex_unlock(&nvme_subsystems_lock);
-
        if (sysfs_create_link(&subsys->dev.kobj, &ctrl->device->kobj,
                        dev_name(ctrl->device))) {
                dev_err(ctrl->device,
                        "failed to create sysfs link from subsystem.\n");
-               /* the transport driver will eventually put the subsystem */
-               return -EINVAL;
+               goto out_put_subsystem;
        }
 
-       mutex_lock(&subsys->lock);
+       ctrl->subsys = subsys;
        list_add_tail(&ctrl->subsys_entry, &subsys->ctrls);
-       mutex_unlock(&subsys->lock);
-
+       mutex_unlock(&nvme_subsystems_lock);
        return 0;
 
+out_put_subsystem:
+       nvme_put_subsystem(subsys);
 out_unlock:
        mutex_unlock(&nvme_subsystems_lock);
        put_device(&subsys->dev);
        __free_page(ctrl->discard_page);
 
        if (subsys) {
-               mutex_lock(&subsys->lock);
+               mutex_lock(&nvme_subsystems_lock);
                list_del(&ctrl->subsys_entry);
-               mutex_unlock(&subsys->lock);
                sysfs_remove_link(&subsys->dev.kobj, dev_name(ctrl->device));
+               mutex_unlock(&nvme_subsystems_lock);
        }
 
        ctrl->ops->free_ctrl(ctrl);