]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Stefan Roscher <stefan.roscher@de.ibm.com> |
2 | Subject: Fix problem with max number of QPs and CQs | |
3 | References: bnc#441619 | |
4 | ||
5 | Because ehca adapters can differ in the maximum number of QPs and CQs | |
6 | we have to save the maximum number of these ressources per adapter and not | |
7 | globally per ehca driver. This fix introduces 2 new members to the shca | |
8 | structure to store the maximum value for QPs and CQs per adapter. | |
9 | The module parameters are now used as initial values for those variables. | |
10 | If a user selects an invalid number of CQs or QPs we don't print an error any | |
11 | longer, instead we will inform the user with a warning and set the values to | |
12 | the respective maximum supported by the HW. | |
13 | ||
14 | Acked-by: John Jolly <jjolly@novell.com> | |
15 | ||
16 | Index: linux-2.6.27/drivers/infiniband/hw/ehca/ehca_classes.h | |
17 | =================================================================== | |
18 | --- linux-2.6.27.orig/drivers/infiniband/hw/ehca/ehca_classes.h | |
19 | +++ linux-2.6.27/drivers/infiniband/hw/ehca/ehca_classes.h | |
20 | @@ -128,6 +128,8 @@ struct ehca_shca { | |
21 | /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */ | |
22 | u32 hca_cap_mr_pgsize; | |
23 | int max_mtu; | |
24 | + int max_num_qps; | |
25 | + int max_num_cqs; | |
26 | atomic_t num_cqs; | |
27 | atomic_t num_qps; | |
28 | }; | |
29 | Index: linux-2.6.27/drivers/infiniband/hw/ehca/ehca_cq.c | |
30 | =================================================================== | |
31 | --- linux-2.6.27.orig/drivers/infiniband/hw/ehca/ehca_cq.c | |
32 | +++ linux-2.6.27/drivers/infiniband/hw/ehca/ehca_cq.c | |
33 | @@ -132,9 +132,9 @@ struct ib_cq *ehca_create_cq(struct ib_d | |
34 | if (cqe >= 0xFFFFFFFF - 64 - additional_cqe) | |
35 | return ERR_PTR(-EINVAL); | |
36 | ||
37 | - if (!atomic_add_unless(&shca->num_cqs, 1, ehca_max_cq)) { | |
38 | + if (!atomic_add_unless(&shca->num_cqs, 1, shca->max_num_cqs)) { | |
39 | ehca_err(device, "Unable to create CQ, max number of %i " | |
40 | - "CQs reached.", ehca_max_cq); | |
41 | + "CQs reached.", shca->max_num_cqs); | |
42 | ehca_err(device, "To increase the maximum number of CQs " | |
43 | "use the number_of_cqs module parameter.\n"); | |
44 | return ERR_PTR(-ENOSPC); | |
45 | Index: linux-2.6.27/drivers/infiniband/hw/ehca/ehca_main.c | |
46 | =================================================================== | |
47 | --- linux-2.6.27.orig/drivers/infiniband/hw/ehca/ehca_main.c | |
48 | +++ linux-2.6.27/drivers/infiniband/hw/ehca/ehca_main.c | |
49 | @@ -368,22 +368,23 @@ static int ehca_sense_attributes(struct | |
50 | shca->hca_cap_mr_pgsize |= pgsize_map[i + 1]; | |
51 | ||
52 | /* Set maximum number of CQs and QPs to calculate EQ size */ | |
53 | - if (ehca_max_qp == -1) | |
54 | - ehca_max_qp = min_t(int, rblock->max_qp, EHCA_MAX_NUM_QUEUES); | |
55 | - else if (ehca_max_qp < 1 || ehca_max_qp > rblock->max_qp) { | |
56 | - ehca_gen_err("Requested number of QPs is out of range (1 - %i) " | |
57 | - "specified by HW", rblock->max_qp); | |
58 | - ret = -EINVAL; | |
59 | - goto sense_attributes1; | |
60 | - } | |
61 | - | |
62 | - if (ehca_max_cq == -1) | |
63 | - ehca_max_cq = min_t(int, rblock->max_cq, EHCA_MAX_NUM_QUEUES); | |
64 | - else if (ehca_max_cq < 1 || ehca_max_cq > rblock->max_cq) { | |
65 | - ehca_gen_err("Requested number of CQs is out of range (1 - %i) " | |
66 | - "specified by HW", rblock->max_cq); | |
67 | - ret = -EINVAL; | |
68 | - goto sense_attributes1; | |
69 | + if (shca->max_num_qps == -1) | |
70 | + shca->max_num_qps = min_t(int, rblock->max_qp, | |
71 | + EHCA_MAX_NUM_QUEUES); | |
72 | + else if (shca->max_num_qps < 1 || shca->max_num_qps > rblock->max_qp) { | |
73 | + ehca_gen_warn("The requested number of QPs is out of range " | |
74 | + "(1 - %i) specified by HW. Value is set to %i", | |
75 | + rblock->max_qp, rblock->max_qp); | |
76 | + shca->max_num_qps = rblock->max_qp; | |
77 | + } | |
78 | + | |
79 | + if (shca->max_num_cqs == -1) | |
80 | + shca->max_num_cqs = min_t(int, rblock->max_cq, | |
81 | + EHCA_MAX_NUM_QUEUES); | |
82 | + else if (shca->max_num_cqs < 1 || shca->max_num_cqs > rblock->max_cq) { | |
83 | + ehca_gen_warn("The requested number of CQs is out of range " | |
84 | + "(1 - %i) specified by HW. Value is set to %i", | |
85 | + rblock->max_cq, rblock->max_cq); | |
86 | } | |
87 | ||
88 | /* query max MTU from first port -- it's the same for all ports */ | |
89 | @@ -735,9 +736,13 @@ static int __devinit ehca_probe(struct o | |
90 | ehca_gen_err("Cannot allocate shca memory."); | |
91 | return -ENOMEM; | |
92 | } | |
93 | + | |
94 | mutex_init(&shca->modify_mutex); | |
95 | atomic_set(&shca->num_cqs, 0); | |
96 | atomic_set(&shca->num_qps, 0); | |
97 | + shca->max_num_qps = ehca_max_qp; | |
98 | + shca->max_num_cqs = ehca_max_cq; | |
99 | + | |
100 | for (i = 0; i < ARRAY_SIZE(shca->sport); i++) | |
101 | spin_lock_init(&shca->sport[i].mod_sqp_lock); | |
102 | ||
103 | @@ -757,7 +762,7 @@ static int __devinit ehca_probe(struct o | |
104 | goto probe1; | |
105 | } | |
106 | ||
107 | - eq_size = 2 * ehca_max_cq + 4 * ehca_max_qp; | |
108 | + eq_size = 2 * shca->max_num_cqs + 4 * shca->max_num_qps; | |
109 | /* create event queues */ | |
110 | ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, eq_size); | |
111 | if (ret) { | |
112 | Index: linux-2.6.27/drivers/infiniband/hw/ehca/ehca_qp.c | |
113 | =================================================================== | |
114 | --- linux-2.6.27.orig/drivers/infiniband/hw/ehca/ehca_qp.c | |
115 | +++ linux-2.6.27/drivers/infiniband/hw/ehca/ehca_qp.c | |
116 | @@ -465,9 +465,9 @@ static struct ehca_qp *internal_create_q | |
117 | u32 swqe_size = 0, rwqe_size = 0, ib_qp_num; | |
118 | unsigned long flags; | |
119 | ||
120 | - if (!atomic_add_unless(&shca->num_qps, 1, ehca_max_qp)) { | |
121 | + if (!atomic_add_unless(&shca->num_qps, 1, shca->max_num_qps)) { | |
122 | ehca_err(pd->device, "Unable to create QP, max number of %i " | |
123 | - "QPs reached.", ehca_max_qp); | |
124 | + "QPs reached.", shca->max_num_qps); | |
125 | ehca_err(pd->device, "To increase the maximum number of QPs " | |
126 | "use the number_of_qps module parameter.\n"); | |
127 | return ERR_PTR(-ENOSPC); |