diff options
-rw-r--r-- | drivers/infiniband/hw/mlx4/cq.c | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 84 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/mlx4_ib.h | 2 |
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 | ||
1079 | static 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 | |||
1135 | static 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 | |||
1079 | static void *mlx4_ib_add(struct mlx4_dev *dev) | 1159 | static 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 | ||
207 | static inline struct mlx4_ib_dev *to_mdev(struct ib_device *ibdev) | 209 | static inline struct mlx4_ib_dev *to_mdev(struct ib_device *ibdev) |