Hannes,
In megasas_change_queue_type(), is it possible for sdev->queue_depth to
be greater than 256?
Unless I'm misunderstanding the SCSI code, we can request a
queue-depth/tag-map-size which is greater than 256, but, since the
scsi_cmnd::tag field is an unsigned char, depths greater than 256 may
overflow the field when high-numbered tags are used...do I have that right?
Thanks,
Webb
On 9/29/14 7:47 AM, Hannes Reinecke wrote:
Megaraid_sas uses a shared pool of commands per HBA, so we
should be enabling a shared tag map.
This will allow the I/O scheduler to make better scheduling
decisions and will avoid BUSY states in the driver.
Signed-off-by: Hannes Reinecke <hare@xxxxxxx>
---
drivers/scsi/megaraid/megaraid_sas_base.c | 34 ++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index f6a69a3..996fa9a 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1659,7 +1659,7 @@ static int megasas_slave_configure(struct scsi_device *sdev)
*/
blk_queue_rq_timeout(sdev->request_queue,
MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
-
+ sdev->tagged_supported = 1;
return 0;
}
@@ -1667,6 +1667,10 @@ static int megasas_slave_alloc(struct scsi_device *sdev)
{
u16 pd_index = 0;
struct megasas_instance *instance ;
+
+ /* We have a shared tag map, so TCQ is always supported */
+ sdev->tagged_supported = 1;
+
instance = megasas_lookup_instance(sdev->host->host_no);
if (sdev->channel < MEGASAS_MAX_PD_CHANNELS) {
/*
@@ -1677,13 +1681,20 @@ static int megasas_slave_alloc(struct scsi_device *sdev)
sdev->id;
if (instance->pd_list[pd_index].driveState ==
MR_PD_STATE_SYSTEM) {
+ scsi_activate_tcq(sdev, MEGASAS_DEFAULT_CMD_PER_LUN);
return 0;
}
return -ENXIO;
}
+ scsi_activate_tcq(sdev, MEGASAS_DEFAULT_CMD_PER_LUN);
return 0;
}
+static void megasas_slave_destroy(struct scsi_device *sdev)
+{
+ scsi_deactivate_tcq(sdev, 1);
+}
+
void megaraid_sas_kill_hba(struct megasas_instance *instance)
{
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
@@ -2746,6 +2757,21 @@ struct device_attribute *megaraid_host_attrs[] = {
NULL,
};
+static int megasas_change_queue_type(struct scsi_device *sdev, int tag_type)
+{
+ if (sdev->host->bqt && sdev->tagged_supported) {
+ scsi_set_tag_type(sdev, tag_type);
+
+ if (tag_type)
+ scsi_activate_tcq(sdev, sdev->queue_depth);
+ else
+ scsi_deactivate_tcq(sdev, sdev->queue_depth);
+ } else
+ tag_type = 0;
+
+ return tag_type;
+}
+
/*
* Scsi host template for megaraid_sas driver
*/
@@ -2756,6 +2782,7 @@ static struct scsi_host_template megasas_template = {
.proc_name = "megaraid_sas",
.slave_configure = megasas_slave_configure,
.slave_alloc = megasas_slave_alloc,
+ .slave_destroy = megasas_slave_destroy,
.queuecommand = megasas_queue_command,
.eh_device_reset_handler = megasas_reset_device,
.eh_bus_reset_handler = megasas_reset_bus_host,
@@ -2765,6 +2792,7 @@ static struct scsi_host_template megasas_template = {
.bios_param = megasas_bios_param,
.use_clustering = ENABLE_CLUSTERING,
.change_queue_depth = megasas_change_queue_depth,
+ .change_queue_type = megasas_change_queue_type,
.no_write_same = 1,
};
@@ -4909,6 +4937,10 @@ static int megasas_io_attach(struct megasas_instance *instance)
host->this_id = instance->init_id;
host->sg_tablesize = instance->max_num_sge;
+ if (!scsi_init_shared_tag_map(host, host->can_queue))
+ printk(KERN_WARNING "megasas: enable TCQ support, depth %d",
+ host->can_queue);
+
if (instance->fw_support_ieee)
instance->max_sectors_per_req = MEGASAS_MAX_SECTORS_IEEE;
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html