This fixes data corruptions arising from concurrent enabling of a target devices. When multiple enable calls are made concurrently then it is possible for the target device to be set up twice which results in a kernel BUG. Introduces a per target device mutex for serializing enable requests. Signed-off-by: Grzegorz Uriasz ---  drivers/target/target_core_device.c | 17 +++++++++++++----  include/target/target_core_base.h   |  1 +  2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 90f3f4926172..6d8fb962c780 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -742,6 +742,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)      INIT_WORK(&dev->delayed_cmd_work, target_do_delayed_work);      mutex_init(&dev->lun_reset_mutex); +    mutex_init(&dev->configure_mutex);      dev->t10_wwn.t10_dev = dev;      /* @@ -904,10 +905,15 @@ int target_configure_device(struct se_device *dev)      struct se_hba *hba = dev->se_hba;      int ret, id; +    ret = mutex_lock_interruptible(&dev->configure_mutex); +    if (ret) +        return ret; +      if (target_dev_configured(dev)) {          pr_err("se_dev->se_dev_ptr already set for storage"                  " object\n"); -        return -EEXIST; +        ret = -EEXIST; +        goto out_release_mutex;      }      /* @@ -923,7 +929,7 @@ int target_configure_device(struct se_device *dev)      mutex_unlock(&device_mutex);      if (id < 0) {          ret = -ENOMEM; -        goto out; +        goto out_release_vpd;      }      dev->dev_index = id; @@ -969,7 +975,8 @@ int target_configure_device(struct se_device *dev)      dev->dev_flags |= DF_CONFIGURED; -    return 0; +    ret = 0; +    goto out_release_mutex;  out_destroy_device:      dev->transport->destroy_device(dev); @@ -977,8 +984,10 @@ int target_configure_device(struct se_device *dev)      mutex_lock(&device_mutex);      idr_remove(&devices_idr, dev->dev_index);      mutex_unlock(&device_mutex); -out: +out_release_vpd:      se_release_vpd_for_dev(dev); +out_release_mutex: +    mutex_unlock(&dev->configure_mutex);      return ret;  } diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 5f8e96f1516f..b3f9bd641688 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -869,6 +869,7 @@ struct se_device {      int            queue_cnt;      struct se_device_queue    *queues;      struct mutex        lun_reset_mutex; +    struct mutex        configure_mutex;  };  struct target_opcode_descriptor { -- 2.40.0