diff options
author | David Dillow <dillowda@ornl.gov> | 2011-01-16 13:57:10 -0500 |
---|---|---|
committer | David Dillow <dillowda@ornl.gov> | 2011-03-15 19:37:23 -0400 |
commit | c07d424d6118d528ef71b22b7424bfc359c307a5 (patch) | |
tree | 1d61da8aea0fa80c2c7bc13b03d15ddb470bcfa6 /drivers | |
parent | 8f26c9ff9cd0317ad867bce972f69e0c6c2cbe3c (diff) |
IB/srp: add support for indirect tables that don't fit in SRP_CMD
This allows us to guarantee the ability to submit up to 8 MB requests
based on the current value of SCSI_MAX_SG_CHAIN_SEGMENTS. While FMR will
usually condense the requests into 8 SG entries, it is imperative that
the target support external tables in case the FMR mapping fails or is
not supported.
We add a safety valve to allow targets without the needed support to
reap the benefits of the large tables, but fail in a manner that lets
the user know that the data didn't make it to the device. The user must
add "allow_ext_sg=1" to the target parameters to indicate that the
target has the needed support.
If indirect_sg_entries is not specified in the modules options, then
the sg_tablesize for the target will default to cmd_sg_entries unless
overridden by the target options.
Signed-off-by: David Dillow <dillowda@ornl.gov>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.c | 117 | ||||
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.h | 5 |
2 files changed, 110 insertions, 12 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 9ce129ab3beb..4ec7dddbbf49 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -61,6 +61,8 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
61 | 61 | ||
62 | static unsigned int srp_sg_tablesize; | 62 | static unsigned int srp_sg_tablesize; |
63 | static unsigned int cmd_sg_entries; | 63 | static unsigned int cmd_sg_entries; |
64 | static unsigned int indirect_sg_entries; | ||
65 | static bool allow_ext_sg; | ||
64 | static int topspin_workarounds = 1; | 66 | static int topspin_workarounds = 1; |
65 | 67 | ||
66 | module_param(srp_sg_tablesize, uint, 0444); | 68 | module_param(srp_sg_tablesize, uint, 0444); |
@@ -70,6 +72,14 @@ module_param(cmd_sg_entries, uint, 0444); | |||
70 | MODULE_PARM_DESC(cmd_sg_entries, | 72 | MODULE_PARM_DESC(cmd_sg_entries, |
71 | "Default number of gather/scatter entries in the SRP command (default is 12, max 255)"); | 73 | "Default number of gather/scatter entries in the SRP command (default is 12, max 255)"); |
72 | 74 | ||
75 | module_param(indirect_sg_entries, uint, 0444); | ||
76 | MODULE_PARM_DESC(indirect_sg_entries, | ||
77 | "Default max number of gather/scatter entries (default is 12, max is " __stringify(SCSI_MAX_SG_CHAIN_SEGMENTS) ")"); | ||
78 | |||
79 | module_param(allow_ext_sg, bool, 0444); | ||
80 | MODULE_PARM_DESC(allow_ext_sg, | ||
81 | "Default behavior when there are more than cmd_sg_entries S/G entries after mapping; fails the request when false (default false)"); | ||
82 | |||
73 | module_param(topspin_workarounds, int, 0444); | 83 | module_param(topspin_workarounds, int, 0444); |
74 | MODULE_PARM_DESC(topspin_workarounds, | 84 | MODULE_PARM_DESC(topspin_workarounds, |
75 | "Enable workarounds for Topspin/Cisco SRP target bugs if != 0"); | 85 | "Enable workarounds for Topspin/Cisco SRP target bugs if != 0"); |
@@ -446,12 +456,19 @@ static bool srp_change_state(struct srp_target_port *target, | |||
446 | 456 | ||
447 | static void srp_free_req_data(struct srp_target_port *target) | 457 | static void srp_free_req_data(struct srp_target_port *target) |
448 | { | 458 | { |
459 | struct ib_device *ibdev = target->srp_host->srp_dev->dev; | ||
449 | struct srp_request *req; | 460 | struct srp_request *req; |
450 | int i; | 461 | int i; |
451 | 462 | ||
452 | for (i = 0, req = target->req_ring; i < SRP_CMD_SQ_SIZE; ++i, ++req) { | 463 | for (i = 0, req = target->req_ring; i < SRP_CMD_SQ_SIZE; ++i, ++req) { |
453 | kfree(req->fmr_list); | 464 | kfree(req->fmr_list); |
454 | kfree(req->map_page); | 465 | kfree(req->map_page); |
466 | if (req->indirect_dma_addr) { | ||
467 | ib_dma_unmap_single(ibdev, req->indirect_dma_addr, | ||
468 | target->indirect_size, | ||
469 | DMA_TO_DEVICE); | ||
470 | } | ||
471 | kfree(req->indirect_desc); | ||
455 | } | 472 | } |
456 | } | 473 | } |
457 | 474 | ||
@@ -790,7 +807,6 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, | |||
790 | struct ib_device *ibdev; | 807 | struct ib_device *ibdev; |
791 | struct srp_map_state state; | 808 | struct srp_map_state state; |
792 | struct srp_indirect_buf *indirect_hdr; | 809 | struct srp_indirect_buf *indirect_hdr; |
793 | dma_addr_t indirect_addr; | ||
794 | u32 table_len; | 810 | u32 table_len; |
795 | u8 fmt; | 811 | u8 fmt; |
796 | 812 | ||
@@ -841,8 +857,11 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, | |||
841 | */ | 857 | */ |
842 | indirect_hdr = (void *) cmd->add_data; | 858 | indirect_hdr = (void *) cmd->add_data; |
843 | 859 | ||
860 | ib_dma_sync_single_for_cpu(ibdev, req->indirect_dma_addr, | ||
861 | target->indirect_size, DMA_TO_DEVICE); | ||
862 | |||
844 | memset(&state, 0, sizeof(state)); | 863 | memset(&state, 0, sizeof(state)); |
845 | state.desc = indirect_hdr->desc_list; | 864 | state.desc = req->indirect_desc; |
846 | state.pages = req->map_page; | 865 | state.pages = req->map_page; |
847 | state.next_fmr = req->fmr_list; | 866 | state.next_fmr = req->fmr_list; |
848 | 867 | ||
@@ -872,7 +891,11 @@ backtrack: | |||
872 | if (use_fmr == SRP_MAP_ALLOW_FMR && srp_map_finish_fmr(&state, target)) | 891 | if (use_fmr == SRP_MAP_ALLOW_FMR && srp_map_finish_fmr(&state, target)) |
873 | goto backtrack; | 892 | goto backtrack; |
874 | 893 | ||
875 | /* We've mapped the request, fill in the command buffer. | 894 | /* We've mapped the request, now pull as much of the indirect |
895 | * descriptor table as we can into the command buffer. If this | ||
896 | * target is not using an external indirect table, we are | ||
897 | * guaranteed to fit into the command, as the SCSI layer won't | ||
898 | * give us more S/G entries than we allow. | ||
876 | */ | 899 | */ |
877 | req->nfmr = state.nfmr; | 900 | req->nfmr = state.nfmr; |
878 | if (state.ndesc == 1) { | 901 | if (state.ndesc == 1) { |
@@ -881,27 +904,39 @@ backtrack: | |||
881 | */ | 904 | */ |
882 | struct srp_direct_buf *buf = (void *) cmd->add_data; | 905 | struct srp_direct_buf *buf = (void *) cmd->add_data; |
883 | 906 | ||
884 | *buf = indirect_hdr->desc_list[0]; | 907 | *buf = req->indirect_desc[0]; |
885 | goto map_complete; | 908 | goto map_complete; |
886 | } | 909 | } |
887 | 910 | ||
911 | if (unlikely(target->cmd_sg_cnt < state.ndesc && | ||
912 | !target->allow_ext_sg)) { | ||
913 | shost_printk(KERN_ERR, target->scsi_host, | ||
914 | "Could not fit S/G list into SRP_CMD\n"); | ||
915 | return -EIO; | ||
916 | } | ||
917 | |||
918 | count = min(state.ndesc, target->cmd_sg_cnt); | ||
888 | table_len = state.ndesc * sizeof (struct srp_direct_buf); | 919 | table_len = state.ndesc * sizeof (struct srp_direct_buf); |
889 | 920 | ||
890 | fmt = SRP_DATA_DESC_INDIRECT; | 921 | fmt = SRP_DATA_DESC_INDIRECT; |
891 | len = sizeof(struct srp_cmd) + sizeof (struct srp_indirect_buf); | 922 | len = sizeof(struct srp_cmd) + sizeof (struct srp_indirect_buf); |
892 | len += table_len; | 923 | len += count * sizeof (struct srp_direct_buf); |
893 | 924 | ||
894 | indirect_addr = req->cmd->dma + sizeof *cmd + sizeof *indirect_hdr; | 925 | memcpy(indirect_hdr->desc_list, req->indirect_desc, |
926 | count * sizeof (struct srp_direct_buf)); | ||
895 | 927 | ||
896 | indirect_hdr->table_desc.va = cpu_to_be64(indirect_addr); | 928 | indirect_hdr->table_desc.va = cpu_to_be64(req->indirect_dma_addr); |
897 | indirect_hdr->table_desc.key = cpu_to_be32(target->rkey); | 929 | indirect_hdr->table_desc.key = cpu_to_be32(target->rkey); |
898 | indirect_hdr->table_desc.len = cpu_to_be32(table_len); | 930 | indirect_hdr->table_desc.len = cpu_to_be32(table_len); |
899 | indirect_hdr->len = cpu_to_be32(state.total_len); | 931 | indirect_hdr->len = cpu_to_be32(state.total_len); |
900 | 932 | ||
901 | if (scmnd->sc_data_direction == DMA_TO_DEVICE) | 933 | if (scmnd->sc_data_direction == DMA_TO_DEVICE) |
902 | cmd->data_out_desc_cnt = state.ndesc; | 934 | cmd->data_out_desc_cnt = count; |
903 | else | 935 | else |
904 | cmd->data_in_desc_cnt = state.ndesc; | 936 | cmd->data_in_desc_cnt = count; |
937 | |||
938 | ib_dma_sync_single_for_device(ibdev, req->indirect_dma_addr, table_len, | ||
939 | DMA_TO_DEVICE); | ||
905 | 940 | ||
906 | map_complete: | 941 | map_complete: |
907 | if (scmnd->sc_data_direction == DMA_TO_DEVICE) | 942 | if (scmnd->sc_data_direction == DMA_TO_DEVICE) |
@@ -1759,6 +1794,14 @@ static ssize_t show_cmd_sg_entries(struct device *dev, | |||
1759 | return sprintf(buf, "%u\n", target->cmd_sg_cnt); | 1794 | return sprintf(buf, "%u\n", target->cmd_sg_cnt); |
1760 | } | 1795 | } |
1761 | 1796 | ||
1797 | static ssize_t show_allow_ext_sg(struct device *dev, | ||
1798 | struct device_attribute *attr, char *buf) | ||
1799 | { | ||
1800 | struct srp_target_port *target = host_to_target(class_to_shost(dev)); | ||
1801 | |||
1802 | return sprintf(buf, "%s\n", target->allow_ext_sg ? "true" : "false"); | ||
1803 | } | ||
1804 | |||
1762 | static DEVICE_ATTR(id_ext, S_IRUGO, show_id_ext, NULL); | 1805 | static DEVICE_ATTR(id_ext, S_IRUGO, show_id_ext, NULL); |
1763 | static DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL); | 1806 | static DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL); |
1764 | static DEVICE_ATTR(service_id, S_IRUGO, show_service_id, NULL); | 1807 | static DEVICE_ATTR(service_id, S_IRUGO, show_service_id, NULL); |
@@ -1770,6 +1813,7 @@ static DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL); | |||
1770 | static DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL); | 1813 | static DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL); |
1771 | static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL); | 1814 | static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL); |
1772 | static DEVICE_ATTR(cmd_sg_entries, S_IRUGO, show_cmd_sg_entries, NULL); | 1815 | static DEVICE_ATTR(cmd_sg_entries, S_IRUGO, show_cmd_sg_entries, NULL); |
1816 | static DEVICE_ATTR(allow_ext_sg, S_IRUGO, show_allow_ext_sg, NULL); | ||
1773 | 1817 | ||
1774 | static struct device_attribute *srp_host_attrs[] = { | 1818 | static struct device_attribute *srp_host_attrs[] = { |
1775 | &dev_attr_id_ext, | 1819 | &dev_attr_id_ext, |
@@ -1783,6 +1827,7 @@ static struct device_attribute *srp_host_attrs[] = { | |||
1783 | &dev_attr_local_ib_port, | 1827 | &dev_attr_local_ib_port, |
1784 | &dev_attr_local_ib_device, | 1828 | &dev_attr_local_ib_device, |
1785 | &dev_attr_cmd_sg_entries, | 1829 | &dev_attr_cmd_sg_entries, |
1830 | &dev_attr_allow_ext_sg, | ||
1786 | NULL | 1831 | NULL |
1787 | }; | 1832 | }; |
1788 | 1833 | ||
@@ -1868,6 +1913,8 @@ enum { | |||
1868 | SRP_OPT_IO_CLASS = 1 << 7, | 1913 | SRP_OPT_IO_CLASS = 1 << 7, |
1869 | SRP_OPT_INITIATOR_EXT = 1 << 8, | 1914 | SRP_OPT_INITIATOR_EXT = 1 << 8, |
1870 | SRP_OPT_CMD_SG_ENTRIES = 1 << 9, | 1915 | SRP_OPT_CMD_SG_ENTRIES = 1 << 9, |
1916 | SRP_OPT_ALLOW_EXT_SG = 1 << 10, | ||
1917 | SRP_OPT_SG_TABLESIZE = 1 << 11, | ||
1871 | SRP_OPT_ALL = (SRP_OPT_ID_EXT | | 1918 | SRP_OPT_ALL = (SRP_OPT_ID_EXT | |
1872 | SRP_OPT_IOC_GUID | | 1919 | SRP_OPT_IOC_GUID | |
1873 | SRP_OPT_DGID | | 1920 | SRP_OPT_DGID | |
@@ -1886,6 +1933,8 @@ static const match_table_t srp_opt_tokens = { | |||
1886 | { SRP_OPT_IO_CLASS, "io_class=%x" }, | 1933 | { SRP_OPT_IO_CLASS, "io_class=%x" }, |
1887 | { SRP_OPT_INITIATOR_EXT, "initiator_ext=%s" }, | 1934 | { SRP_OPT_INITIATOR_EXT, "initiator_ext=%s" }, |
1888 | { SRP_OPT_CMD_SG_ENTRIES, "cmd_sg_entries=%u" }, | 1935 | { SRP_OPT_CMD_SG_ENTRIES, "cmd_sg_entries=%u" }, |
1936 | { SRP_OPT_ALLOW_EXT_SG, "allow_ext_sg=%u" }, | ||
1937 | { SRP_OPT_SG_TABLESIZE, "sg_tablesize=%u" }, | ||
1889 | { SRP_OPT_ERR, NULL } | 1938 | { SRP_OPT_ERR, NULL } |
1890 | }; | 1939 | }; |
1891 | 1940 | ||
@@ -2021,6 +2070,23 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) | |||
2021 | target->cmd_sg_cnt = token; | 2070 | target->cmd_sg_cnt = token; |
2022 | break; | 2071 | break; |
2023 | 2072 | ||
2073 | case SRP_OPT_ALLOW_EXT_SG: | ||
2074 | if (match_int(args, &token)) { | ||
2075 | printk(KERN_WARNING PFX "bad allow_ext_sg parameter '%s'\n", p); | ||
2076 | goto out; | ||
2077 | } | ||
2078 | target->allow_ext_sg = !!token; | ||
2079 | break; | ||
2080 | |||
2081 | case SRP_OPT_SG_TABLESIZE: | ||
2082 | if (match_int(args, &token) || token < 1 || | ||
2083 | token > SCSI_MAX_SG_CHAIN_SEGMENTS) { | ||
2084 | printk(KERN_WARNING PFX "bad max sg_tablesize parameter '%s'\n", p); | ||
2085 | goto out; | ||
2086 | } | ||
2087 | target->sg_tablesize = token; | ||
2088 | break; | ||
2089 | |||
2024 | default: | 2090 | default: |
2025 | printk(KERN_WARNING PFX "unknown parameter or missing value " | 2091 | printk(KERN_WARNING PFX "unknown parameter or missing value " |
2026 | "'%s' in target creation request\n", p); | 2092 | "'%s' in target creation request\n", p); |
@@ -2051,6 +2117,8 @@ static ssize_t srp_create_target(struct device *dev, | |||
2051 | container_of(dev, struct srp_host, dev); | 2117 | container_of(dev, struct srp_host, dev); |
2052 | struct Scsi_Host *target_host; | 2118 | struct Scsi_Host *target_host; |
2053 | struct srp_target_port *target; | 2119 | struct srp_target_port *target; |
2120 | struct ib_device *ibdev = host->srp_dev->dev; | ||
2121 | dma_addr_t dma_addr; | ||
2054 | int i, ret; | 2122 | int i, ret; |
2055 | 2123 | ||
2056 | target_host = scsi_host_alloc(&srp_template, | 2124 | target_host = scsi_host_alloc(&srp_template, |
@@ -2070,12 +2138,22 @@ static ssize_t srp_create_target(struct device *dev, | |||
2070 | target->lkey = host->srp_dev->mr->lkey; | 2138 | target->lkey = host->srp_dev->mr->lkey; |
2071 | target->rkey = host->srp_dev->mr->rkey; | 2139 | target->rkey = host->srp_dev->mr->rkey; |
2072 | target->cmd_sg_cnt = cmd_sg_entries; | 2140 | target->cmd_sg_cnt = cmd_sg_entries; |
2141 | target->sg_tablesize = indirect_sg_entries ? : cmd_sg_entries; | ||
2142 | target->allow_ext_sg = allow_ext_sg; | ||
2073 | 2143 | ||
2074 | ret = srp_parse_options(buf, target); | 2144 | ret = srp_parse_options(buf, target); |
2075 | if (ret) | 2145 | if (ret) |
2076 | goto err; | 2146 | goto err; |
2077 | 2147 | ||
2078 | target_host->sg_tablesize = target->cmd_sg_cnt; | 2148 | if (!host->srp_dev->fmr_pool && !target->allow_ext_sg && |
2149 | target->cmd_sg_cnt < target->sg_tablesize) { | ||
2150 | printk(KERN_WARNING PFX "No FMR pool and no external indirect descriptors, limiting sg_tablesize to cmd_sg_cnt\n"); | ||
2151 | target->sg_tablesize = target->cmd_sg_cnt; | ||
2152 | } | ||
2153 | |||
2154 | target_host->sg_tablesize = target->sg_tablesize; | ||
2155 | target->indirect_size = target->sg_tablesize * | ||
2156 | sizeof (struct srp_direct_buf); | ||
2079 | target->max_iu_len = sizeof (struct srp_cmd) + | 2157 | target->max_iu_len = sizeof (struct srp_cmd) + |
2080 | sizeof (struct srp_indirect_buf) + | 2158 | sizeof (struct srp_indirect_buf) + |
2081 | target->cmd_sg_cnt * sizeof (struct srp_direct_buf); | 2159 | target->cmd_sg_cnt * sizeof (struct srp_direct_buf); |
@@ -2090,14 +2168,22 @@ static ssize_t srp_create_target(struct device *dev, | |||
2090 | GFP_KERNEL); | 2168 | GFP_KERNEL); |
2091 | req->map_page = kmalloc(SRP_FMR_SIZE * sizeof (void *), | 2169 | req->map_page = kmalloc(SRP_FMR_SIZE * sizeof (void *), |
2092 | GFP_KERNEL); | 2170 | GFP_KERNEL); |
2093 | if (!req->fmr_list || !req->map_page) | 2171 | req->indirect_desc = kmalloc(target->indirect_size, GFP_KERNEL); |
2172 | if (!req->fmr_list || !req->map_page || !req->indirect_desc) | ||
2094 | goto err_free_mem; | 2173 | goto err_free_mem; |
2095 | 2174 | ||
2175 | dma_addr = ib_dma_map_single(ibdev, req->indirect_desc, | ||
2176 | target->indirect_size, | ||
2177 | DMA_TO_DEVICE); | ||
2178 | if (ib_dma_mapping_error(ibdev, dma_addr)) | ||
2179 | goto err_free_mem; | ||
2180 | |||
2181 | req->indirect_dma_addr = dma_addr; | ||
2096 | req->index = i; | 2182 | req->index = i; |
2097 | list_add_tail(&req->list, &target->free_reqs); | 2183 | list_add_tail(&req->list, &target->free_reqs); |
2098 | } | 2184 | } |
2099 | 2185 | ||
2100 | ib_query_gid(host->srp_dev->dev, host->port, 0, &target->path.sgid); | 2186 | ib_query_gid(ibdev, host->port, 0, &target->path.sgid); |
2101 | 2187 | ||
2102 | shost_printk(KERN_DEBUG, target->scsi_host, PFX | 2188 | shost_printk(KERN_DEBUG, target->scsi_host, PFX |
2103 | "new target: id_ext %016llx ioc_guid %016llx pkey %04x " | 2189 | "new target: id_ext %016llx ioc_guid %016llx pkey %04x " |
@@ -2377,6 +2463,13 @@ static int __init srp_init_module(void) | |||
2377 | cmd_sg_entries = 255; | 2463 | cmd_sg_entries = 255; |
2378 | } | 2464 | } |
2379 | 2465 | ||
2466 | if (!indirect_sg_entries) | ||
2467 | indirect_sg_entries = cmd_sg_entries; | ||
2468 | else if (indirect_sg_entries < cmd_sg_entries) { | ||
2469 | printk(KERN_WARNING PFX "Bumping up indirect_sg_entries to match cmd_sg_entries (%u)\n", cmd_sg_entries); | ||
2470 | indirect_sg_entries = cmd_sg_entries; | ||
2471 | } | ||
2472 | |||
2380 | ib_srp_transport_template = | 2473 | ib_srp_transport_template = |
2381 | srp_attach_transport(&ib_srp_transport_functions); | 2474 | srp_attach_transport(&ib_srp_transport_functions); |
2382 | if (!ib_srp_transport_template) | 2475 | if (!ib_srp_transport_template) |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index b43b5e7acbde..cf696218eeeb 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h | |||
@@ -117,6 +117,8 @@ struct srp_request { | |||
117 | struct srp_iu *cmd; | 117 | struct srp_iu *cmd; |
118 | struct ib_pool_fmr **fmr_list; | 118 | struct ib_pool_fmr **fmr_list; |
119 | u64 *map_page; | 119 | u64 *map_page; |
120 | struct srp_direct_buf *indirect_desc; | ||
121 | dma_addr_t indirect_dma_addr; | ||
120 | short nfmr; | 122 | short nfmr; |
121 | short index; | 123 | short index; |
122 | }; | 124 | }; |
@@ -137,6 +139,8 @@ struct srp_target_port { | |||
137 | enum srp_target_state state; | 139 | enum srp_target_state state; |
138 | unsigned int max_iu_len; | 140 | unsigned int max_iu_len; |
139 | unsigned int cmd_sg_cnt; | 141 | unsigned int cmd_sg_cnt; |
142 | unsigned int indirect_size; | ||
143 | bool allow_ext_sg; | ||
140 | 144 | ||
141 | /* Everything above this point is used in the hot path of | 145 | /* Everything above this point is used in the hot path of |
142 | * command processing. Try to keep them packed into cachelines. | 146 | * command processing. Try to keep them packed into cachelines. |
@@ -151,6 +155,7 @@ struct srp_target_port { | |||
151 | struct Scsi_Host *scsi_host; | 155 | struct Scsi_Host *scsi_host; |
152 | char target_name[32]; | 156 | char target_name[32]; |
153 | unsigned int scsi_id; | 157 | unsigned int scsi_id; |
158 | unsigned int sg_tablesize; | ||
154 | 159 | ||
155 | struct ib_sa_path_rec path; | 160 | struct ib_sa_path_rec path; |
156 | __be16 orig_dgid[8]; | 161 | __be16 orig_dgid[8]; |