diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_classes.h | 5 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_cq.c | 11 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_main.c | 36 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_qp.c | 26 |
4 files changed, 74 insertions, 4 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h index 3d6d9461c31d..00bab60f6de4 100644 --- a/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/drivers/infiniband/hw/ehca/ehca_classes.h | |||
@@ -66,6 +66,7 @@ struct ehca_av; | |||
66 | #include "ehca_irq.h" | 66 | #include "ehca_irq.h" |
67 | 67 | ||
68 | #define EHCA_EQE_CACHE_SIZE 20 | 68 | #define EHCA_EQE_CACHE_SIZE 20 |
69 | #define EHCA_MAX_NUM_QUEUES 0xffff | ||
69 | 70 | ||
70 | struct ehca_eqe_cache_entry { | 71 | struct ehca_eqe_cache_entry { |
71 | struct ehca_eqe *eqe; | 72 | struct ehca_eqe *eqe; |
@@ -127,6 +128,8 @@ struct ehca_shca { | |||
127 | /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */ | 128 | /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */ |
128 | u32 hca_cap_mr_pgsize; | 129 | u32 hca_cap_mr_pgsize; |
129 | int max_mtu; | 130 | int max_mtu; |
131 | atomic_t num_cqs; | ||
132 | atomic_t num_qps; | ||
130 | }; | 133 | }; |
131 | 134 | ||
132 | struct ehca_pd { | 135 | struct ehca_pd { |
@@ -344,6 +347,8 @@ extern int ehca_use_hp_mr; | |||
344 | extern int ehca_scaling_code; | 347 | extern int ehca_scaling_code; |
345 | extern int ehca_lock_hcalls; | 348 | extern int ehca_lock_hcalls; |
346 | extern int ehca_nr_ports; | 349 | extern int ehca_nr_ports; |
350 | extern int ehca_max_cq; | ||
351 | extern int ehca_max_qp; | ||
347 | 352 | ||
348 | struct ipzu_queue_resp { | 353 | struct ipzu_queue_resp { |
349 | u32 qe_size; /* queue entry size */ | 354 | u32 qe_size; /* queue entry size */ |
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c index ec0cfcf3073f..5540b276a33c 100644 --- a/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/drivers/infiniband/hw/ehca/ehca_cq.c | |||
@@ -132,10 +132,19 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, | |||
132 | if (cqe >= 0xFFFFFFFF - 64 - additional_cqe) | 132 | if (cqe >= 0xFFFFFFFF - 64 - additional_cqe) |
133 | return ERR_PTR(-EINVAL); | 133 | return ERR_PTR(-EINVAL); |
134 | 134 | ||
135 | if (!atomic_add_unless(&shca->num_cqs, 1, ehca_max_cq)) { | ||
136 | ehca_err(device, "Unable to create CQ, max number of %i " | ||
137 | "CQs reached.", ehca_max_cq); | ||
138 | ehca_err(device, "To increase the maximum number of CQs " | ||
139 | "use the number_of_cqs module parameter.\n"); | ||
140 | return ERR_PTR(-ENOSPC); | ||
141 | } | ||
142 | |||
135 | my_cq = kmem_cache_zalloc(cq_cache, GFP_KERNEL); | 143 | my_cq = kmem_cache_zalloc(cq_cache, GFP_KERNEL); |
136 | if (!my_cq) { | 144 | if (!my_cq) { |
137 | ehca_err(device, "Out of memory for ehca_cq struct device=%p", | 145 | ehca_err(device, "Out of memory for ehca_cq struct device=%p", |
138 | device); | 146 | device); |
147 | atomic_dec(&shca->num_cqs); | ||
139 | return ERR_PTR(-ENOMEM); | 148 | return ERR_PTR(-ENOMEM); |
140 | } | 149 | } |
141 | 150 | ||
@@ -305,6 +314,7 @@ create_cq_exit2: | |||
305 | create_cq_exit1: | 314 | create_cq_exit1: |
306 | kmem_cache_free(cq_cache, my_cq); | 315 | kmem_cache_free(cq_cache, my_cq); |
307 | 316 | ||
317 | atomic_dec(&shca->num_cqs); | ||
308 | return cq; | 318 | return cq; |
309 | } | 319 | } |
310 | 320 | ||
@@ -359,6 +369,7 @@ int ehca_destroy_cq(struct ib_cq *cq) | |||
359 | ipz_queue_dtor(NULL, &my_cq->ipz_queue); | 369 | ipz_queue_dtor(NULL, &my_cq->ipz_queue); |
360 | kmem_cache_free(cq_cache, my_cq); | 370 | kmem_cache_free(cq_cache, my_cq); |
361 | 371 | ||
372 | atomic_dec(&shca->num_cqs); | ||
362 | return 0; | 373 | return 0; |
363 | } | 374 | } |
364 | 375 | ||
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 65048976198c..482103eb6eac 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
@@ -68,6 +68,8 @@ int ehca_port_act_time = 30; | |||
68 | int ehca_static_rate = -1; | 68 | int ehca_static_rate = -1; |
69 | int ehca_scaling_code = 0; | 69 | int ehca_scaling_code = 0; |
70 | int ehca_lock_hcalls = -1; | 70 | int ehca_lock_hcalls = -1; |
71 | int ehca_max_cq = -1; | ||
72 | int ehca_max_qp = -1; | ||
71 | 73 | ||
72 | module_param_named(open_aqp1, ehca_open_aqp1, bool, S_IRUGO); | 74 | module_param_named(open_aqp1, ehca_open_aqp1, bool, S_IRUGO); |
73 | module_param_named(debug_level, ehca_debug_level, int, S_IRUGO); | 75 | module_param_named(debug_level, ehca_debug_level, int, S_IRUGO); |
@@ -79,6 +81,8 @@ module_param_named(poll_all_eqs, ehca_poll_all_eqs, bool, S_IRUGO); | |||
79 | module_param_named(static_rate, ehca_static_rate, int, S_IRUGO); | 81 | module_param_named(static_rate, ehca_static_rate, int, S_IRUGO); |
80 | module_param_named(scaling_code, ehca_scaling_code, bool, S_IRUGO); | 82 | module_param_named(scaling_code, ehca_scaling_code, bool, S_IRUGO); |
81 | module_param_named(lock_hcalls, ehca_lock_hcalls, bool, S_IRUGO); | 83 | module_param_named(lock_hcalls, ehca_lock_hcalls, bool, S_IRUGO); |
84 | module_param_named(number_of_cqs, ehca_max_cq, int, S_IRUGO); | ||
85 | module_param_named(number_of_qps, ehca_max_qp, int, S_IRUGO); | ||
82 | 86 | ||
83 | MODULE_PARM_DESC(open_aqp1, | 87 | MODULE_PARM_DESC(open_aqp1, |
84 | "Open AQP1 on startup (default: no)"); | 88 | "Open AQP1 on startup (default: no)"); |
@@ -104,6 +108,12 @@ MODULE_PARM_DESC(scaling_code, | |||
104 | MODULE_PARM_DESC(lock_hcalls, | 108 | MODULE_PARM_DESC(lock_hcalls, |
105 | "Serialize all hCalls made by the driver " | 109 | "Serialize all hCalls made by the driver " |
106 | "(default: autodetect)"); | 110 | "(default: autodetect)"); |
111 | MODULE_PARM_DESC(number_of_cqs, | ||
112 | "Max number of CQs which can be allocated " | ||
113 | "(default: autodetect)"); | ||
114 | MODULE_PARM_DESC(number_of_qps, | ||
115 | "Max number of QPs which can be allocated " | ||
116 | "(default: autodetect)"); | ||
107 | 117 | ||
108 | DEFINE_RWLOCK(ehca_qp_idr_lock); | 118 | DEFINE_RWLOCK(ehca_qp_idr_lock); |
109 | DEFINE_RWLOCK(ehca_cq_idr_lock); | 119 | DEFINE_RWLOCK(ehca_cq_idr_lock); |
@@ -355,6 +365,25 @@ static int ehca_sense_attributes(struct ehca_shca *shca) | |||
355 | if (rblock->memory_page_size_supported & pgsize_map[i]) | 365 | if (rblock->memory_page_size_supported & pgsize_map[i]) |
356 | shca->hca_cap_mr_pgsize |= pgsize_map[i + 1]; | 366 | shca->hca_cap_mr_pgsize |= pgsize_map[i + 1]; |
357 | 367 | ||
368 | /* Set maximum number of CQs and QPs to calculate EQ size */ | ||
369 | if (ehca_max_qp == -1) | ||
370 | ehca_max_qp = min_t(int, rblock->max_qp, EHCA_MAX_NUM_QUEUES); | ||
371 | else if (ehca_max_qp < 1 || ehca_max_qp > rblock->max_qp) { | ||
372 | ehca_gen_err("Requested number of QPs is out of range (1 - %i) " | ||
373 | "specified by HW", rblock->max_qp); | ||
374 | ret = -EINVAL; | ||
375 | goto sense_attributes1; | ||
376 | } | ||
377 | |||
378 | if (ehca_max_cq == -1) | ||
379 | ehca_max_cq = min_t(int, rblock->max_cq, EHCA_MAX_NUM_QUEUES); | ||
380 | else if (ehca_max_cq < 1 || ehca_max_cq > rblock->max_cq) { | ||
381 | ehca_gen_err("Requested number of CQs is out of range (1 - %i) " | ||
382 | "specified by HW", rblock->max_cq); | ||
383 | ret = -EINVAL; | ||
384 | goto sense_attributes1; | ||
385 | } | ||
386 | |||
358 | /* query max MTU from first port -- it's the same for all ports */ | 387 | /* query max MTU from first port -- it's the same for all ports */ |
359 | port = (struct hipz_query_port *)rblock; | 388 | port = (struct hipz_query_port *)rblock; |
360 | h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port); | 389 | h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port); |
@@ -684,7 +713,7 @@ static int __devinit ehca_probe(struct of_device *dev, | |||
684 | struct ehca_shca *shca; | 713 | struct ehca_shca *shca; |
685 | const u64 *handle; | 714 | const u64 *handle; |
686 | struct ib_pd *ibpd; | 715 | struct ib_pd *ibpd; |
687 | int ret, i; | 716 | int ret, i, eq_size; |
688 | 717 | ||
689 | handle = of_get_property(dev->node, "ibm,hca-handle", NULL); | 718 | handle = of_get_property(dev->node, "ibm,hca-handle", NULL); |
690 | if (!handle) { | 719 | if (!handle) { |
@@ -705,6 +734,8 @@ static int __devinit ehca_probe(struct of_device *dev, | |||
705 | return -ENOMEM; | 734 | return -ENOMEM; |
706 | } | 735 | } |
707 | mutex_init(&shca->modify_mutex); | 736 | mutex_init(&shca->modify_mutex); |
737 | atomic_set(&shca->num_cqs, 0); | ||
738 | atomic_set(&shca->num_qps, 0); | ||
708 | for (i = 0; i < ARRAY_SIZE(shca->sport); i++) | 739 | for (i = 0; i < ARRAY_SIZE(shca->sport); i++) |
709 | spin_lock_init(&shca->sport[i].mod_sqp_lock); | 740 | spin_lock_init(&shca->sport[i].mod_sqp_lock); |
710 | 741 | ||
@@ -724,8 +755,9 @@ static int __devinit ehca_probe(struct of_device *dev, | |||
724 | goto probe1; | 755 | goto probe1; |
725 | } | 756 | } |
726 | 757 | ||
758 | eq_size = 2 * ehca_max_cq + 4 * ehca_max_qp; | ||
727 | /* create event queues */ | 759 | /* create event queues */ |
728 | ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, 2048); | 760 | ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, eq_size); |
729 | if (ret) { | 761 | if (ret) { |
730 | ehca_err(&shca->ib_device, "Cannot create EQ."); | 762 | ehca_err(&shca->ib_device, "Cannot create EQ."); |
731 | goto probe1; | 763 | goto probe1; |
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 57bef1152cc2..18fba92fa7ae 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c | |||
@@ -421,8 +421,18 @@ static struct ehca_qp *internal_create_qp( | |||
421 | u32 swqe_size = 0, rwqe_size = 0, ib_qp_num; | 421 | u32 swqe_size = 0, rwqe_size = 0, ib_qp_num; |
422 | unsigned long flags; | 422 | unsigned long flags; |
423 | 423 | ||
424 | if (init_attr->create_flags) | 424 | if (!atomic_add_unless(&shca->num_qps, 1, ehca_max_qp)) { |
425 | ehca_err(pd->device, "Unable to create QP, max number of %i " | ||
426 | "QPs reached.", ehca_max_qp); | ||
427 | ehca_err(pd->device, "To increase the maximum number of QPs " | ||
428 | "use the number_of_qps module parameter.\n"); | ||
429 | return ERR_PTR(-ENOSPC); | ||
430 | } | ||
431 | |||
432 | if (init_attr->create_flags) { | ||
433 | atomic_dec(&shca->num_qps); | ||
425 | return ERR_PTR(-EINVAL); | 434 | return ERR_PTR(-EINVAL); |
435 | } | ||
426 | 436 | ||
427 | memset(&parms, 0, sizeof(parms)); | 437 | memset(&parms, 0, sizeof(parms)); |
428 | qp_type = init_attr->qp_type; | 438 | qp_type = init_attr->qp_type; |
@@ -431,6 +441,7 @@ static struct ehca_qp *internal_create_qp( | |||
431 | init_attr->sq_sig_type != IB_SIGNAL_ALL_WR) { | 441 | init_attr->sq_sig_type != IB_SIGNAL_ALL_WR) { |
432 | ehca_err(pd->device, "init_attr->sg_sig_type=%x not allowed", | 442 | ehca_err(pd->device, "init_attr->sg_sig_type=%x not allowed", |
433 | init_attr->sq_sig_type); | 443 | init_attr->sq_sig_type); |
444 | atomic_dec(&shca->num_qps); | ||
434 | return ERR_PTR(-EINVAL); | 445 | return ERR_PTR(-EINVAL); |
435 | } | 446 | } |
436 | 447 | ||
@@ -455,6 +466,7 @@ static struct ehca_qp *internal_create_qp( | |||
455 | 466 | ||
456 | if (is_llqp && has_srq) { | 467 | if (is_llqp && has_srq) { |
457 | ehca_err(pd->device, "LLQPs can't have an SRQ"); | 468 | ehca_err(pd->device, "LLQPs can't have an SRQ"); |
469 | atomic_dec(&shca->num_qps); | ||
458 | return ERR_PTR(-EINVAL); | 470 | return ERR_PTR(-EINVAL); |
459 | } | 471 | } |
460 | 472 | ||
@@ -466,6 +478,7 @@ static struct ehca_qp *internal_create_qp( | |||
466 | ehca_err(pd->device, "no more than three SGEs " | 478 | ehca_err(pd->device, "no more than three SGEs " |
467 | "supported for SRQ pd=%p max_sge=%x", | 479 | "supported for SRQ pd=%p max_sge=%x", |
468 | pd, init_attr->cap.max_recv_sge); | 480 | pd, init_attr->cap.max_recv_sge); |
481 | atomic_dec(&shca->num_qps); | ||
469 | return ERR_PTR(-EINVAL); | 482 | return ERR_PTR(-EINVAL); |
470 | } | 483 | } |
471 | } | 484 | } |
@@ -477,6 +490,7 @@ static struct ehca_qp *internal_create_qp( | |||
477 | qp_type != IB_QPT_SMI && | 490 | qp_type != IB_QPT_SMI && |
478 | qp_type != IB_QPT_GSI) { | 491 | qp_type != IB_QPT_GSI) { |
479 | ehca_err(pd->device, "wrong QP Type=%x", qp_type); | 492 | ehca_err(pd->device, "wrong QP Type=%x", qp_type); |
493 | atomic_dec(&shca->num_qps); | ||
480 | return ERR_PTR(-EINVAL); | 494 | return ERR_PTR(-EINVAL); |
481 | } | 495 | } |
482 | 496 | ||
@@ -490,6 +504,7 @@ static struct ehca_qp *internal_create_qp( | |||
490 | "or max_rq_wr=%x for RC LLQP", | 504 | "or max_rq_wr=%x for RC LLQP", |
491 | init_attr->cap.max_send_wr, | 505 | init_attr->cap.max_send_wr, |
492 | init_attr->cap.max_recv_wr); | 506 | init_attr->cap.max_recv_wr); |
507 | atomic_dec(&shca->num_qps); | ||
493 | return ERR_PTR(-EINVAL); | 508 | return ERR_PTR(-EINVAL); |
494 | } | 509 | } |
495 | break; | 510 | break; |
@@ -497,6 +512,7 @@ static struct ehca_qp *internal_create_qp( | |||
497 | if (!EHCA_BMASK_GET(HCA_CAP_UD_LL_QP, shca->hca_cap)) { | 512 | if (!EHCA_BMASK_GET(HCA_CAP_UD_LL_QP, shca->hca_cap)) { |
498 | ehca_err(pd->device, "UD LLQP not supported " | 513 | ehca_err(pd->device, "UD LLQP not supported " |
499 | "by this adapter"); | 514 | "by this adapter"); |
515 | atomic_dec(&shca->num_qps); | ||
500 | return ERR_PTR(-ENOSYS); | 516 | return ERR_PTR(-ENOSYS); |
501 | } | 517 | } |
502 | if (!(init_attr->cap.max_send_sge <= 5 | 518 | if (!(init_attr->cap.max_send_sge <= 5 |
@@ -508,20 +524,22 @@ static struct ehca_qp *internal_create_qp( | |||
508 | "or max_recv_sge=%x for UD LLQP", | 524 | "or max_recv_sge=%x for UD LLQP", |
509 | init_attr->cap.max_send_sge, | 525 | init_attr->cap.max_send_sge, |
510 | init_attr->cap.max_recv_sge); | 526 | init_attr->cap.max_recv_sge); |
527 | atomic_dec(&shca->num_qps); | ||
511 | return ERR_PTR(-EINVAL); | 528 | return ERR_PTR(-EINVAL); |
512 | } else if (init_attr->cap.max_send_wr > 255) { | 529 | } else if (init_attr->cap.max_send_wr > 255) { |
513 | ehca_err(pd->device, | 530 | ehca_err(pd->device, |
514 | "Invalid Number of " | 531 | "Invalid Number of " |
515 | "max_send_wr=%x for UD QP_TYPE=%x", | 532 | "max_send_wr=%x for UD QP_TYPE=%x", |
516 | init_attr->cap.max_send_wr, qp_type); | 533 | init_attr->cap.max_send_wr, qp_type); |
534 | atomic_dec(&shca->num_qps); | ||
517 | return ERR_PTR(-EINVAL); | 535 | return ERR_PTR(-EINVAL); |
518 | } | 536 | } |
519 | break; | 537 | break; |
520 | default: | 538 | default: |
521 | ehca_err(pd->device, "unsupported LL QP Type=%x", | 539 | ehca_err(pd->device, "unsupported LL QP Type=%x", |
522 | qp_type); | 540 | qp_type); |
541 | atomic_dec(&shca->num_qps); | ||
523 | return ERR_PTR(-EINVAL); | 542 | return ERR_PTR(-EINVAL); |
524 | break; | ||
525 | } | 543 | } |
526 | } else { | 544 | } else { |
527 | int max_sge = (qp_type == IB_QPT_UD || qp_type == IB_QPT_SMI | 545 | int max_sge = (qp_type == IB_QPT_UD || qp_type == IB_QPT_SMI |
@@ -533,6 +551,7 @@ static struct ehca_qp *internal_create_qp( | |||
533 | "send_sge=%x recv_sge=%x max_sge=%x", | 551 | "send_sge=%x recv_sge=%x max_sge=%x", |
534 | init_attr->cap.max_send_sge, | 552 | init_attr->cap.max_send_sge, |
535 | init_attr->cap.max_recv_sge, max_sge); | 553 | init_attr->cap.max_recv_sge, max_sge); |
554 | atomic_dec(&shca->num_qps); | ||
536 | return ERR_PTR(-EINVAL); | 555 | return ERR_PTR(-EINVAL); |
537 | } | 556 | } |
538 | } | 557 | } |
@@ -543,6 +562,7 @@ static struct ehca_qp *internal_create_qp( | |||
543 | my_qp = kmem_cache_zalloc(qp_cache, GFP_KERNEL); | 562 | my_qp = kmem_cache_zalloc(qp_cache, GFP_KERNEL); |
544 | if (!my_qp) { | 563 | if (!my_qp) { |
545 | ehca_err(pd->device, "pd=%p not enough memory to alloc qp", pd); | 564 | ehca_err(pd->device, "pd=%p not enough memory to alloc qp", pd); |
565 | atomic_dec(&shca->num_qps); | ||
546 | return ERR_PTR(-ENOMEM); | 566 | return ERR_PTR(-ENOMEM); |
547 | } | 567 | } |
548 | 568 | ||
@@ -823,6 +843,7 @@ create_qp_exit1: | |||
823 | 843 | ||
824 | create_qp_exit0: | 844 | create_qp_exit0: |
825 | kmem_cache_free(qp_cache, my_qp); | 845 | kmem_cache_free(qp_cache, my_qp); |
846 | atomic_dec(&shca->num_qps); | ||
826 | return ERR_PTR(ret); | 847 | return ERR_PTR(ret); |
827 | } | 848 | } |
828 | 849 | ||
@@ -1948,6 +1969,7 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, | |||
1948 | if (HAS_SQ(my_qp)) | 1969 | if (HAS_SQ(my_qp)) |
1949 | ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); | 1970 | ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); |
1950 | kmem_cache_free(qp_cache, my_qp); | 1971 | kmem_cache_free(qp_cache, my_qp); |
1972 | atomic_dec(&shca->num_qps); | ||
1951 | return 0; | 1973 | return 0; |
1952 | } | 1974 | } |
1953 | 1975 | ||