summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Christie <mchristi@redhat.com>2017-03-09 03:42:09 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2017-03-18 19:32:27 -0400
commitaf980e46a26ac8805685bb70c8572dbc47abb126 (patch)
tree68fb80c55ec73bedb428cd33ccf7685dbf07aa43
parent972c7f167974fa41ea8a2eed4b857cc59f59c42c (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.c41
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
1038enum { 1047enum {
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
1043static match_table_t tokens = { 1052static 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}