aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorStefan Roscher <ossrosch@linux.vnet.ibm.com>2008-10-22 18:52:31 -0400
committerRoland Dreier <rolandd@cisco.com>2008-10-22 18:52:31 -0400
commit19f4282149147b4a3e8c670373dc73ddd5d5facc (patch)
treee6b740a392f7c76dec479ec762c837b16d2e0651 /drivers/infiniband
parent0540bbbe455e123a1692d26205ad1a29983883b0 (diff)
IB/ehca: Fix reported max number of QPs and CQs in systems with >1 adapter
Because ehca adapters can differ in the maximum number of QPs and CQs we have to save the maximum number of these ressources per adapter and not globally per ehca driver. This fix introduces 2 new members to the shca structure to store the maximum value for QPs and CQs per adapter. The module parameters are now used as initial values for those variables. If a user selects an invalid number of CQs or QPs we don't print an error any longer, instead we will inform the user with a warning and set the values to the respective maximum supported by the HW. Signed-off-by: Stefan Roscher <stefan.roscher@de.ibm.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes.h2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_cq.c4
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c35
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c4
4 files changed, 26 insertions, 19 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index 5d7b7855afb9..4df887af66a5 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -128,6 +128,8 @@ struct ehca_shca {
128 /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */ 128 /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */
129 u32 hca_cap_mr_pgsize; 129 u32 hca_cap_mr_pgsize;
130 int max_mtu; 130 int max_mtu;
131 int max_num_qps;
132 int max_num_cqs;
131 atomic_t num_cqs; 133 atomic_t num_cqs;
132 atomic_t num_qps; 134 atomic_t num_qps;
133}; 135};
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index 33647a95eb9a..2f4c28a30271 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -132,9 +132,9 @@ 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)) { 135 if (!atomic_add_unless(&shca->num_cqs, 1, shca->max_num_cqs)) {
136 ehca_err(device, "Unable to create CQ, max number of %i " 136 ehca_err(device, "Unable to create CQ, max number of %i "
137 "CQs reached.", ehca_max_cq); 137 "CQs reached.", shca->max_num_cqs);
138 ehca_err(device, "To increase the maximum number of CQs " 138 ehca_err(device, "To increase the maximum number of CQs "
139 "use the number_of_cqs module parameter.\n"); 139 "use the number_of_cqs module parameter.\n");
140 return ERR_PTR(-ENOSPC); 140 return ERR_PTR(-ENOSPC);
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 598844d2edc9..086959a0cbee 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -366,22 +366,23 @@ static int ehca_sense_attributes(struct ehca_shca *shca)
366 shca->hca_cap_mr_pgsize |= pgsize_map[i + 1]; 366 shca->hca_cap_mr_pgsize |= pgsize_map[i + 1];
367 367
368 /* Set maximum number of CQs and QPs to calculate EQ size */ 368 /* Set maximum number of CQs and QPs to calculate EQ size */
369 if (ehca_max_qp == -1) 369 if (shca->max_num_qps == -1)
370 ehca_max_qp = min_t(int, rblock->max_qp, EHCA_MAX_NUM_QUEUES); 370 shca->max_num_qps = min_t(int, rblock->max_qp,
371 else if (ehca_max_qp < 1 || ehca_max_qp > rblock->max_qp) { 371 EHCA_MAX_NUM_QUEUES);
372 ehca_gen_err("Requested number of QPs is out of range (1 - %i) " 372 else if (shca->max_num_qps < 1 || shca->max_num_qps > rblock->max_qp) {
373 "specified by HW", rblock->max_qp); 373 ehca_gen_warn("The requested number of QPs is out of range "
374 ret = -EINVAL; 374 "(1 - %i) specified by HW. Value is set to %i",
375 goto sense_attributes1; 375 rblock->max_qp, rblock->max_qp);
376 shca->max_num_qps = rblock->max_qp;
376 } 377 }
377 378
378 if (ehca_max_cq == -1) 379 if (shca->max_num_cqs == -1)
379 ehca_max_cq = min_t(int, rblock->max_cq, EHCA_MAX_NUM_QUEUES); 380 shca->max_num_cqs = min_t(int, rblock->max_cq,
380 else if (ehca_max_cq < 1 || ehca_max_cq > rblock->max_cq) { 381 EHCA_MAX_NUM_QUEUES);
381 ehca_gen_err("Requested number of CQs is out of range (1 - %i) " 382 else if (shca->max_num_cqs < 1 || shca->max_num_cqs > rblock->max_cq) {
382 "specified by HW", rblock->max_cq); 383 ehca_gen_warn("The requested number of CQs is out of range "
383 ret = -EINVAL; 384 "(1 - %i) specified by HW. Value is set to %i",
384 goto sense_attributes1; 385 rblock->max_cq, rblock->max_cq);
385 } 386 }
386 387
387 /* query max MTU from first port -- it's the same for all ports */ 388 /* query max MTU from first port -- it's the same for all ports */
@@ -733,9 +734,13 @@ static int __devinit ehca_probe(struct of_device *dev,
733 ehca_gen_err("Cannot allocate shca memory."); 734 ehca_gen_err("Cannot allocate shca memory.");
734 return -ENOMEM; 735 return -ENOMEM;
735 } 736 }
737
736 mutex_init(&shca->modify_mutex); 738 mutex_init(&shca->modify_mutex);
737 atomic_set(&shca->num_cqs, 0); 739 atomic_set(&shca->num_cqs, 0);
738 atomic_set(&shca->num_qps, 0); 740 atomic_set(&shca->num_qps, 0);
741 shca->max_num_qps = ehca_max_qp;
742 shca->max_num_cqs = ehca_max_cq;
743
739 for (i = 0; i < ARRAY_SIZE(shca->sport); i++) 744 for (i = 0; i < ARRAY_SIZE(shca->sport); i++)
740 spin_lock_init(&shca->sport[i].mod_sqp_lock); 745 spin_lock_init(&shca->sport[i].mod_sqp_lock);
741 746
@@ -755,7 +760,7 @@ static int __devinit ehca_probe(struct of_device *dev,
755 goto probe1; 760 goto probe1;
756 } 761 }
757 762
758 eq_size = 2 * ehca_max_cq + 4 * ehca_max_qp; 763 eq_size = 2 * shca->max_num_cqs + 4 * shca->max_num_qps;
759 /* create event queues */ 764 /* create event queues */
760 ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, eq_size); 765 ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, eq_size);
761 if (ret) { 766 if (ret) {
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index 40b578d601c5..4d54b9f64567 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -465,9 +465,9 @@ static struct ehca_qp *internal_create_qp(
465 u32 swqe_size = 0, rwqe_size = 0, ib_qp_num; 465 u32 swqe_size = 0, rwqe_size = 0, ib_qp_num;
466 unsigned long flags; 466 unsigned long flags;
467 467
468 if (!atomic_add_unless(&shca->num_qps, 1, ehca_max_qp)) { 468 if (!atomic_add_unless(&shca->num_qps, 1, shca->max_num_qps)) {
469 ehca_err(pd->device, "Unable to create QP, max number of %i " 469 ehca_err(pd->device, "Unable to create QP, max number of %i "
470 "QPs reached.", ehca_max_qp); 470 "QPs reached.", shca->max_num_qps);
471 ehca_err(pd->device, "To increase the maximum number of QPs " 471 ehca_err(pd->device, "To increase the maximum number of QPs "
472 "use the number_of_qps module parameter.\n"); 472 "use the number_of_qps module parameter.\n");
473 return ERR_PTR(-ENOSPC); 473 return ERR_PTR(-ENOSPC);