diff options
author | David Dillow <dillowda@ornl.gov> | 2011-01-14 18:23:24 -0500 |
---|---|---|
committer | David Dillow <dillowda@ornl.gov> | 2011-03-15 19:35:05 -0400 |
commit | 4924864404d0ce2c32a6d20b27b5b6fcb31e481d (patch) | |
tree | 2157ed7ed90b1fddf4013c560467082374d7c688 | |
parent | 961e0be89a5120a1409ebc525cca6f603615a8a8 (diff) |
IB/srp: allow sg_tablesize to be set for each target
Different configurations of target software allow differing max sizes of
the command IU. Allowing this to be changed per-target allows all
targets on an initiator to get an optimal setting.
We deprecate srp_sg_tablesize and replace it with cmd_sg_entries in
preparation for allowing more indirect descriptors than can fit in the
IU.
Signed-off-by: David Dillow <dillowda@ornl.gov>
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.c | 81 | ||||
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.h | 2 |
2 files changed, 59 insertions, 24 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 060e6a84f18f..6f8ee0c7ef5f 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -59,14 +59,16 @@ MODULE_DESCRIPTION("InfiniBand SCSI RDMA Protocol initiator " | |||
59 | "v" DRV_VERSION " (" DRV_RELDATE ")"); | 59 | "v" DRV_VERSION " (" DRV_RELDATE ")"); |
60 | MODULE_LICENSE("Dual BSD/GPL"); | 60 | MODULE_LICENSE("Dual BSD/GPL"); |
61 | 61 | ||
62 | static int srp_sg_tablesize = SRP_DEF_SG_TABLESIZE; | 62 | static unsigned int srp_sg_tablesize; |
63 | static int srp_max_iu_len; | 63 | static unsigned int cmd_sg_entries; |
64 | static int topspin_workarounds = 1; | ||
64 | 65 | ||
65 | module_param(srp_sg_tablesize, int, 0444); | 66 | module_param(srp_sg_tablesize, uint, 0444); |
66 | MODULE_PARM_DESC(srp_sg_tablesize, | 67 | MODULE_PARM_DESC(srp_sg_tablesize, "Deprecated name for cmd_sg_entries"); |
67 | "Max number of gather/scatter entries per I/O (default is 12, max 255)"); | ||
68 | 68 | ||
69 | static int topspin_workarounds = 1; | 69 | module_param(cmd_sg_entries, uint, 0444); |
70 | MODULE_PARM_DESC(cmd_sg_entries, | ||
71 | "Default number of gather/scatter entries in the SRP command (default is 12, max 255)"); | ||
70 | 72 | ||
71 | module_param(topspin_workarounds, int, 0444); | 73 | module_param(topspin_workarounds, int, 0444); |
72 | MODULE_PARM_DESC(topspin_workarounds, | 74 | MODULE_PARM_DESC(topspin_workarounds, |
@@ -364,7 +366,7 @@ static int srp_send_req(struct srp_target_port *target) | |||
364 | 366 | ||
365 | req->priv.opcode = SRP_LOGIN_REQ; | 367 | req->priv.opcode = SRP_LOGIN_REQ; |
366 | req->priv.tag = 0; | 368 | req->priv.tag = 0; |
367 | req->priv.req_it_iu_len = cpu_to_be32(srp_max_iu_len); | 369 | req->priv.req_it_iu_len = cpu_to_be32(target->max_iu_len); |
368 | req->priv.req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | | 370 | req->priv.req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | |
369 | SRP_BUF_FORMAT_INDIRECT); | 371 | SRP_BUF_FORMAT_INDIRECT); |
370 | /* | 372 | /* |
@@ -1125,7 +1127,7 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd) | |||
1125 | spin_unlock_irqrestore(&target->lock, flags); | 1127 | spin_unlock_irqrestore(&target->lock, flags); |
1126 | 1128 | ||
1127 | dev = target->srp_host->srp_dev->dev; | 1129 | dev = target->srp_host->srp_dev->dev; |
1128 | ib_dma_sync_single_for_cpu(dev, iu->dma, srp_max_iu_len, | 1130 | ib_dma_sync_single_for_cpu(dev, iu->dma, target->max_iu_len, |
1129 | DMA_TO_DEVICE); | 1131 | DMA_TO_DEVICE); |
1130 | 1132 | ||
1131 | scmnd->result = 0; | 1133 | scmnd->result = 0; |
@@ -1149,7 +1151,7 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd) | |||
1149 | goto err_iu; | 1151 | goto err_iu; |
1150 | } | 1152 | } |
1151 | 1153 | ||
1152 | ib_dma_sync_single_for_device(dev, iu->dma, srp_max_iu_len, | 1154 | ib_dma_sync_single_for_device(dev, iu->dma, target->max_iu_len, |
1153 | DMA_TO_DEVICE); | 1155 | DMA_TO_DEVICE); |
1154 | 1156 | ||
1155 | if (srp_post_send(target, iu, len)) { | 1157 | if (srp_post_send(target, iu, len)) { |
@@ -1189,7 +1191,7 @@ static int srp_alloc_iu_bufs(struct srp_target_port *target) | |||
1189 | 1191 | ||
1190 | for (i = 0; i < SRP_SQ_SIZE; ++i) { | 1192 | for (i = 0; i < SRP_SQ_SIZE; ++i) { |
1191 | target->tx_ring[i] = srp_alloc_iu(target->srp_host, | 1193 | target->tx_ring[i] = srp_alloc_iu(target->srp_host, |
1192 | srp_max_iu_len, | 1194 | target->max_iu_len, |
1193 | GFP_KERNEL, DMA_TO_DEVICE); | 1195 | GFP_KERNEL, DMA_TO_DEVICE); |
1194 | if (!target->tx_ring[i]) | 1196 | if (!target->tx_ring[i]) |
1195 | goto err; | 1197 | goto err; |
@@ -1645,6 +1647,14 @@ static ssize_t show_local_ib_device(struct device *dev, | |||
1645 | return sprintf(buf, "%s\n", target->srp_host->srp_dev->dev->name); | 1647 | return sprintf(buf, "%s\n", target->srp_host->srp_dev->dev->name); |
1646 | } | 1648 | } |
1647 | 1649 | ||
1650 | static ssize_t show_cmd_sg_entries(struct device *dev, | ||
1651 | struct device_attribute *attr, char *buf) | ||
1652 | { | ||
1653 | struct srp_target_port *target = host_to_target(class_to_shost(dev)); | ||
1654 | |||
1655 | return sprintf(buf, "%u\n", target->cmd_sg_cnt); | ||
1656 | } | ||
1657 | |||
1648 | static DEVICE_ATTR(id_ext, S_IRUGO, show_id_ext, NULL); | 1658 | static DEVICE_ATTR(id_ext, S_IRUGO, show_id_ext, NULL); |
1649 | static DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL); | 1659 | static DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL); |
1650 | static DEVICE_ATTR(service_id, S_IRUGO, show_service_id, NULL); | 1660 | static DEVICE_ATTR(service_id, S_IRUGO, show_service_id, NULL); |
@@ -1655,6 +1665,7 @@ static DEVICE_ATTR(req_lim, S_IRUGO, show_req_lim, NULL); | |||
1655 | static DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL); | 1665 | static DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL); |
1656 | static DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL); | 1666 | static DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL); |
1657 | static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL); | 1667 | static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL); |
1668 | static DEVICE_ATTR(cmd_sg_entries, S_IRUGO, show_cmd_sg_entries, NULL); | ||
1658 | 1669 | ||
1659 | static struct device_attribute *srp_host_attrs[] = { | 1670 | static struct device_attribute *srp_host_attrs[] = { |
1660 | &dev_attr_id_ext, | 1671 | &dev_attr_id_ext, |
@@ -1667,6 +1678,7 @@ static struct device_attribute *srp_host_attrs[] = { | |||
1667 | &dev_attr_zero_req_lim, | 1678 | &dev_attr_zero_req_lim, |
1668 | &dev_attr_local_ib_port, | 1679 | &dev_attr_local_ib_port, |
1669 | &dev_attr_local_ib_device, | 1680 | &dev_attr_local_ib_device, |
1681 | &dev_attr_cmd_sg_entries, | ||
1670 | NULL | 1682 | NULL |
1671 | }; | 1683 | }; |
1672 | 1684 | ||
@@ -1679,6 +1691,7 @@ static struct scsi_host_template srp_template = { | |||
1679 | .eh_abort_handler = srp_abort, | 1691 | .eh_abort_handler = srp_abort, |
1680 | .eh_device_reset_handler = srp_reset_device, | 1692 | .eh_device_reset_handler = srp_reset_device, |
1681 | .eh_host_reset_handler = srp_reset_host, | 1693 | .eh_host_reset_handler = srp_reset_host, |
1694 | .sg_tablesize = SRP_DEF_SG_TABLESIZE, | ||
1682 | .can_queue = SRP_CMD_SQ_SIZE, | 1695 | .can_queue = SRP_CMD_SQ_SIZE, |
1683 | .this_id = -1, | 1696 | .this_id = -1, |
1684 | .cmd_per_lun = SRP_CMD_SQ_SIZE, | 1697 | .cmd_per_lun = SRP_CMD_SQ_SIZE, |
@@ -1750,6 +1763,7 @@ enum { | |||
1750 | SRP_OPT_MAX_CMD_PER_LUN = 1 << 6, | 1763 | SRP_OPT_MAX_CMD_PER_LUN = 1 << 6, |
1751 | SRP_OPT_IO_CLASS = 1 << 7, | 1764 | SRP_OPT_IO_CLASS = 1 << 7, |
1752 | SRP_OPT_INITIATOR_EXT = 1 << 8, | 1765 | SRP_OPT_INITIATOR_EXT = 1 << 8, |
1766 | SRP_OPT_CMD_SG_ENTRIES = 1 << 9, | ||
1753 | SRP_OPT_ALL = (SRP_OPT_ID_EXT | | 1767 | SRP_OPT_ALL = (SRP_OPT_ID_EXT | |
1754 | SRP_OPT_IOC_GUID | | 1768 | SRP_OPT_IOC_GUID | |
1755 | SRP_OPT_DGID | | 1769 | SRP_OPT_DGID | |
@@ -1767,6 +1781,7 @@ static const match_table_t srp_opt_tokens = { | |||
1767 | { SRP_OPT_MAX_CMD_PER_LUN, "max_cmd_per_lun=%d" }, | 1781 | { SRP_OPT_MAX_CMD_PER_LUN, "max_cmd_per_lun=%d" }, |
1768 | { SRP_OPT_IO_CLASS, "io_class=%x" }, | 1782 | { SRP_OPT_IO_CLASS, "io_class=%x" }, |
1769 | { SRP_OPT_INITIATOR_EXT, "initiator_ext=%s" }, | 1783 | { SRP_OPT_INITIATOR_EXT, "initiator_ext=%s" }, |
1784 | { SRP_OPT_CMD_SG_ENTRIES, "cmd_sg_entries=%u" }, | ||
1770 | { SRP_OPT_ERR, NULL } | 1785 | { SRP_OPT_ERR, NULL } |
1771 | }; | 1786 | }; |
1772 | 1787 | ||
@@ -1894,6 +1909,14 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) | |||
1894 | kfree(p); | 1909 | kfree(p); |
1895 | break; | 1910 | break; |
1896 | 1911 | ||
1912 | case SRP_OPT_CMD_SG_ENTRIES: | ||
1913 | if (match_int(args, &token) || token < 1 || token > 255) { | ||
1914 | printk(KERN_WARNING PFX "bad max cmd_sg_entries parameter '%s'\n", p); | ||
1915 | goto out; | ||
1916 | } | ||
1917 | target->cmd_sg_cnt = token; | ||
1918 | break; | ||
1919 | |||
1897 | default: | 1920 | default: |
1898 | printk(KERN_WARNING PFX "unknown parameter or missing value " | 1921 | printk(KERN_WARNING PFX "unknown parameter or missing value " |
1899 | "'%s' in target creation request\n", p); | 1922 | "'%s' in target creation request\n", p); |
@@ -1932,17 +1955,18 @@ static ssize_t srp_create_target(struct device *dev, | |||
1932 | if (!target_host) | 1955 | if (!target_host) |
1933 | return -ENOMEM; | 1956 | return -ENOMEM; |
1934 | 1957 | ||
1935 | target_host->transportt = ib_srp_transport_template; | 1958 | target_host->transportt = ib_srp_transport_template; |
1936 | target_host->max_lun = SRP_MAX_LUN; | 1959 | target_host->max_lun = SRP_MAX_LUN; |
1937 | target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb; | 1960 | target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb; |
1938 | 1961 | ||
1939 | target = host_to_target(target_host); | 1962 | target = host_to_target(target_host); |
1940 | 1963 | ||
1941 | target->io_class = SRP_REV16A_IB_IO_CLASS; | 1964 | target->io_class = SRP_REV16A_IB_IO_CLASS; |
1942 | target->scsi_host = target_host; | 1965 | target->scsi_host = target_host; |
1943 | target->srp_host = host; | 1966 | target->srp_host = host; |
1944 | target->lkey = host->srp_dev->mr->lkey; | 1967 | target->lkey = host->srp_dev->mr->lkey; |
1945 | target->rkey = host->srp_dev->mr->rkey; | 1968 | target->rkey = host->srp_dev->mr->rkey; |
1969 | target->cmd_sg_cnt = cmd_sg_entries; | ||
1946 | 1970 | ||
1947 | spin_lock_init(&target->lock); | 1971 | spin_lock_init(&target->lock); |
1948 | INIT_LIST_HEAD(&target->free_tx); | 1972 | INIT_LIST_HEAD(&target->free_tx); |
@@ -1956,6 +1980,11 @@ static ssize_t srp_create_target(struct device *dev, | |||
1956 | if (ret) | 1980 | if (ret) |
1957 | goto err; | 1981 | goto err; |
1958 | 1982 | ||
1983 | target_host->sg_tablesize = target->cmd_sg_cnt; | ||
1984 | target->max_iu_len = sizeof (struct srp_cmd) + | ||
1985 | sizeof (struct srp_indirect_buf) + | ||
1986 | target->cmd_sg_cnt * sizeof (struct srp_direct_buf); | ||
1987 | |||
1959 | ib_query_gid(host->srp_dev->dev, host->port, 0, &target->path.sgid); | 1988 | ib_query_gid(host->srp_dev->dev, host->port, 0, &target->path.sgid); |
1960 | 1989 | ||
1961 | shost_printk(KERN_DEBUG, target->scsi_host, PFX | 1990 | shost_printk(KERN_DEBUG, target->scsi_host, PFX |
@@ -2217,9 +2246,18 @@ static int __init srp_init_module(void) | |||
2217 | 2246 | ||
2218 | BUILD_BUG_ON(FIELD_SIZEOF(struct ib_wc, wr_id) < sizeof(void *)); | 2247 | BUILD_BUG_ON(FIELD_SIZEOF(struct ib_wc, wr_id) < sizeof(void *)); |
2219 | 2248 | ||
2220 | if (srp_sg_tablesize > 255) { | 2249 | if (srp_sg_tablesize) { |
2221 | printk(KERN_WARNING PFX "Clamping srp_sg_tablesize to 255\n"); | 2250 | printk(KERN_WARNING PFX "srp_sg_tablesize is deprecated, please use cmd_sg_entries\n"); |
2222 | srp_sg_tablesize = 255; | 2251 | if (!cmd_sg_entries) |
2252 | cmd_sg_entries = srp_sg_tablesize; | ||
2253 | } | ||
2254 | |||
2255 | if (!cmd_sg_entries) | ||
2256 | cmd_sg_entries = SRP_DEF_SG_TABLESIZE; | ||
2257 | |||
2258 | if (cmd_sg_entries > 255) { | ||
2259 | printk(KERN_WARNING PFX "Clamping cmd_sg_entries to 255\n"); | ||
2260 | cmd_sg_entries = 255; | ||
2223 | } | 2261 | } |
2224 | 2262 | ||
2225 | ib_srp_transport_template = | 2263 | ib_srp_transport_template = |
@@ -2227,11 +2265,6 @@ static int __init srp_init_module(void) | |||
2227 | if (!ib_srp_transport_template) | 2265 | if (!ib_srp_transport_template) |
2228 | return -ENOMEM; | 2266 | return -ENOMEM; |
2229 | 2267 | ||
2230 | srp_template.sg_tablesize = srp_sg_tablesize; | ||
2231 | srp_max_iu_len = (sizeof (struct srp_cmd) + | ||
2232 | sizeof (struct srp_indirect_buf) + | ||
2233 | srp_sg_tablesize * 16); | ||
2234 | |||
2235 | ret = class_register(&srp_class); | 2268 | ret = class_register(&srp_class); |
2236 | if (ret) { | 2269 | if (ret) { |
2237 | printk(KERN_ERR PFX "couldn't register class infiniband_srp\n"); | 2270 | printk(KERN_ERR PFX "couldn't register class infiniband_srp\n"); |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index 9dc6fc3fd894..db39dbf76216 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h | |||
@@ -130,6 +130,8 @@ struct srp_target_port { | |||
130 | u32 lkey; | 130 | u32 lkey; |
131 | u32 rkey; | 131 | u32 rkey; |
132 | enum srp_target_state state; | 132 | enum srp_target_state state; |
133 | unsigned int max_iu_len; | ||
134 | unsigned int cmd_sg_cnt; | ||
133 | 135 | ||
134 | /* Everything above this point is used in the hot path of | 136 | /* Everything above this point is used in the hot path of |
135 | * command processing. Try to keep them packed into cachelines. | 137 | * command processing. Try to keep them packed into cachelines. |