diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 32 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 17 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/qp.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 157 |
6 files changed, 205 insertions, 23 deletions
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index f0612645de99..7567437dbd34 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -177,18 +177,18 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, | |||
177 | 177 | ||
178 | props->max_mr_size = ~0ull; | 178 | props->max_mr_size = ~0ull; |
179 | props->page_size_cap = dev->dev->caps.page_size_cap; | 179 | props->page_size_cap = dev->dev->caps.page_size_cap; |
180 | props->max_qp = dev->dev->caps.num_qps - dev->dev->caps.reserved_qps; | 180 | props->max_qp = dev->dev->quotas.qp; |
181 | props->max_qp_wr = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE; | 181 | props->max_qp_wr = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE; |
182 | props->max_sge = min(dev->dev->caps.max_sq_sg, | 182 | props->max_sge = min(dev->dev->caps.max_sq_sg, |
183 | dev->dev->caps.max_rq_sg); | 183 | dev->dev->caps.max_rq_sg); |
184 | props->max_cq = dev->dev->caps.num_cqs - dev->dev->caps.reserved_cqs; | 184 | props->max_cq = dev->dev->quotas.cq; |
185 | props->max_cqe = dev->dev->caps.max_cqes; | 185 | props->max_cqe = dev->dev->caps.max_cqes; |
186 | props->max_mr = dev->dev->caps.num_mpts - dev->dev->caps.reserved_mrws; | 186 | props->max_mr = dev->dev->quotas.mpt; |
187 | props->max_pd = dev->dev->caps.num_pds - dev->dev->caps.reserved_pds; | 187 | props->max_pd = dev->dev->caps.num_pds - dev->dev->caps.reserved_pds; |
188 | props->max_qp_rd_atom = dev->dev->caps.max_qp_dest_rdma; | 188 | props->max_qp_rd_atom = dev->dev->caps.max_qp_dest_rdma; |
189 | props->max_qp_init_rd_atom = dev->dev->caps.max_qp_init_rdma; | 189 | props->max_qp_init_rd_atom = dev->dev->caps.max_qp_init_rdma; |
190 | props->max_res_rd_atom = props->max_qp_rd_atom * props->max_qp; | 190 | props->max_res_rd_atom = props->max_qp_rd_atom * props->max_qp; |
191 | props->max_srq = dev->dev->caps.num_srqs - dev->dev->caps.reserved_srqs; | 191 | props->max_srq = dev->dev->quotas.srq; |
192 | props->max_srq_wr = dev->dev->caps.max_srq_wqes - 1; | 192 | props->max_srq_wr = dev->dev->caps.max_srq_wqes - 1; |
193 | props->max_srq_sge = dev->dev->caps.max_srq_sge; | 193 | props->max_srq_sge = dev->dev->caps.max_srq_sge; |
194 | props->max_fast_reg_page_list_len = MLX4_MAX_FAST_REG_PAGES; | 194 | props->max_fast_reg_page_list_len = MLX4_MAX_FAST_REG_PAGES; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index c151e7a6710a..f8c88c3ad9fc 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -177,6 +177,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
177 | struct mlx4_cmd_mailbox *outbox, | 177 | struct mlx4_cmd_mailbox *outbox, |
178 | struct mlx4_cmd_info *cmd) | 178 | struct mlx4_cmd_info *cmd) |
179 | { | 179 | { |
180 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
180 | u8 field; | 181 | u8 field; |
181 | u32 size; | 182 | u32 size; |
182 | int err = 0; | 183 | int err = 0; |
@@ -250,13 +251,13 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
250 | field = 0; /* protected FMR support not available as yet */ | 251 | field = 0; /* protected FMR support not available as yet */ |
251 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FMR_OFFSET); | 252 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FMR_OFFSET); |
252 | 253 | ||
253 | size = dev->caps.num_qps; | 254 | size = priv->mfunc.master.res_tracker.res_alloc[RES_QP].quota[slave]; |
254 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); | 255 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); |
255 | 256 | ||
256 | size = dev->caps.num_srqs; | 257 | size = priv->mfunc.master.res_tracker.res_alloc[RES_SRQ].quota[slave]; |
257 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET); | 258 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET); |
258 | 259 | ||
259 | size = dev->caps.num_cqs; | 260 | size = priv->mfunc.master.res_tracker.res_alloc[RES_CQ].quota[slave]; |
260 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET); | 261 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET); |
261 | 262 | ||
262 | size = dev->caps.num_eqs; | 263 | size = dev->caps.num_eqs; |
@@ -265,10 +266,10 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
265 | size = dev->caps.reserved_eqs; | 266 | size = dev->caps.reserved_eqs; |
266 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); | 267 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); |
267 | 268 | ||
268 | size = dev->caps.num_mpts; | 269 | size = priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[slave]; |
269 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET); | 270 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET); |
270 | 271 | ||
271 | size = dev->caps.num_mtts; | 272 | size = priv->mfunc.master.res_tracker.res_alloc[RES_MTT].quota[slave]; |
272 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET); | 273 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET); |
273 | 274 | ||
274 | size = dev->caps.num_mgms + dev->caps.num_amgms; | 275 | size = dev->caps.num_mgms + dev->caps.num_amgms; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 179d26709c94..7d2628dfdc29 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -562,13 +562,17 @@ static int mlx4_slave_cap(struct mlx4_dev *dev) | |||
562 | } | 562 | } |
563 | 563 | ||
564 | dev->caps.num_ports = func_cap.num_ports; | 564 | dev->caps.num_ports = func_cap.num_ports; |
565 | dev->caps.num_qps = func_cap.qp_quota; | 565 | dev->quotas.qp = func_cap.qp_quota; |
566 | dev->caps.num_srqs = func_cap.srq_quota; | 566 | dev->quotas.srq = func_cap.srq_quota; |
567 | dev->caps.num_cqs = func_cap.cq_quota; | 567 | dev->quotas.cq = func_cap.cq_quota; |
568 | dev->caps.num_eqs = func_cap.max_eq; | 568 | dev->quotas.mpt = func_cap.mpt_quota; |
569 | dev->caps.reserved_eqs = func_cap.reserved_eq; | 569 | dev->quotas.mtt = func_cap.mtt_quota; |
570 | dev->caps.num_mpts = func_cap.mpt_quota; | 570 | dev->caps.num_qps = 1 << hca_param.log_num_qps; |
571 | dev->caps.num_mtts = func_cap.mtt_quota; | 571 | dev->caps.num_srqs = 1 << hca_param.log_num_srqs; |
572 | dev->caps.num_cqs = 1 << hca_param.log_num_cqs; | ||
573 | dev->caps.num_mpts = 1 << hca_param.log_mpt_sz; | ||
574 | dev->caps.num_eqs = func_cap.max_eq; | ||
575 | dev->caps.reserved_eqs = func_cap.reserved_eq; | ||
572 | dev->caps.num_pds = MLX4_NUM_PDS; | 576 | dev->caps.num_pds = MLX4_NUM_PDS; |
573 | dev->caps.num_mgms = 0; | 577 | dev->caps.num_mgms = 0; |
574 | dev->caps.num_amgms = 0; | 578 | dev->caps.num_amgms = 0; |
@@ -2102,9 +2106,15 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data) | |||
2102 | "aborting.\n"); | 2106 | "aborting.\n"); |
2103 | return err; | 2107 | return err; |
2104 | } | 2108 | } |
2105 | if (num_vfs > MLX4_MAX_NUM_VF) { | 2109 | |
2106 | printk(KERN_ERR "There are more VF's (%d) than allowed(%d)\n", | 2110 | /* Due to requirement that all VFs and the PF are *guaranteed* 2 MACS |
2107 | num_vfs, MLX4_MAX_NUM_VF); | 2111 | * per port, we must limit the number of VFs to 63 (since their are |
2112 | * 128 MACs) | ||
2113 | */ | ||
2114 | if (num_vfs >= MLX4_MAX_NUM_VF) { | ||
2115 | dev_err(&pdev->dev, | ||
2116 | "Requested more VF's (%d) than allowed (%d)\n", | ||
2117 | num_vfs, MLX4_MAX_NUM_VF - 1); | ||
2108 | return -EINVAL; | 2118 | return -EINVAL; |
2109 | } | 2119 | } |
2110 | 2120 | ||
@@ -2322,6 +2332,8 @@ slave_start: | |||
2322 | if (err) | 2332 | if (err) |
2323 | goto err_steer; | 2333 | goto err_steer; |
2324 | 2334 | ||
2335 | mlx4_init_quotas(dev); | ||
2336 | |||
2325 | for (port = 1; port <= dev->caps.num_ports; port++) { | 2337 | for (port = 1; port <= dev->caps.num_ports; port++) { |
2326 | err = mlx4_init_port_info(dev, port); | 2338 | err = mlx4_init_port_info(dev, port); |
2327 | if (err) | 2339 | if (err) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 97941269bc14..e7eb86ecc6ea 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -504,12 +504,27 @@ struct slave_list { | |||
504 | struct list_head res_list[MLX4_NUM_OF_RESOURCE_TYPE]; | 504 | struct list_head res_list[MLX4_NUM_OF_RESOURCE_TYPE]; |
505 | }; | 505 | }; |
506 | 506 | ||
507 | struct resource_allocator { | ||
508 | union { | ||
509 | int res_reserved; | ||
510 | int res_port_rsvd[MLX4_MAX_PORTS]; | ||
511 | }; | ||
512 | union { | ||
513 | int res_free; | ||
514 | int res_port_free[MLX4_MAX_PORTS]; | ||
515 | }; | ||
516 | int *quota; | ||
517 | int *allocated; | ||
518 | int *guaranteed; | ||
519 | }; | ||
520 | |||
507 | struct mlx4_resource_tracker { | 521 | struct mlx4_resource_tracker { |
508 | spinlock_t lock; | 522 | spinlock_t lock; |
509 | /* tree for each resources */ | 523 | /* tree for each resources */ |
510 | struct rb_root res_tree[MLX4_NUM_OF_RESOURCE_TYPE]; | 524 | struct rb_root res_tree[MLX4_NUM_OF_RESOURCE_TYPE]; |
511 | /* num_of_slave's lists, one per slave */ | 525 | /* num_of_slave's lists, one per slave */ |
512 | struct slave_list *slave_list; | 526 | struct slave_list *slave_list; |
527 | struct resource_allocator res_alloc[MLX4_NUM_OF_RESOURCE_TYPE]; | ||
513 | }; | 528 | }; |
514 | 529 | ||
515 | #define SLAVE_EVENT_EQ_SIZE 128 | 530 | #define SLAVE_EVENT_EQ_SIZE 128 |
@@ -1253,4 +1268,6 @@ static inline spinlock_t *mlx4_tlock(struct mlx4_dev *dev) | |||
1253 | 1268 | ||
1254 | void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work); | 1269 | void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work); |
1255 | 1270 | ||
1271 | void mlx4_init_quotas(struct mlx4_dev *dev); | ||
1272 | |||
1256 | #endif /* MLX4_H */ | 1273 | #endif /* MLX4_H */ |
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c index e891b058c1be..2715e61dbb74 100644 --- a/drivers/net/ethernet/mellanox/mlx4/qp.c +++ b/drivers/net/ethernet/mellanox/mlx4/qp.c | |||
@@ -480,8 +480,7 @@ int mlx4_init_qp_table(struct mlx4_dev *dev) | |||
480 | */ | 480 | */ |
481 | 481 | ||
482 | err = mlx4_bitmap_init(&qp_table->bitmap, dev->caps.num_qps, | 482 | err = mlx4_bitmap_init(&qp_table->bitmap, dev->caps.num_qps, |
483 | (1 << 23) - 1, dev->phys_caps.base_sqpn + 8 + | 483 | (1 << 23) - 1, mlx4_num_reserved_sqps(dev), |
484 | 16 * MLX4_MFUNC_MAX * !!mlx4_is_master(dev), | ||
485 | reserved_from_top); | 484 | reserved_from_top); |
486 | if (err) | 485 | if (err) |
487 | return err; | 486 | return err; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 35863889bec0..cc5d6d0aad16 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -284,10 +284,59 @@ static const char *ResourceType(enum mlx4_resource rt) | |||
284 | } | 284 | } |
285 | 285 | ||
286 | static void rem_slave_vlans(struct mlx4_dev *dev, int slave); | 286 | static void rem_slave_vlans(struct mlx4_dev *dev, int slave); |
287 | static inline void initialize_res_quotas(struct mlx4_dev *dev, | ||
288 | struct resource_allocator *res_alloc, | ||
289 | enum mlx4_resource res_type, | ||
290 | int vf, int num_instances) | ||
291 | { | ||
292 | res_alloc->guaranteed[vf] = num_instances / (2 * (dev->num_vfs + 1)); | ||
293 | res_alloc->quota[vf] = (num_instances / 2) + res_alloc->guaranteed[vf]; | ||
294 | if (vf == mlx4_master_func_num(dev)) { | ||
295 | res_alloc->res_free = num_instances; | ||
296 | if (res_type == RES_MTT) { | ||
297 | /* reserved mtts will be taken out of the PF allocation */ | ||
298 | res_alloc->res_free += dev->caps.reserved_mtts; | ||
299 | res_alloc->guaranteed[vf] += dev->caps.reserved_mtts; | ||
300 | res_alloc->quota[vf] += dev->caps.reserved_mtts; | ||
301 | } | ||
302 | } | ||
303 | } | ||
304 | |||
305 | void mlx4_init_quotas(struct mlx4_dev *dev) | ||
306 | { | ||
307 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
308 | int pf; | ||
309 | |||
310 | /* quotas for VFs are initialized in mlx4_slave_cap */ | ||
311 | if (mlx4_is_slave(dev)) | ||
312 | return; | ||
313 | |||
314 | if (!mlx4_is_mfunc(dev)) { | ||
315 | dev->quotas.qp = dev->caps.num_qps - dev->caps.reserved_qps - | ||
316 | mlx4_num_reserved_sqps(dev); | ||
317 | dev->quotas.cq = dev->caps.num_cqs - dev->caps.reserved_cqs; | ||
318 | dev->quotas.srq = dev->caps.num_srqs - dev->caps.reserved_srqs; | ||
319 | dev->quotas.mtt = dev->caps.num_mtts - dev->caps.reserved_mtts; | ||
320 | dev->quotas.mpt = dev->caps.num_mpts - dev->caps.reserved_mrws; | ||
321 | return; | ||
322 | } | ||
323 | |||
324 | pf = mlx4_master_func_num(dev); | ||
325 | dev->quotas.qp = | ||
326 | priv->mfunc.master.res_tracker.res_alloc[RES_QP].quota[pf]; | ||
327 | dev->quotas.cq = | ||
328 | priv->mfunc.master.res_tracker.res_alloc[RES_CQ].quota[pf]; | ||
329 | dev->quotas.srq = | ||
330 | priv->mfunc.master.res_tracker.res_alloc[RES_SRQ].quota[pf]; | ||
331 | dev->quotas.mtt = | ||
332 | priv->mfunc.master.res_tracker.res_alloc[RES_MTT].quota[pf]; | ||
333 | dev->quotas.mpt = | ||
334 | priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[pf]; | ||
335 | } | ||
287 | int mlx4_init_resource_tracker(struct mlx4_dev *dev) | 336 | int mlx4_init_resource_tracker(struct mlx4_dev *dev) |
288 | { | 337 | { |
289 | struct mlx4_priv *priv = mlx4_priv(dev); | 338 | struct mlx4_priv *priv = mlx4_priv(dev); |
290 | int i; | 339 | int i, j; |
291 | int t; | 340 | int t; |
292 | 341 | ||
293 | priv->mfunc.master.res_tracker.slave_list = | 342 | priv->mfunc.master.res_tracker.slave_list = |
@@ -308,8 +357,104 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev) | |||
308 | for (i = 0 ; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) | 357 | for (i = 0 ; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) |
309 | priv->mfunc.master.res_tracker.res_tree[i] = RB_ROOT; | 358 | priv->mfunc.master.res_tracker.res_tree[i] = RB_ROOT; |
310 | 359 | ||
360 | for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) { | ||
361 | struct resource_allocator *res_alloc = | ||
362 | &priv->mfunc.master.res_tracker.res_alloc[i]; | ||
363 | res_alloc->quota = kmalloc((dev->num_vfs + 1) * sizeof(int), GFP_KERNEL); | ||
364 | res_alloc->guaranteed = kmalloc((dev->num_vfs + 1) * sizeof(int), GFP_KERNEL); | ||
365 | if (i == RES_MAC || i == RES_VLAN) | ||
366 | res_alloc->allocated = kzalloc(MLX4_MAX_PORTS * | ||
367 | (dev->num_vfs + 1) * sizeof(int), | ||
368 | GFP_KERNEL); | ||
369 | else | ||
370 | res_alloc->allocated = kzalloc((dev->num_vfs + 1) * sizeof(int), GFP_KERNEL); | ||
371 | |||
372 | if (!res_alloc->quota || !res_alloc->guaranteed || | ||
373 | !res_alloc->allocated) | ||
374 | goto no_mem_err; | ||
375 | |||
376 | for (t = 0; t < dev->num_vfs + 1; t++) { | ||
377 | switch (i) { | ||
378 | case RES_QP: | ||
379 | initialize_res_quotas(dev, res_alloc, RES_QP, | ||
380 | t, dev->caps.num_qps - | ||
381 | dev->caps.reserved_qps - | ||
382 | mlx4_num_reserved_sqps(dev)); | ||
383 | break; | ||
384 | case RES_CQ: | ||
385 | initialize_res_quotas(dev, res_alloc, RES_CQ, | ||
386 | t, dev->caps.num_cqs - | ||
387 | dev->caps.reserved_cqs); | ||
388 | break; | ||
389 | case RES_SRQ: | ||
390 | initialize_res_quotas(dev, res_alloc, RES_SRQ, | ||
391 | t, dev->caps.num_srqs - | ||
392 | dev->caps.reserved_srqs); | ||
393 | break; | ||
394 | case RES_MPT: | ||
395 | initialize_res_quotas(dev, res_alloc, RES_MPT, | ||
396 | t, dev->caps.num_mpts - | ||
397 | dev->caps.reserved_mrws); | ||
398 | break; | ||
399 | case RES_MTT: | ||
400 | initialize_res_quotas(dev, res_alloc, RES_MTT, | ||
401 | t, dev->caps.num_mtts - | ||
402 | dev->caps.reserved_mtts); | ||
403 | break; | ||
404 | case RES_MAC: | ||
405 | if (t == mlx4_master_func_num(dev)) { | ||
406 | res_alloc->quota[t] = MLX4_MAX_MAC_NUM; | ||
407 | res_alloc->guaranteed[t] = 2; | ||
408 | for (j = 0; j < MLX4_MAX_PORTS; j++) | ||
409 | res_alloc->res_port_free[j] = MLX4_MAX_MAC_NUM; | ||
410 | } else { | ||
411 | res_alloc->quota[t] = MLX4_MAX_MAC_NUM; | ||
412 | res_alloc->guaranteed[t] = 2; | ||
413 | } | ||
414 | break; | ||
415 | case RES_VLAN: | ||
416 | if (t == mlx4_master_func_num(dev)) { | ||
417 | res_alloc->quota[t] = MLX4_MAX_VLAN_NUM; | ||
418 | res_alloc->guaranteed[t] = MLX4_MAX_VLAN_NUM / 2; | ||
419 | for (j = 0; j < MLX4_MAX_PORTS; j++) | ||
420 | res_alloc->res_port_free[j] = | ||
421 | res_alloc->quota[t]; | ||
422 | } else { | ||
423 | res_alloc->quota[t] = MLX4_MAX_VLAN_NUM / 2; | ||
424 | res_alloc->guaranteed[t] = 0; | ||
425 | } | ||
426 | break; | ||
427 | case RES_COUNTER: | ||
428 | res_alloc->quota[t] = dev->caps.max_counters; | ||
429 | res_alloc->guaranteed[t] = 0; | ||
430 | if (t == mlx4_master_func_num(dev)) | ||
431 | res_alloc->res_free = res_alloc->quota[t]; | ||
432 | break; | ||
433 | default: | ||
434 | break; | ||
435 | } | ||
436 | if (i == RES_MAC || i == RES_VLAN) { | ||
437 | for (j = 0; j < MLX4_MAX_PORTS; j++) | ||
438 | res_alloc->res_port_rsvd[j] += | ||
439 | res_alloc->guaranteed[t]; | ||
440 | } else { | ||
441 | res_alloc->res_reserved += res_alloc->guaranteed[t]; | ||
442 | } | ||
443 | } | ||
444 | } | ||
311 | spin_lock_init(&priv->mfunc.master.res_tracker.lock); | 445 | spin_lock_init(&priv->mfunc.master.res_tracker.lock); |
312 | return 0 ; | 446 | return 0; |
447 | |||
448 | no_mem_err: | ||
449 | for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) { | ||
450 | kfree(priv->mfunc.master.res_tracker.res_alloc[i].allocated); | ||
451 | priv->mfunc.master.res_tracker.res_alloc[i].allocated = NULL; | ||
452 | kfree(priv->mfunc.master.res_tracker.res_alloc[i].guaranteed); | ||
453 | priv->mfunc.master.res_tracker.res_alloc[i].guaranteed = NULL; | ||
454 | kfree(priv->mfunc.master.res_tracker.res_alloc[i].quota); | ||
455 | priv->mfunc.master.res_tracker.res_alloc[i].quota = NULL; | ||
456 | } | ||
457 | return -ENOMEM; | ||
313 | } | 458 | } |
314 | 459 | ||
315 | void mlx4_free_resource_tracker(struct mlx4_dev *dev, | 460 | void mlx4_free_resource_tracker(struct mlx4_dev *dev, |
@@ -333,6 +478,14 @@ void mlx4_free_resource_tracker(struct mlx4_dev *dev, | |||
333 | } | 478 | } |
334 | 479 | ||
335 | if (type != RES_TR_FREE_SLAVES_ONLY) { | 480 | if (type != RES_TR_FREE_SLAVES_ONLY) { |
481 | for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) { | ||
482 | kfree(priv->mfunc.master.res_tracker.res_alloc[i].allocated); | ||
483 | priv->mfunc.master.res_tracker.res_alloc[i].allocated = NULL; | ||
484 | kfree(priv->mfunc.master.res_tracker.res_alloc[i].guaranteed); | ||
485 | priv->mfunc.master.res_tracker.res_alloc[i].guaranteed = NULL; | ||
486 | kfree(priv->mfunc.master.res_tracker.res_alloc[i].quota); | ||
487 | priv->mfunc.master.res_tracker.res_alloc[i].quota = NULL; | ||
488 | } | ||
336 | kfree(priv->mfunc.master.res_tracker.slave_list); | 489 | kfree(priv->mfunc.master.res_tracker.slave_list); |
337 | priv->mfunc.master.res_tracker.slave_list = NULL; | 490 | priv->mfunc.master.res_tracker.slave_list = NULL; |
338 | } | 491 | } |