aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Shamay <idos@mellanox.com>2014-09-18 04:50:59 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-19 17:30:10 -0400
commit77507aa249aecd06fa25ad058b64481e46887a01 (patch)
tree814aa07a0d83e7cfee705f512cd6afb2d303ed78
parent54003f119c26573d3bb86a5efc64f3e5fd43b8c6 (diff)
net/mlx4_core: Enable CQE/EQE stride support
This feature is intended for archs having cache line larger then 64B. Since our CQE/EQEs are generally 64B in those systems, HW will write twice to the same cache line consecutively, causing pipe locks due to he hazard prevention mechanism. For elements in a cyclic buffer, writes are consecutive, so entries smaller than a cache line should be avoided, especially if they are written at a high rate. Reduce consecutive writes to same cache line in CQs/EQs, by allowing the driver to increase the distance between entries so that each will reside in a different cache line. Until the introduction of this feature, there were two types of CQE/EQE: 1. 32B stride and context in the [0-31] segment 2. 64B stride and context in the [32-63] segment This feature introduces two additional types: 3. 128B stride and context in the [0-31] segment (128B cache line) 4. 256B stride and context in the [0-31] segment (256B cache line) Modify the mlx4_core driver to query the device for the CQE/EQE cache line stride capability and to enable that capability when the host cache line size is larger than 64 bytes (supported cache lines are 128B and 256B). The mlx4 IB driver and libmlx4 need not be aware of this change. The PF context behaviour is changed to require this change in VF drivers running on such archs. Signed-off-by: Ido Shamay <idos@mellanox.com> Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c38
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c61
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h3
-rw-r--r--include/linux/mlx4/device.h11
5 files changed, 108 insertions, 7 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 494753e44ae3..13b2e4a51ef4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -137,7 +137,9 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
137 [8] = "Dynamic QP updates support", 137 [8] = "Dynamic QP updates support",
138 [9] = "Device managed flow steering IPoIB support", 138 [9] = "Device managed flow steering IPoIB support",
139 [10] = "TCP/IP offloads/flow-steering for VXLAN support", 139 [10] = "TCP/IP offloads/flow-steering for VXLAN support",
140 [11] = "MAD DEMUX (Secure-Host) support" 140 [11] = "MAD DEMUX (Secure-Host) support",
141 [12] = "Large cache line (>64B) CQE stride support",
142 [13] = "Large cache line (>64B) EQE stride support"
141 }; 143 };
142 int i; 144 int i;
143 145
@@ -557,6 +559,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
557#define QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET 0x74 559#define QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET 0x74
558#define QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET 0x76 560#define QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET 0x76
559#define QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET 0x77 561#define QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET 0x77
562#define QUERY_DEV_CAP_CQ_EQ_CACHE_LINE_STRIDE 0x7a
560#define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80 563#define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80
561#define QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET 0x82 564#define QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET 0x82
562#define QUERY_DEV_CAP_AUX_ENTRY_SZ_OFFSET 0x84 565#define QUERY_DEV_CAP_AUX_ENTRY_SZ_OFFSET 0x84
@@ -733,6 +736,11 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
733 dev_cap->max_rq_sg = field; 736 dev_cap->max_rq_sg = field;
734 MLX4_GET(size, outbox, QUERY_DEV_CAP_MAX_DESC_SZ_RQ_OFFSET); 737 MLX4_GET(size, outbox, QUERY_DEV_CAP_MAX_DESC_SZ_RQ_OFFSET);
735 dev_cap->max_rq_desc_sz = size; 738 dev_cap->max_rq_desc_sz = size;
739 MLX4_GET(field, outbox, QUERY_DEV_CAP_CQ_EQ_CACHE_LINE_STRIDE);
740 if (field & (1 << 6))
741 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_CQE_STRIDE;
742 if (field & (1 << 7))
743 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_EQE_STRIDE;
736 744
737 MLX4_GET(dev_cap->bmme_flags, outbox, 745 MLX4_GET(dev_cap->bmme_flags, outbox,
738 QUERY_DEV_CAP_BMME_FLAGS_OFFSET); 746 QUERY_DEV_CAP_BMME_FLAGS_OFFSET);
@@ -1376,6 +1384,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
1376#define INIT_HCA_CQC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x30) 1384#define INIT_HCA_CQC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x30)
1377#define INIT_HCA_LOG_CQ_OFFSET (INIT_HCA_QPC_OFFSET + 0x37) 1385#define INIT_HCA_LOG_CQ_OFFSET (INIT_HCA_QPC_OFFSET + 0x37)
1378#define INIT_HCA_EQE_CQE_OFFSETS (INIT_HCA_QPC_OFFSET + 0x38) 1386#define INIT_HCA_EQE_CQE_OFFSETS (INIT_HCA_QPC_OFFSET + 0x38)
1387#define INIT_HCA_EQE_CQE_STRIDE_OFFSET (INIT_HCA_QPC_OFFSET + 0x3b)
1379#define INIT_HCA_ALTC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x40) 1388#define INIT_HCA_ALTC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x40)
1380#define INIT_HCA_AUXC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x50) 1389#define INIT_HCA_AUXC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x50)
1381#define INIT_HCA_EQC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x60) 1390#define INIT_HCA_EQC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x60)
@@ -1452,11 +1461,25 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
1452 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_64B_CQE) { 1461 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_64B_CQE) {
1453 *(inbox + INIT_HCA_EQE_CQE_OFFSETS / 4) |= cpu_to_be32(1 << 30); 1462 *(inbox + INIT_HCA_EQE_CQE_OFFSETS / 4) |= cpu_to_be32(1 << 30);
1454 dev->caps.cqe_size = 64; 1463 dev->caps.cqe_size = 64;
1455 dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_64B_CQE; 1464 dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_LARGE_CQE;
1456 } else { 1465 } else {
1457 dev->caps.cqe_size = 32; 1466 dev->caps.cqe_size = 32;
1458 } 1467 }
1459 1468
1469 /* CX3 is capable of extending CQEs\EQEs to strides larger than 64B */
1470 if ((dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_EQE_STRIDE) &&
1471 (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_CQE_STRIDE)) {
1472 dev->caps.eqe_size = cache_line_size();
1473 dev->caps.cqe_size = cache_line_size();
1474 dev->caps.eqe_factor = 0;
1475 MLX4_PUT(inbox, (u8)((ilog2(dev->caps.eqe_size) - 5) << 4 |
1476 (ilog2(dev->caps.eqe_size) - 5)),
1477 INIT_HCA_EQE_CQE_STRIDE_OFFSET);
1478
1479 /* User still need to know to support CQE > 32B */
1480 dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_LARGE_CQE;
1481 }
1482
1460 /* QPC/EEC/CQC/EQC/RDMARC attributes */ 1483 /* QPC/EEC/CQC/EQC/RDMARC attributes */
1461 1484
1462 MLX4_PUT(inbox, param->qpc_base, INIT_HCA_QPC_BASE_OFFSET); 1485 MLX4_PUT(inbox, param->qpc_base, INIT_HCA_QPC_BASE_OFFSET);
@@ -1616,6 +1639,17 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev,
1616 if (byte_field & 0x40) /* 64-bytes cqe enabled */ 1639 if (byte_field & 0x40) /* 64-bytes cqe enabled */
1617 param->dev_cap_enabled |= MLX4_DEV_CAP_64B_CQE_ENABLED; 1640 param->dev_cap_enabled |= MLX4_DEV_CAP_64B_CQE_ENABLED;
1618 1641
1642 /* CX3 is capable of extending CQEs\EQEs to strides larger than 64B */
1643 MLX4_GET(byte_field, outbox, INIT_HCA_EQE_CQE_STRIDE_OFFSET);
1644 if (byte_field) {
1645 param->dev_cap_enabled |= MLX4_DEV_CAP_64B_EQE_ENABLED;
1646 param->dev_cap_enabled |= MLX4_DEV_CAP_64B_CQE_ENABLED;
1647 param->cqe_size = 1 << ((byte_field &
1648 MLX4_CQE_SIZE_MASK_STRIDE) + 5);
1649 param->eqe_size = 1 << (((byte_field &
1650 MLX4_EQE_SIZE_MASK_STRIDE) >> 4) + 5);
1651 }
1652
1619 /* TPT attributes */ 1653 /* TPT attributes */
1620 1654
1621 MLX4_GET(param->dmpt_base, outbox, INIT_HCA_DMPT_BASE_OFFSET); 1655 MLX4_GET(param->dmpt_base, outbox, INIT_HCA_DMPT_BASE_OFFSET);
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h
index 1fce03ebe5c4..9b835aecac96 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.h
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.h
@@ -178,6 +178,8 @@ struct mlx4_init_hca_param {
178 u8 uar_page_sz; /* log pg sz in 4k chunks */ 178 u8 uar_page_sz; /* log pg sz in 4k chunks */
179 u8 steering_mode; /* for QUERY_HCA */ 179 u8 steering_mode; /* for QUERY_HCA */
180 u64 dev_cap_enabled; 180 u64 dev_cap_enabled;
181 u16 cqe_size; /* For use only when CQE stride feature enabled */
182 u16 eqe_size; /* For use only when EQE stride feature enabled */
181}; 183};
182 184
183struct mlx4_init_ib_param { 185struct mlx4_init_ib_param {
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 7e2d5d57c598..1f10023af1db 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -104,7 +104,8 @@ module_param(enable_64b_cqe_eqe, bool, 0444);
104MODULE_PARM_DESC(enable_64b_cqe_eqe, 104MODULE_PARM_DESC(enable_64b_cqe_eqe,
105 "Enable 64 byte CQEs/EQEs when the FW supports this (default: True)"); 105 "Enable 64 byte CQEs/EQEs when the FW supports this (default: True)");
106 106
107#define PF_CONTEXT_BEHAVIOUR_MASK MLX4_FUNC_CAP_64B_EQE_CQE 107#define PF_CONTEXT_BEHAVIOUR_MASK (MLX4_FUNC_CAP_64B_EQE_CQE | \
108 MLX4_FUNC_CAP_EQE_CQE_STRIDE)
108 109
109static char mlx4_version[] = 110static char mlx4_version[] =
110 DRV_NAME ": Mellanox ConnectX core driver v" 111 DRV_NAME ": Mellanox ConnectX core driver v"
@@ -196,6 +197,40 @@ static void mlx4_set_port_mask(struct mlx4_dev *dev)
196 dev->caps.port_mask[i] = dev->caps.port_type[i]; 197 dev->caps.port_mask[i] = dev->caps.port_type[i];
197} 198}
198 199
200static void mlx4_enable_cqe_eqe_stride(struct mlx4_dev *dev)
201{
202 struct mlx4_caps *dev_cap = &dev->caps;
203
204 /* FW not supporting or cancelled by user */
205 if (!(dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_EQE_STRIDE) ||
206 !(dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_CQE_STRIDE))
207 return;
208
209 /* Must have 64B CQE_EQE enabled by FW to use bigger stride
210 * When FW has NCSI it may decide not to report 64B CQE/EQEs
211 */
212 if (!(dev_cap->flags & MLX4_DEV_CAP_FLAG_64B_EQE) ||
213 !(dev_cap->flags & MLX4_DEV_CAP_FLAG_64B_CQE)) {
214 dev_cap->flags2 &= ~MLX4_DEV_CAP_FLAG2_CQE_STRIDE;
215 dev_cap->flags2 &= ~MLX4_DEV_CAP_FLAG2_EQE_STRIDE;
216 return;
217 }
218
219 if (cache_line_size() == 128 || cache_line_size() == 256) {
220 mlx4_dbg(dev, "Enabling CQE stride cacheLine supported\n");
221 /* Changing the real data inside CQE size to 32B */
222 dev_cap->flags &= ~MLX4_DEV_CAP_FLAG_64B_CQE;
223 dev_cap->flags &= ~MLX4_DEV_CAP_FLAG_64B_EQE;
224
225 if (mlx4_is_master(dev))
226 dev_cap->function_caps |= MLX4_FUNC_CAP_EQE_CQE_STRIDE;
227 } else {
228 mlx4_dbg(dev, "Disabling CQE stride cacheLine unsupported\n");
229 dev_cap->flags2 &= ~MLX4_DEV_CAP_FLAG2_CQE_STRIDE;
230 dev_cap->flags2 &= ~MLX4_DEV_CAP_FLAG2_EQE_STRIDE;
231 }
232}
233
199static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) 234static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
200{ 235{
201 int err; 236 int err;
@@ -390,6 +425,14 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
390 dev->caps.flags &= ~MLX4_DEV_CAP_FLAG_64B_CQE; 425 dev->caps.flags &= ~MLX4_DEV_CAP_FLAG_64B_CQE;
391 dev->caps.flags &= ~MLX4_DEV_CAP_FLAG_64B_EQE; 426 dev->caps.flags &= ~MLX4_DEV_CAP_FLAG_64B_EQE;
392 } 427 }
428
429 if (dev_cap->flags2 &
430 (MLX4_DEV_CAP_FLAG2_CQE_STRIDE |
431 MLX4_DEV_CAP_FLAG2_EQE_STRIDE)) {
432 mlx4_warn(dev, "Disabling EQE/CQE stride per user request\n");
433 dev_cap->flags2 &= ~MLX4_DEV_CAP_FLAG2_CQE_STRIDE;
434 dev_cap->flags2 &= ~MLX4_DEV_CAP_FLAG2_EQE_STRIDE;
435 }
393 } 436 }
394 437
395 if ((dev->caps.flags & 438 if ((dev->caps.flags &
@@ -397,6 +440,9 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
397 mlx4_is_master(dev)) 440 mlx4_is_master(dev))
398 dev->caps.function_caps |= MLX4_FUNC_CAP_64B_EQE_CQE; 441 dev->caps.function_caps |= MLX4_FUNC_CAP_64B_EQE_CQE;
399 442
443 if (!mlx4_is_slave(dev))
444 mlx4_enable_cqe_eqe_stride(dev);
445
400 return 0; 446 return 0;
401} 447}
402 448
@@ -724,11 +770,22 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
724 770
725 if (hca_param.dev_cap_enabled & MLX4_DEV_CAP_64B_CQE_ENABLED) { 771 if (hca_param.dev_cap_enabled & MLX4_DEV_CAP_64B_CQE_ENABLED) {
726 dev->caps.cqe_size = 64; 772 dev->caps.cqe_size = 64;
727 dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_64B_CQE; 773 dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_LARGE_CQE;
728 } else { 774 } else {
729 dev->caps.cqe_size = 32; 775 dev->caps.cqe_size = 32;
730 } 776 }
731 777
778 if (hca_param.dev_cap_enabled & MLX4_DEV_CAP_EQE_STRIDE_ENABLED) {
779 dev->caps.eqe_size = hca_param.eqe_size;
780 dev->caps.eqe_factor = 0;
781 }
782
783 if (hca_param.dev_cap_enabled & MLX4_DEV_CAP_CQE_STRIDE_ENABLED) {
784 dev->caps.cqe_size = hca_param.cqe_size;
785 /* User still need to know when CQE > 32B */
786 dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_LARGE_CQE;
787 }
788
732 dev->caps.flags2 &= ~MLX4_DEV_CAP_FLAG2_TS; 789 dev->caps.flags2 &= ~MLX4_DEV_CAP_FLAG2_TS;
733 mlx4_warn(dev, "Timestamping is not supported in slave mode\n"); 790 mlx4_warn(dev, "Timestamping is not supported in slave mode\n");
734 791
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index b508c7887ef8..de10dbb2e6ed 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -285,6 +285,9 @@ struct mlx4_icm_table {
285#define MLX4_MPT_STATUS_SW 0xF0 285#define MLX4_MPT_STATUS_SW 0xF0
286#define MLX4_MPT_STATUS_HW 0x00 286#define MLX4_MPT_STATUS_HW 0x00
287 287
288#define MLX4_CQE_SIZE_MASK_STRIDE 0x3
289#define MLX4_EQE_SIZE_MASK_STRIDE 0x30
290
288/* 291/*
289 * Must be packed because mtt_seg is 64 bits but only aligned to 32 bits. 292 * Must be packed because mtt_seg is 64 bits but only aligned to 32 bits.
290 */ 293 */
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 1befd8df9cfc..7bcefe749a39 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -185,19 +185,24 @@ enum {
185 MLX4_DEV_CAP_FLAG2_DMFS_IPOIB = 1LL << 9, 185 MLX4_DEV_CAP_FLAG2_DMFS_IPOIB = 1LL << 9,
186 MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS = 1LL << 10, 186 MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS = 1LL << 10,
187 MLX4_DEV_CAP_FLAG2_MAD_DEMUX = 1LL << 11, 187 MLX4_DEV_CAP_FLAG2_MAD_DEMUX = 1LL << 11,
188 MLX4_DEV_CAP_FLAG2_CQE_STRIDE = 1LL << 12,
189 MLX4_DEV_CAP_FLAG2_EQE_STRIDE = 1LL << 13
188}; 190};
189 191
190enum { 192enum {
191 MLX4_DEV_CAP_64B_EQE_ENABLED = 1LL << 0, 193 MLX4_DEV_CAP_64B_EQE_ENABLED = 1LL << 0,
192 MLX4_DEV_CAP_64B_CQE_ENABLED = 1LL << 1 194 MLX4_DEV_CAP_64B_CQE_ENABLED = 1LL << 1,
195 MLX4_DEV_CAP_CQE_STRIDE_ENABLED = 1LL << 2,
196 MLX4_DEV_CAP_EQE_STRIDE_ENABLED = 1LL << 3
193}; 197};
194 198
195enum { 199enum {
196 MLX4_USER_DEV_CAP_64B_CQE = 1L << 0 200 MLX4_USER_DEV_CAP_LARGE_CQE = 1L << 0
197}; 201};
198 202
199enum { 203enum {
200 MLX4_FUNC_CAP_64B_EQE_CQE = 1L << 0 204 MLX4_FUNC_CAP_64B_EQE_CQE = 1L << 0,
205 MLX4_FUNC_CAP_EQE_CQE_STRIDE = 1L << 1
201}; 206};
202 207
203 208