aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/mlx4/cq.c3
-rw-r--r--drivers/infiniband/hw/mlx4/main.c84
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h2
3 files changed, 89 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index 34ac0e2e97ee..6d4ef71cbcdf 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -222,6 +222,9 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, int entries, int vector
222 uar = &dev->priv_uar; 222 uar = &dev->priv_uar;
223 } 223 }
224 224
225 if (dev->eq_table)
226 vector = dev->eq_table[vector % ibdev->num_comp_vectors];
227
225 err = mlx4_cq_alloc(dev->dev, entries, &cq->buf.mtt, uar, 228 err = mlx4_cq_alloc(dev->dev, entries, &cq->buf.mtt, uar,
226 cq->db.dma, &cq->mcq, vector, 0); 229 cq->db.dma, &cq->mcq, vector, 0);
227 if (err) 230 if (err)
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index a739d2738331..7dfa7866d594 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -1076,6 +1076,86 @@ static int mlx4_ib_netdev_event(struct notifier_block *this, unsigned long event
1076 return NOTIFY_DONE; 1076 return NOTIFY_DONE;
1077} 1077}
1078 1078
1079static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev)
1080{
1081 char name[32];
1082 int eq_per_port = 0;
1083 int added_eqs = 0;
1084 int total_eqs = 0;
1085 int i, j, eq;
1086
1087 /* Init eq table */
1088 ibdev->eq_table = NULL;
1089 ibdev->eq_added = 0;
1090
1091 /* Legacy mode? */
1092 if (dev->caps.comp_pool == 0)
1093 return;
1094
1095 eq_per_port = rounddown_pow_of_two(dev->caps.comp_pool/
1096 dev->caps.num_ports);
1097
1098 /* Init eq table */
1099 added_eqs = 0;
1100 mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB)
1101 added_eqs += eq_per_port;
1102
1103 total_eqs = dev->caps.num_comp_vectors + added_eqs;
1104
1105 ibdev->eq_table = kzalloc(total_eqs * sizeof(int), GFP_KERNEL);
1106 if (!ibdev->eq_table)
1107 return;
1108
1109 ibdev->eq_added = added_eqs;
1110
1111 eq = 0;
1112 mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB) {
1113 for (j = 0; j < eq_per_port; j++) {
1114 sprintf(name, "mlx4-ib-%d-%d@%s",
1115 i, j, dev->pdev->bus->name);
1116 /* Set IRQ for specific name (per ring) */
1117 if (mlx4_assign_eq(dev, name, &ibdev->eq_table[eq])) {
1118 /* Use legacy (same as mlx4_en driver) */
1119 pr_warn("Can't allocate EQ %d; reverting to legacy\n", eq);
1120 ibdev->eq_table[eq] =
1121 (eq % dev->caps.num_comp_vectors);
1122 }
1123 eq++;
1124 }
1125 }
1126
1127 /* Fill the reset of the vector with legacy EQ */
1128 for (i = 0, eq = added_eqs; i < dev->caps.num_comp_vectors; i++)
1129 ibdev->eq_table[eq++] = i;
1130
1131 /* Advertise the new number of EQs to clients */
1132 ibdev->ib_dev.num_comp_vectors = total_eqs;
1133}
1134
1135static void mlx4_ib_free_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev)
1136{
1137 int i;
1138 int total_eqs;
1139
1140 /* Reset the advertised EQ number */
1141 ibdev->ib_dev.num_comp_vectors = dev->caps.num_comp_vectors;
1142
1143 /* Free only the added eqs */
1144 for (i = 0; i < ibdev->eq_added; i++) {
1145 /* Don't free legacy eqs if used */
1146 if (ibdev->eq_table[i] <= dev->caps.num_comp_vectors)
1147 continue;
1148 mlx4_release_eq(dev, ibdev->eq_table[i]);
1149 }
1150
1151 total_eqs = dev->caps.num_comp_vectors + ibdev->eq_added;
1152 memset(ibdev->eq_table, 0, total_eqs * sizeof(int));
1153 kfree(ibdev->eq_table);
1154
1155 ibdev->eq_table = NULL;
1156 ibdev->eq_added = 0;
1157}
1158
1079static void *mlx4_ib_add(struct mlx4_dev *dev) 1159static void *mlx4_ib_add(struct mlx4_dev *dev)
1080{ 1160{
1081 struct mlx4_ib_dev *ibdev; 1161 struct mlx4_ib_dev *ibdev;
@@ -1210,6 +1290,8 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
1210 (1ull << IB_USER_VERBS_CMD_CLOSE_XRCD); 1290 (1ull << IB_USER_VERBS_CMD_CLOSE_XRCD);
1211 } 1291 }
1212 1292
1293 mlx4_ib_alloc_eqs(dev, ibdev);
1294
1213 spin_lock_init(&iboe->lock); 1295 spin_lock_init(&iboe->lock);
1214 1296
1215 if (init_node_data(ibdev)) 1297 if (init_node_data(ibdev))
@@ -1298,6 +1380,8 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
1298 mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB) 1380 mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB)
1299 mlx4_CLOSE_PORT(dev, p); 1381 mlx4_CLOSE_PORT(dev, p);
1300 1382
1383 mlx4_ib_free_eqs(dev, ibdev);
1384
1301 mlx4_uar_free(dev, &ibdev->priv_uar); 1385 mlx4_uar_free(dev, &ibdev->priv_uar);
1302 mlx4_pd_free(dev, ibdev->priv_pdn); 1386 mlx4_pd_free(dev, ibdev->priv_pdn);
1303 ib_dealloc_device(&ibdev->ib_dev); 1387 ib_dealloc_device(&ibdev->ib_dev);
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index ed80345c99ae..e62297cc77cc 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -202,6 +202,8 @@ struct mlx4_ib_dev {
202 bool ib_active; 202 bool ib_active;
203 struct mlx4_ib_iboe iboe; 203 struct mlx4_ib_iboe iboe;
204 int counters[MLX4_MAX_PORTS]; 204 int counters[MLX4_MAX_PORTS];
205 int *eq_table;
206 int eq_added;
205}; 207};
206 208
207static inline struct mlx4_ib_dev *to_mdev(struct ib_device *ibdev) 209static inline struct mlx4_ib_dev *to_mdev(struct ib_device *ibdev)