aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorBart Van Assche <bvanassche@acm.org>2013-06-28 08:57:42 -0400
committerRoland Dreier <roland@purestorage.com>2013-07-01 13:40:55 -0400
commit4b5e5f41c8e114bb856347134657eb9e1cccc822 (patch)
treecdca03a8d34e6c190b021a54c98925eaf1330c7c /drivers/infiniband
parent96fc248a4c6fe1e5ffac4903b39d2dd5cbe2dc9a (diff)
IB/srp: Make HCA completion vector configurable
Several InfiniBand HCAs allow configuring the completion vector per CQ. This allows spreading the workload created by IB completion interrupts over multiple MSI-X vectors and hence over multiple CPU cores. In other words, configuring the completion vector properly not only allows reducing latency on an initiator connected to multiple SRP targets but also allows improving throughput. Signed-off-by: Bart Van Assche <bvanassche@acm.org> Acked-by: David Dillow <dillowda@ornl.gov> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c26
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.h1
2 files changed, 25 insertions, 2 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 830ef0037087..9b30366cb017 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -231,14 +231,16 @@ static int srp_create_target_ib(struct srp_target_port *target)
231 return -ENOMEM; 231 return -ENOMEM;
232 232
233 recv_cq = ib_create_cq(target->srp_host->srp_dev->dev, 233 recv_cq = ib_create_cq(target->srp_host->srp_dev->dev,
234 srp_recv_completion, NULL, target, SRP_RQ_SIZE, 0); 234 srp_recv_completion, NULL, target, SRP_RQ_SIZE,
235 target->comp_vector);
235 if (IS_ERR(recv_cq)) { 236 if (IS_ERR(recv_cq)) {
236 ret = PTR_ERR(recv_cq); 237 ret = PTR_ERR(recv_cq);
237 goto err; 238 goto err;
238 } 239 }
239 240
240 send_cq = ib_create_cq(target->srp_host->srp_dev->dev, 241 send_cq = ib_create_cq(target->srp_host->srp_dev->dev,
241 srp_send_completion, NULL, target, SRP_SQ_SIZE, 0); 242 srp_send_completion, NULL, target, SRP_SQ_SIZE,
243 target->comp_vector);
242 if (IS_ERR(send_cq)) { 244 if (IS_ERR(send_cq)) {
243 ret = PTR_ERR(send_cq); 245 ret = PTR_ERR(send_cq);
244 goto err_recv_cq; 246 goto err_recv_cq;
@@ -1898,6 +1900,14 @@ static ssize_t show_local_ib_device(struct device *dev,
1898 return sprintf(buf, "%s\n", target->srp_host->srp_dev->dev->name); 1900 return sprintf(buf, "%s\n", target->srp_host->srp_dev->dev->name);
1899} 1901}
1900 1902
1903static ssize_t show_comp_vector(struct device *dev,
1904 struct device_attribute *attr, char *buf)
1905{
1906 struct srp_target_port *target = host_to_target(class_to_shost(dev));
1907
1908 return sprintf(buf, "%d\n", target->comp_vector);
1909}
1910
1901static ssize_t show_cmd_sg_entries(struct device *dev, 1911static ssize_t show_cmd_sg_entries(struct device *dev,
1902 struct device_attribute *attr, char *buf) 1912 struct device_attribute *attr, char *buf)
1903{ 1913{
@@ -1924,6 +1934,7 @@ static DEVICE_ATTR(req_lim, S_IRUGO, show_req_lim, NULL);
1924static DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL); 1934static DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL);
1925static DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL); 1935static DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL);
1926static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL); 1936static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL);
1937static DEVICE_ATTR(comp_vector, S_IRUGO, show_comp_vector, NULL);
1927static DEVICE_ATTR(cmd_sg_entries, S_IRUGO, show_cmd_sg_entries, NULL); 1938static DEVICE_ATTR(cmd_sg_entries, S_IRUGO, show_cmd_sg_entries, NULL);
1928static DEVICE_ATTR(allow_ext_sg, S_IRUGO, show_allow_ext_sg, NULL); 1939static DEVICE_ATTR(allow_ext_sg, S_IRUGO, show_allow_ext_sg, NULL);
1929 1940
@@ -1938,6 +1949,7 @@ static struct device_attribute *srp_host_attrs[] = {
1938 &dev_attr_zero_req_lim, 1949 &dev_attr_zero_req_lim,
1939 &dev_attr_local_ib_port, 1950 &dev_attr_local_ib_port,
1940 &dev_attr_local_ib_device, 1951 &dev_attr_local_ib_device,
1952 &dev_attr_comp_vector,
1941 &dev_attr_cmd_sg_entries, 1953 &dev_attr_cmd_sg_entries,
1942 &dev_attr_allow_ext_sg, 1954 &dev_attr_allow_ext_sg,
1943 NULL 1955 NULL
@@ -2061,6 +2073,7 @@ enum {
2061 SRP_OPT_CMD_SG_ENTRIES = 1 << 9, 2073 SRP_OPT_CMD_SG_ENTRIES = 1 << 9,
2062 SRP_OPT_ALLOW_EXT_SG = 1 << 10, 2074 SRP_OPT_ALLOW_EXT_SG = 1 << 10,
2063 SRP_OPT_SG_TABLESIZE = 1 << 11, 2075 SRP_OPT_SG_TABLESIZE = 1 << 11,
2076 SRP_OPT_COMP_VECTOR = 1 << 12,
2064 SRP_OPT_ALL = (SRP_OPT_ID_EXT | 2077 SRP_OPT_ALL = (SRP_OPT_ID_EXT |
2065 SRP_OPT_IOC_GUID | 2078 SRP_OPT_IOC_GUID |
2066 SRP_OPT_DGID | 2079 SRP_OPT_DGID |
@@ -2081,6 +2094,7 @@ static const match_table_t srp_opt_tokens = {
2081 { SRP_OPT_CMD_SG_ENTRIES, "cmd_sg_entries=%u" }, 2094 { SRP_OPT_CMD_SG_ENTRIES, "cmd_sg_entries=%u" },
2082 { SRP_OPT_ALLOW_EXT_SG, "allow_ext_sg=%u" }, 2095 { SRP_OPT_ALLOW_EXT_SG, "allow_ext_sg=%u" },
2083 { SRP_OPT_SG_TABLESIZE, "sg_tablesize=%u" }, 2096 { SRP_OPT_SG_TABLESIZE, "sg_tablesize=%u" },
2097 { SRP_OPT_COMP_VECTOR, "comp_vector=%u" },
2084 { SRP_OPT_ERR, NULL } 2098 { SRP_OPT_ERR, NULL }
2085}; 2099};
2086 2100
@@ -2236,6 +2250,14 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
2236 target->sg_tablesize = token; 2250 target->sg_tablesize = token;
2237 break; 2251 break;
2238 2252
2253 case SRP_OPT_COMP_VECTOR:
2254 if (match_int(args, &token) || token < 0) {
2255 pr_warn("bad comp_vector parameter '%s'\n", p);
2256 goto out;
2257 }
2258 target->comp_vector = token;
2259 break;
2260
2239 default: 2261 default:
2240 pr_warn("unknown parameter or missing value '%s' in target creation request\n", 2262 pr_warn("unknown parameter or missing value '%s' in target creation request\n",
2241 p); 2263 p);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
index 66fbedda4571..e641088c14dc 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -156,6 +156,7 @@ struct srp_target_port {
156 char target_name[32]; 156 char target_name[32];
157 unsigned int scsi_id; 157 unsigned int scsi_id;
158 unsigned int sg_tablesize; 158 unsigned int sg_tablesize;
159 int comp_vector;
159 160
160 struct ib_sa_path_rec path; 161 struct ib_sa_path_rec path;
161 __be16 orig_dgid[8]; 162 __be16 orig_dgid[8];