diff options
author | Mike Christie <mchristi@redhat.com> | 2017-11-28 13:40:32 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2018-01-12 18:07:13 -0500 |
commit | 6fddcb775477bb2213bd76ab62145645eb570f33 (patch) | |
tree | 59c35a54d94bf131d8af543e5740519fcaa46aa9 /drivers/target | |
parent | 488ebe4c355fdead39dbb3f6a51329c16cbfcc60 (diff) |
tcmu: remove commands_lock
No need for the commands_lock. The cmdr_lock is already held during
idr addition and deletion, so just grab it during traversal.
Note: This also fixes a issue where we should have been using at
least _bh locking in tcmu_handle_completions when taking the commands
lock to prevent the case where tcmu_handle_completions could be
interrupted by a timer softirq while the commands_lock is held.
Signed-off-by: Mike Christie <mchristi@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_user.c | 13 |
1 files changed, 3 insertions, 10 deletions
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 2ccc8e61449b..43583a792439 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c | |||
@@ -139,7 +139,6 @@ struct tcmu_dev { | |||
139 | struct radix_tree_root data_blocks; | 139 | struct radix_tree_root data_blocks; |
140 | 140 | ||
141 | struct idr commands; | 141 | struct idr commands; |
142 | spinlock_t commands_lock; | ||
143 | 142 | ||
144 | struct timer_list timeout; | 143 | struct timer_list timeout; |
145 | unsigned int cmd_time_out; | 144 | unsigned int cmd_time_out; |
@@ -1014,10 +1013,7 @@ static unsigned int tcmu_handle_completions(struct tcmu_dev *udev) | |||
1014 | } | 1013 | } |
1015 | WARN_ON(tcmu_hdr_get_op(entry->hdr.len_op) != TCMU_OP_CMD); | 1014 | WARN_ON(tcmu_hdr_get_op(entry->hdr.len_op) != TCMU_OP_CMD); |
1016 | 1015 | ||
1017 | spin_lock(&udev->commands_lock); | ||
1018 | cmd = idr_remove(&udev->commands, entry->hdr.cmd_id); | 1016 | cmd = idr_remove(&udev->commands, entry->hdr.cmd_id); |
1019 | spin_unlock(&udev->commands_lock); | ||
1020 | |||
1021 | if (!cmd) { | 1017 | if (!cmd) { |
1022 | pr_err("cmd_id not found, ring is broken\n"); | 1018 | pr_err("cmd_id not found, ring is broken\n"); |
1023 | set_bit(TCMU_DEV_BIT_BROKEN, &udev->flags); | 1019 | set_bit(TCMU_DEV_BIT_BROKEN, &udev->flags); |
@@ -1115,7 +1111,6 @@ static struct se_device *tcmu_alloc_device(struct se_hba *hba, const char *name) | |||
1115 | 1111 | ||
1116 | INIT_LIST_HEAD(&udev->timedout_entry); | 1112 | INIT_LIST_HEAD(&udev->timedout_entry); |
1117 | idr_init(&udev->commands); | 1113 | idr_init(&udev->commands); |
1118 | spin_lock_init(&udev->commands_lock); | ||
1119 | 1114 | ||
1120 | timer_setup(&udev->timeout, tcmu_device_timedout, 0); | 1115 | timer_setup(&udev->timeout, tcmu_device_timedout, 0); |
1121 | 1116 | ||
@@ -1333,16 +1328,14 @@ static void tcmu_dev_kref_release(struct kref *kref) | |||
1333 | spin_unlock_bh(&timed_out_udevs_lock); | 1328 | spin_unlock_bh(&timed_out_udevs_lock); |
1334 | 1329 | ||
1335 | /* Upper layer should drain all requests before calling this */ | 1330 | /* Upper layer should drain all requests before calling this */ |
1336 | spin_lock_irq(&udev->commands_lock); | 1331 | mutex_lock(&udev->cmdr_lock); |
1337 | idr_for_each_entry(&udev->commands, cmd, i) { | 1332 | idr_for_each_entry(&udev->commands, cmd, i) { |
1338 | if (tcmu_check_and_free_pending_cmd(cmd) != 0) | 1333 | if (tcmu_check_and_free_pending_cmd(cmd) != 0) |
1339 | all_expired = false; | 1334 | all_expired = false; |
1340 | } | 1335 | } |
1341 | idr_destroy(&udev->commands); | 1336 | idr_destroy(&udev->commands); |
1342 | spin_unlock_irq(&udev->commands_lock); | ||
1343 | WARN_ON(!all_expired); | 1337 | WARN_ON(!all_expired); |
1344 | 1338 | ||
1345 | mutex_lock(&udev->cmdr_lock); | ||
1346 | tcmu_blocks_release(&udev->data_blocks, 0, udev->dbi_max + 1); | 1339 | tcmu_blocks_release(&udev->data_blocks, 0, udev->dbi_max + 1); |
1347 | mutex_unlock(&udev->cmdr_lock); | 1340 | mutex_unlock(&udev->cmdr_lock); |
1348 | 1341 | ||
@@ -2060,9 +2053,9 @@ static void check_timedout_devices(void) | |||
2060 | list_del_init(&udev->timedout_entry); | 2053 | list_del_init(&udev->timedout_entry); |
2061 | spin_unlock_bh(&timed_out_udevs_lock); | 2054 | spin_unlock_bh(&timed_out_udevs_lock); |
2062 | 2055 | ||
2063 | spin_lock(&udev->commands_lock); | 2056 | mutex_lock(&udev->cmdr_lock); |
2064 | idr_for_each(&udev->commands, tcmu_check_expired_cmd, NULL); | 2057 | idr_for_each(&udev->commands, tcmu_check_expired_cmd, NULL); |
2065 | spin_unlock(&udev->commands_lock); | 2058 | mutex_unlock(&udev->cmdr_lock); |
2066 | 2059 | ||
2067 | spin_lock_bh(&timed_out_udevs_lock); | 2060 | spin_lock_bh(&timed_out_udevs_lock); |
2068 | } | 2061 | } |