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) |
