diff options
author | Mike Christie <mchristi@redhat.com> | 2017-03-09 03:42:09 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2017-03-18 19:32:27 -0400 |
commit | af980e46a26ac8805685bb70c8572dbc47abb126 (patch) | |
tree | 68fb80c55ec73bedb428cd33ccf7685dbf07aa43 | |
parent | 972c7f167974fa41ea8a2eed4b857cc59f59c42c (diff) |
tcmu: make cmd timeout configurable
A single daemon could implement multiple types of devices
using multuple types of real devices that may not support
restarting from crashes and/or handling tcmu timeouts. This
makes the cmd timeout configurable, so handlers that do not
support it can turn if off for now.
Signed-off-by: Mike Christie <mchristi@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/target/target_core_user.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 892b311e7874..10cc15f0b1fa 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c | |||
@@ -112,6 +112,7 @@ struct tcmu_dev { | |||
112 | spinlock_t commands_lock; | 112 | spinlock_t commands_lock; |
113 | 113 | ||
114 | struct timer_list timeout; | 114 | struct timer_list timeout; |
115 | unsigned int cmd_time_out; | ||
115 | 116 | ||
116 | char dev_config[TCMU_CONFIG_LEN]; | 117 | char dev_config[TCMU_CONFIG_LEN]; |
117 | }; | 118 | }; |
@@ -172,7 +173,9 @@ static struct tcmu_cmd *tcmu_alloc_cmd(struct se_cmd *se_cmd) | |||
172 | 173 | ||
173 | tcmu_cmd->se_cmd = se_cmd; | 174 | tcmu_cmd->se_cmd = se_cmd; |
174 | tcmu_cmd->tcmu_dev = udev; | 175 | tcmu_cmd->tcmu_dev = udev; |
175 | tcmu_cmd->deadline = jiffies + msecs_to_jiffies(TCMU_TIME_OUT); | 176 | if (udev->cmd_time_out) |
177 | tcmu_cmd->deadline = jiffies + | ||
178 | msecs_to_jiffies(udev->cmd_time_out); | ||
176 | 179 | ||
177 | idr_preload(GFP_KERNEL); | 180 | idr_preload(GFP_KERNEL); |
178 | spin_lock_irq(&udev->commands_lock); | 181 | spin_lock_irq(&udev->commands_lock); |
@@ -451,7 +454,11 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd) | |||
451 | 454 | ||
452 | pr_debug("sleeping for ring space\n"); | 455 | pr_debug("sleeping for ring space\n"); |
453 | spin_unlock_irq(&udev->cmdr_lock); | 456 | spin_unlock_irq(&udev->cmdr_lock); |
454 | ret = schedule_timeout(msecs_to_jiffies(TCMU_TIME_OUT)); | 457 | if (udev->cmd_time_out) |
458 | ret = schedule_timeout( | ||
459 | msecs_to_jiffies(udev->cmd_time_out)); | ||
460 | else | ||
461 | ret = schedule_timeout(msecs_to_jiffies(TCMU_TIME_OUT)); | ||
455 | finish_wait(&udev->wait_cmdr, &__wait); | 462 | finish_wait(&udev->wait_cmdr, &__wait); |
456 | if (!ret) { | 463 | if (!ret) { |
457 | pr_warn("tcmu: command timed out\n"); | 464 | pr_warn("tcmu: command timed out\n"); |
@@ -526,8 +533,9 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd) | |||
526 | /* TODO: only if FLUSH and FUA? */ | 533 | /* TODO: only if FLUSH and FUA? */ |
527 | uio_event_notify(&udev->uio_info); | 534 | uio_event_notify(&udev->uio_info); |
528 | 535 | ||
529 | mod_timer(&udev->timeout, | 536 | if (udev->cmd_time_out) |
530 | round_jiffies_up(jiffies + msecs_to_jiffies(TCMU_TIME_OUT))); | 537 | mod_timer(&udev->timeout, round_jiffies_up(jiffies + |
538 | msecs_to_jiffies(udev->cmd_time_out))); | ||
531 | 539 | ||
532 | return TCM_NO_SENSE; | 540 | return TCM_NO_SENSE; |
533 | } | 541 | } |
@@ -742,6 +750,7 @@ static struct se_device *tcmu_alloc_device(struct se_hba *hba, const char *name) | |||
742 | } | 750 | } |
743 | 751 | ||
744 | udev->hba = hba; | 752 | udev->hba = hba; |
753 | udev->cmd_time_out = TCMU_TIME_OUT; | ||
745 | 754 | ||
746 | init_waitqueue_head(&udev->wait_cmdr); | 755 | init_waitqueue_head(&udev->wait_cmdr); |
747 | spin_lock_init(&udev->cmdr_lock); | 756 | spin_lock_init(&udev->cmdr_lock); |
@@ -1037,7 +1046,7 @@ static void tcmu_free_device(struct se_device *dev) | |||
1037 | 1046 | ||
1038 | enum { | 1047 | enum { |
1039 | Opt_dev_config, Opt_dev_size, Opt_hw_block_size, Opt_hw_max_sectors, | 1048 | Opt_dev_config, Opt_dev_size, Opt_hw_block_size, Opt_hw_max_sectors, |
1040 | Opt_err, | 1049 | Opt_cmd_time_out, Opt_err, |
1041 | }; | 1050 | }; |
1042 | 1051 | ||
1043 | static match_table_t tokens = { | 1052 | static match_table_t tokens = { |
@@ -1045,6 +1054,7 @@ static match_table_t tokens = { | |||
1045 | {Opt_dev_size, "dev_size=%u"}, | 1054 | {Opt_dev_size, "dev_size=%u"}, |
1046 | {Opt_hw_block_size, "hw_block_size=%u"}, | 1055 | {Opt_hw_block_size, "hw_block_size=%u"}, |
1047 | {Opt_hw_max_sectors, "hw_max_sectors=%u"}, | 1056 | {Opt_hw_max_sectors, "hw_max_sectors=%u"}, |
1057 | {Opt_cmd_time_out, "cmd_time_out=%u"}, | ||
1048 | {Opt_err, NULL} | 1058 | {Opt_err, NULL} |
1049 | }; | 1059 | }; |
1050 | 1060 | ||
@@ -1111,6 +1121,23 @@ static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev, | |||
1111 | if (ret < 0) | 1121 | if (ret < 0) |
1112 | pr_err("kstrtoul() failed for dev_size=\n"); | 1122 | pr_err("kstrtoul() failed for dev_size=\n"); |
1113 | break; | 1123 | break; |
1124 | case Opt_cmd_time_out: | ||
1125 | if (tcmu_dev_configured(udev)) { | ||
1126 | pr_err("Can not update cmd_time_out after device has been configured.\n"); | ||
1127 | ret = -EINVAL; | ||
1128 | break; | ||
1129 | } | ||
1130 | arg_p = match_strdup(&args[0]); | ||
1131 | if (!arg_p) { | ||
1132 | ret = -ENOMEM; | ||
1133 | break; | ||
1134 | } | ||
1135 | ret = kstrtouint(arg_p, 0, &udev->cmd_time_out); | ||
1136 | kfree(arg_p); | ||
1137 | if (ret < 0) | ||
1138 | pr_err("kstrtouint() failed for cmd_time_out=\n"); | ||
1139 | udev->cmd_time_out *= MSEC_PER_SEC; | ||
1140 | break; | ||
1114 | case Opt_hw_block_size: | 1141 | case Opt_hw_block_size: |
1115 | ret = tcmu_set_dev_attrib(&args[0], | 1142 | ret = tcmu_set_dev_attrib(&args[0], |
1116 | &(dev->dev_attrib.hw_block_size)); | 1143 | &(dev->dev_attrib.hw_block_size)); |
@@ -1138,7 +1165,9 @@ static ssize_t tcmu_show_configfs_dev_params(struct se_device *dev, char *b) | |||
1138 | 1165 | ||
1139 | bl = sprintf(b + bl, "Config: %s ", | 1166 | bl = sprintf(b + bl, "Config: %s ", |
1140 | udev->dev_config[0] ? udev->dev_config : "NULL"); | 1167 | udev->dev_config[0] ? udev->dev_config : "NULL"); |
1141 | bl += sprintf(b + bl, "Size: %zu\n", udev->dev_size); | 1168 | bl += sprintf(b + bl, "Size: %zu ", udev->dev_size); |
1169 | bl += sprintf(b + bl, "Cmd Time Out: %lu\n", | ||
1170 | udev->cmd_time_out / MSEC_PER_SEC); | ||
1142 | 1171 | ||
1143 | return bl; | 1172 | return bl; |
1144 | } | 1173 | } |